From dfaddaa98d645b818ba3947c9267ef7ac8ed9ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kubry=C5=84ski?= Date: Sat, 6 Dec 2014 18:20:29 +0100 Subject: [PATCH 001/719] Initial commit --- .gitignore | 12 ++++ LICENSE | 202 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 214 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..32858aad3c --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..e06d208186 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ +Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + From ac3c611553cf01dc142005fba6cce7c86843c27c Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 6 Dec 2014 20:47:01 +0100 Subject: [PATCH 002/719] Class builder scratch --- .gitignore | 11 +--- pom.xml | 54 ++++++++++++++++ .../groovy/eu/coderate/ck/Generator.groovy | 16 +++++ .../coderate/ck/builder/BlockBuilder.groovy | 59 ++++++++++++++++++ .../coderate/ck/builder/ClassBuilder.groovy | 61 +++++++++++++++++++ .../coderate/ck/builder/MethodBuilder.groovy | 25 ++++++++ 6 files changed, 218 insertions(+), 8 deletions(-) create mode 100644 pom.xml create mode 100644 src/main/groovy/eu/coderate/ck/Generator.groovy create mode 100644 src/main/groovy/eu/coderate/ck/builder/BlockBuilder.groovy create mode 100644 src/main/groovy/eu/coderate/ck/builder/ClassBuilder.groovy create mode 100644 src/main/groovy/eu/coderate/ck/builder/MethodBuilder.groovy diff --git a/.gitignore b/.gitignore index 32858aad3c..c1785e61a0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,7 @@ *.class +*.iml -# Mobile Tools for Java (J2ME) -.mtj.tmp/ +.idea/ +target/ -# Package Files # -*.jar -*.war -*.ear - -# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000..470bfc2b8f --- /dev/null +++ b/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + eu.codearte.contract-keeper + contract-keeper + 1.0.0-SNAPSHOT + + + 2.3.7 + + + + + org.codehaus.groovy + groovy-all + ${groovy.version} + + + + junit + junit + 4.11 + test + + + com.jayway.restassured + rest-assured + 2.4.0 + test + + + + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.2 + + + + compile + testCompile + + + + + + + \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/ck/Generator.groovy b/src/main/groovy/eu/coderate/ck/Generator.groovy new file mode 100644 index 0000000000..2eb6e37959 --- /dev/null +++ b/src/main/groovy/eu/coderate/ck/Generator.groovy @@ -0,0 +1,16 @@ +package eu.coderate.ck + +import static eu.coderate.ck.builder.ClassBuilder.createClass +import static eu.coderate.ck.builder.MethodBuilder.createVoidMethod + +class Generator { + + public static void main(String[] args) { + print createClass('MyTest', 'io.test') + .addImport('org.junit.Test') + .addStaticImport('org.hamcrest.CoreMatchers.*') + .addStaticImport('com.jayway.restassured.RestAssured.*') + .addMethod(createVoidMethod('shouldInvokeService')) + .build() + } +} \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/ck/builder/BlockBuilder.groovy b/src/main/groovy/eu/coderate/ck/builder/BlockBuilder.groovy new file mode 100644 index 0000000000..dd8b4114e0 --- /dev/null +++ b/src/main/groovy/eu/coderate/ck/builder/BlockBuilder.groovy @@ -0,0 +1,59 @@ +package eu.coderate.ck.builder + +import groovy.transform.PackageScope + +/** + * @author Jakub Kubrynski + */ +@PackageScope +class BlockBuilder { + + private final StringBuilder builder + private final String spacer + private int indents + + BlockBuilder(String spacer) { + this.spacer = spacer + builder = new StringBuilder() + } + + BlockBuilder startBlock() { + indents++ + return this + } + + BlockBuilder endBlock() { + indents-- + return this + } + + BlockBuilder addLine(String line) { + addIndentation() + builder << "$line\n" + return this + } + + BlockBuilder addEmptyLine() { + builder << '\n' + return this + } + + void addIndentation() { + indents.times { + builder << spacer + } + } + + BlockBuilder addBlock(MethodBuilder methodBuilder) { + startBlock() + methodBuilder.appendTo(this) + endBlock() + addEmptyLine() + return this + } + + @Override + String toString() { + return builder.toString() + } +} diff --git a/src/main/groovy/eu/coderate/ck/builder/ClassBuilder.groovy b/src/main/groovy/eu/coderate/ck/builder/ClassBuilder.groovy new file mode 100644 index 0000000000..1d53705e21 --- /dev/null +++ b/src/main/groovy/eu/coderate/ck/builder/ClassBuilder.groovy @@ -0,0 +1,61 @@ +package eu.coderate.ck.builder + +/** + * @author Jakub Kubrynski + */ +class ClassBuilder { + + private final String className + private final String packageName + private final List imports = [] + private final List staticImports = [] + private final List methods = [] + + private ClassBuilder(String className, String packageName) { + this.packageName = packageName + this.className = className + } + + static ClassBuilder createClass(String className, String packageName) { + return new ClassBuilder(className, packageName) + } + + ClassBuilder addImport(String importToAdd) { + imports << importToAdd + return this + } + + ClassBuilder addStaticImport(String importToAdd) { + staticImports << importToAdd + return this + } + + ClassBuilder addMethod(MethodBuilder methodBuilder) { + methods << methodBuilder + return this + } + + String build() { + BlockBuilder clazz = new BlockBuilder(" ") + .addLine("package $packageName;") + .addEmptyLine() + imports.sort().each { + clazz.addLine("import $it;") + } + clazz.addEmptyLine() + staticImports.sort().each { + clazz.addLine("static import $it;") + } + clazz.addEmptyLine() + + clazz.addLine("public class $className {") + clazz.addEmptyLine() + + methods.each { + clazz.addBlock(it) + } + + clazz.addLine('}') + clazz.toString() + } +} diff --git a/src/main/groovy/eu/coderate/ck/builder/MethodBuilder.groovy b/src/main/groovy/eu/coderate/ck/builder/MethodBuilder.groovy new file mode 100644 index 0000000000..53d8e3e987 --- /dev/null +++ b/src/main/groovy/eu/coderate/ck/builder/MethodBuilder.groovy @@ -0,0 +1,25 @@ +package eu.coderate.ck.builder + +/** + * @author Jakub Kubrynski + */ +class MethodBuilder { + + private final String methodName + private final String returnType + + private MethodBuilder(String returnType, String methodName) { + this.returnType = returnType + this.methodName = methodName + } + + static MethodBuilder createVoidMethod(String methodName) { + return new MethodBuilder("void", methodName) + } + + void appendTo(BlockBuilder blockBuilder) { + blockBuilder.addLine('@Test') + blockBuilder.addLine("public $returnType $methodName {") + .addLine('}') + } +} From 7d48847e9a6b0d2c5ba375ee2f1face2b249ec33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kubry=C5=84ski?= Date: Sat, 6 Dec 2014 23:19:09 +0100 Subject: [PATCH 003/719] Create README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..37227d41fb --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +accurest +======== From aaa51302fd530d635ae1b716ce30b82da02a54f1 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 6 Dec 2014 23:21:43 +0100 Subject: [PATCH 004/719] Added support for junit rules --- README.md | 5 ++- pom.xml | 4 +- .../eu/coderate/accurest/Generator.groovy | 19 +++++++++ .../builder/BlockBuilder.groovy | 2 +- .../builder/ClassBuilder.groovy | 40 +++++++++++++++++-- .../builder/MethodBuilder.groovy | 2 +- .../coderate/accurest/util/NamesUtil.groovy | 22 ++++++++++ .../groovy/eu/coderate/ck/Generator.groovy | 16 -------- 8 files changed, 84 insertions(+), 26 deletions(-) create mode 100644 src/main/groovy/eu/coderate/accurest/Generator.groovy rename src/main/groovy/eu/coderate/{ck => accurest}/builder/BlockBuilder.groovy (95%) rename src/main/groovy/eu/coderate/{ck => accurest}/builder/ClassBuilder.groovy (52%) rename src/main/groovy/eu/coderate/{ck => accurest}/builder/MethodBuilder.groovy (93%) create mode 100644 src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy delete mode 100644 src/main/groovy/eu/coderate/ck/Generator.groovy diff --git a/README.md b/README.md index 37227d41fb..6937ee468a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ -accurest -======== +Accurate REST +============= +Consumer Driven Contracts verifier for Java \ No newline at end of file diff --git a/pom.xml b/pom.xml index 470bfc2b8f..76c45c3fb3 100644 --- a/pom.xml +++ b/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - eu.codearte.contract-keeper - contract-keeper + eu.codearte.accurest + accurest 1.0.0-SNAPSHOT diff --git a/src/main/groovy/eu/coderate/accurest/Generator.groovy b/src/main/groovy/eu/coderate/accurest/Generator.groovy new file mode 100644 index 0000000000..c8f875643e --- /dev/null +++ b/src/main/groovy/eu/coderate/accurest/Generator.groovy @@ -0,0 +1,19 @@ +package eu.coderate.accurest + +import static eu.coderate.accurest.builder.ClassBuilder.createClass +import static eu.coderate.accurest.builder.MethodBuilder.createVoidMethod + +class Generator { + + public static void main(String[] args) { + print createClass('MyTest', 'io.test', "com.test.BaseClass") + .addImport('org.junit.Test') + .addImport('org.junit.Rule') + .addStaticImport('org.hamcrest.Matchers.*') + .addStaticImport('com.jayway.restassured.RestAssured.*') + .addStaticImport('com.jayway.restassured.matcher.RestAssuredMatchers.*') + .addRule('com.test.MyRule') + .addMethod(createVoidMethod('shouldInvokeService')) + .build() + } +} \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/ck/builder/BlockBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/BlockBuilder.groovy similarity index 95% rename from src/main/groovy/eu/coderate/ck/builder/BlockBuilder.groovy rename to src/main/groovy/eu/coderate/accurest/builder/BlockBuilder.groovy index dd8b4114e0..3d159f139c 100644 --- a/src/main/groovy/eu/coderate/ck/builder/BlockBuilder.groovy +++ b/src/main/groovy/eu/coderate/accurest/builder/BlockBuilder.groovy @@ -1,4 +1,4 @@ -package eu.coderate.ck.builder +package eu.coderate.accurest.builder import groovy.transform.PackageScope diff --git a/src/main/groovy/eu/coderate/ck/builder/ClassBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy similarity index 52% rename from src/main/groovy/eu/coderate/ck/builder/ClassBuilder.groovy rename to src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy index 1d53705e21..ad517a5c96 100644 --- a/src/main/groovy/eu/coderate/ck/builder/ClassBuilder.groovy +++ b/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy @@ -1,4 +1,6 @@ -package eu.coderate.ck.builder +package eu.coderate.accurest.builder + +import eu.coderate.accurest.util.NamesUtil /** * @author Jakub Kubrynski @@ -7,17 +9,27 @@ class ClassBuilder { private final String className private final String packageName + private final String baseClass private final List imports = [] private final List staticImports = [] + private final List rules = [] private final List methods = [] - private ClassBuilder(String className, String packageName) { + private ClassBuilder(String className, String packageName, String baseClass) { + if (baseClass) { + imports << baseClass + } + this.baseClass = NamesUtil.getName(baseClass) this.packageName = packageName this.className = className } static ClassBuilder createClass(String className, String packageName) { - return new ClassBuilder(className, packageName) + return createClass(className, packageName, null) + } + + static ClassBuilder createClass(String className, String packageName, String baseClass) { + return new ClassBuilder(className, packageName, baseClass) } ClassBuilder addImport(String importToAdd) { @@ -35,20 +47,40 @@ class ClassBuilder { return this } + ClassBuilder addRule(String ruleClass) { + imports << ruleClass + rules << NamesUtil.getName(ruleClass) + return this + } + String build() { BlockBuilder clazz = new BlockBuilder(" ") .addLine("package $packageName;") .addEmptyLine() + imports.sort().each { clazz.addLine("import $it;") } clazz.addEmptyLine() + staticImports.sort().each { clazz.addLine("static import $it;") } clazz.addEmptyLine() - clazz.addLine("public class $className {") + def classLine = "public class $className" + if (baseClass) { + classLine += " extends $baseClass" + } + clazz.addLine(classLine + ' {') + clazz.addEmptyLine() + + clazz.startBlock() + rules.sort().each { + clazz.addLine("@Rule") + clazz.addLine("public " + it + " " + NamesUtil.fieldName(it) + " = new $it();") + } + clazz.endBlock() clazz.addEmptyLine() methods.each { diff --git a/src/main/groovy/eu/coderate/ck/builder/MethodBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy similarity index 93% rename from src/main/groovy/eu/coderate/ck/builder/MethodBuilder.groovy rename to src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy index 53d8e3e987..c98d8757f1 100644 --- a/src/main/groovy/eu/coderate/ck/builder/MethodBuilder.groovy +++ b/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy @@ -1,4 +1,4 @@ -package eu.coderate.ck.builder +package eu.coderate.accurest.builder /** * @author Jakub Kubrynski diff --git a/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy b/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy new file mode 100644 index 0000000000..ff9215477a --- /dev/null +++ b/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy @@ -0,0 +1,22 @@ +package eu.coderate.accurest.util + +/** + * @author Jakub Kubrynski + */ +class NamesUtil { + static String getName(String qualifiedName) { + if (qualifiedName?.indexOf('.') > -1) { + return qualifiedName.substring(qualifiedName.lastIndexOf('.')+1) + } + return qualifiedName + } + + static String fieldName(String className) { + if (className) { + return className + } + String name = getName(className) + String firstChar = name.charAt(0).toLowerCase() as String + return firstChar + name.substring(1) + } +} diff --git a/src/main/groovy/eu/coderate/ck/Generator.groovy b/src/main/groovy/eu/coderate/ck/Generator.groovy deleted file mode 100644 index 2eb6e37959..0000000000 --- a/src/main/groovy/eu/coderate/ck/Generator.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package eu.coderate.ck - -import static eu.coderate.ck.builder.ClassBuilder.createClass -import static eu.coderate.ck.builder.MethodBuilder.createVoidMethod - -class Generator { - - public static void main(String[] args) { - print createClass('MyTest', 'io.test') - .addImport('org.junit.Test') - .addStaticImport('org.hamcrest.CoreMatchers.*') - .addStaticImport('com.jayway.restassured.RestAssured.*') - .addMethod(createVoidMethod('shouldInvokeService')) - .build() - } -} \ No newline at end of file From c6a75b7dcfa200000de19ccb3404ed61a87f73af Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sun, 7 Dec 2014 00:00:06 +0100 Subject: [PATCH 005/719] Introduced configuration --- .../eu/coderate/accurest/Generator.groovy | 19 ------- .../eu/coderate/accurest/TestGenerator.groovy | 49 +++++++++++++++++++ .../accurest/builder/ClassBuilder.groovy | 6 +-- .../coderate/accurest/util/NamesUtil.groovy | 32 ++++++++---- src/main/resources/wiremocks/sample.json | 13 +++++ src/main/resources/wiremocks/shouldFail.json | 9 ++++ 6 files changed, 97 insertions(+), 31 deletions(-) delete mode 100644 src/main/groovy/eu/coderate/accurest/Generator.groovy create mode 100644 src/main/groovy/eu/coderate/accurest/TestGenerator.groovy create mode 100644 src/main/resources/wiremocks/sample.json create mode 100644 src/main/resources/wiremocks/shouldFail.json diff --git a/src/main/groovy/eu/coderate/accurest/Generator.groovy b/src/main/groovy/eu/coderate/accurest/Generator.groovy deleted file mode 100644 index c8f875643e..0000000000 --- a/src/main/groovy/eu/coderate/accurest/Generator.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package eu.coderate.accurest - -import static eu.coderate.accurest.builder.ClassBuilder.createClass -import static eu.coderate.accurest.builder.MethodBuilder.createVoidMethod - -class Generator { - - public static void main(String[] args) { - print createClass('MyTest', 'io.test', "com.test.BaseClass") - .addImport('org.junit.Test') - .addImport('org.junit.Rule') - .addStaticImport('org.hamcrest.Matchers.*') - .addStaticImport('com.jayway.restassured.RestAssured.*') - .addStaticImport('com.jayway.restassured.matcher.RestAssuredMatchers.*') - .addRule('com.test.MyRule') - .addMethod(createVoidMethod('shouldInvokeService')) - .build() - } -} \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy new file mode 100644 index 0000000000..24d122df72 --- /dev/null +++ b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy @@ -0,0 +1,49 @@ +package eu.coderate.accurest + +import eu.coderate.accurest.util.NamesUtil + +import static eu.coderate.accurest.builder.ClassBuilder.createClass +import static eu.coderate.accurest.builder.MethodBuilder.createVoidMethod + +/** + * @author Jakub Kubrynski + */ +class TestGenerator { + + private final String mocksBaseDirectory + private final String basePackageForTests + private final String baseClassForTests + private final String ruleClassForTests + + TestGenerator(String mocksBaseDirectory, String basePackageForTests, String baseClassForTests, String ruleClassForTests) { + this.mocksBaseDirectory = getClass().getClassLoader().getResource(mocksBaseDirectory).path + this.basePackageForTests = basePackageForTests + this.baseClassForTests = baseClassForTests + this.ruleClassForTests = ruleClassForTests + } + + public String generate() { + StringBuilder builder = new StringBuilder() + List files = new File(mocksBaseDirectory).list() + files.each { + builder << addClass(NamesUtil.capitalize(NamesUtil.toLastDot(it))) + } + return builder + } + + private String addClass(String className) { + createClass(className, basePackageForTests, baseClassForTests) + .addImport('org.junit.Test') + .addImport('org.junit.Rule') + .addStaticImport('org.hamcrest.Matchers.*') + .addStaticImport('com.jayway.restassured.RestAssured.*') + .addStaticImport('com.jayway.restassured.matcher.RestAssuredMatchers.*') + .addRule('com.test.MyRule') + .addMethod(createVoidMethod('shouldInvokeService')) + .build() + } + + public static void main(String[] args) { + print new TestGenerator("wiremocks", 'io.test', 'com.test.BaseClass', "").generate() + } +} \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy index ad517a5c96..32296dd222 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy +++ b/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy @@ -19,7 +19,7 @@ class ClassBuilder { if (baseClass) { imports << baseClass } - this.baseClass = NamesUtil.getName(baseClass) + this.baseClass = NamesUtil.afterLastDot(baseClass) this.packageName = packageName this.className = className } @@ -49,7 +49,7 @@ class ClassBuilder { ClassBuilder addRule(String ruleClass) { imports << ruleClass - rules << NamesUtil.getName(ruleClass) + rules << NamesUtil.afterLastDot(ruleClass) return this } @@ -78,7 +78,7 @@ class ClassBuilder { clazz.startBlock() rules.sort().each { clazz.addLine("@Rule") - clazz.addLine("public " + it + " " + NamesUtil.fieldName(it) + " = new $it();") + clazz.addLine("public " + it + " " + NamesUtil.uncapitalize(it) + " = new $it();") } clazz.endBlock() clazz.addEmptyLine() diff --git a/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy b/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy index ff9215477a..530febc6d0 100644 --- a/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy +++ b/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy @@ -4,19 +4,33 @@ package eu.coderate.accurest.util * @author Jakub Kubrynski */ class NamesUtil { - static String getName(String qualifiedName) { - if (qualifiedName?.indexOf('.') > -1) { - return qualifiedName.substring(qualifiedName.lastIndexOf('.')+1) + static String afterLastDot(String string) { + if (string?.indexOf('.') > -1) { + return string.substring(string.lastIndexOf('.')+1) } - return qualifiedName + return string } - static String fieldName(String className) { - if (className) { + static String uncapitalize(String className) { + if (!className) { return className } - String name = getName(className) - String firstChar = name.charAt(0).toLowerCase() as String - return firstChar + name.substring(1) + String firstChar = className.charAt(0).toLowerCase() as String + return firstChar + className.substring(1) + } + + static String capitalize(String className) { + if (!className) { + return className + } + String firstChar = className.charAt(0).toUpperCase() as String + return firstChar + className.substring(1) + } + + static String toLastDot(String string) { + if (string?.indexOf('.') > -1) { + return string.substring(0, string.lastIndexOf('.')) + } + return string } } diff --git a/src/main/resources/wiremocks/sample.json b/src/main/resources/wiremocks/sample.json new file mode 100644 index 0000000000..1f97ce2a57 --- /dev/null +++ b/src/main/resources/wiremocks/sample.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/some/thing" + }, + "response": { + "status": 200, + "body": "Hello world!", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/src/main/resources/wiremocks/shouldFail.json b/src/main/resources/wiremocks/shouldFail.json new file mode 100644 index 0000000000..57926656a3 --- /dev/null +++ b/src/main/resources/wiremocks/shouldFail.json @@ -0,0 +1,9 @@ +{ + "request": { + "method": "GET", + "url": "/some/thing2" + }, + "response": { + "status": 400 + } +} \ No newline at end of file From e83455650ec79d3ba90f843ae4ea42e8a40580ed Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sun, 7 Dec 2014 00:37:14 +0100 Subject: [PATCH 006/719] Reading stub definitions basics --- .../eu/coderate/accurest/TestGenerator.groovy | 28 +++++++++++++------ .../accurest/builder/MethodBodyBuilder.groovy | 19 +++++++++++++ .../accurest/builder/MethodBuilder.groovy | 18 ++++++++---- .../coderate/accurest/util/NamesUtil.groovy | 11 ++++++-- src/main/resources/wiremocks/shouldFail.json | 4 +-- 5 files changed, 62 insertions(+), 18 deletions(-) create mode 100644 src/main/groovy/eu/coderate/accurest/builder/MethodBodyBuilder.groovy diff --git a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy index 24d122df72..06264a7bed 100644 --- a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy +++ b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy @@ -1,5 +1,6 @@ package eu.coderate.accurest +import eu.coderate.accurest.builder.ClassBuilder import eu.coderate.accurest.util.NamesUtil import static eu.coderate.accurest.builder.ClassBuilder.createClass @@ -24,26 +25,37 @@ class TestGenerator { public String generate() { StringBuilder builder = new StringBuilder() - List files = new File(mocksBaseDirectory).list() - files.each { - builder << addClass(NamesUtil.capitalize(NamesUtil.toLastDot(it))) + List files = new File(mocksBaseDirectory).listFiles() + files.grep({ File file -> file.isDirectory() && containsStubs(file) }).each { + builder << addClass(it) } return builder } - private String addClass(String className) { - createClass(className, basePackageForTests, baseClassForTests) + boolean containsStubs(File file) { + return file.list(new FilenameFilter() { + @Override + boolean accept(File dir, String name) { + return "json".equalsIgnoreCase(NamesUtil.afterLastDot(name)) + } + }).size() > 0 + } + + private String addClass(File directory) { + ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), basePackageForTests, baseClassForTests) .addImport('org.junit.Test') .addImport('org.junit.Rule') .addStaticImport('org.hamcrest.Matchers.*') .addStaticImport('com.jayway.restassured.RestAssured.*') .addStaticImport('com.jayway.restassured.matcher.RestAssuredMatchers.*') .addRule('com.test.MyRule') - .addMethod(createVoidMethod('shouldInvokeService')) - .build() + directory.listFiles().each { + clazz.addMethod(createVoidMethod(it)) + } + return clazz.build() } public static void main(String[] args) { - print new TestGenerator("wiremocks", 'io.test', 'com.test.BaseClass', "").generate() + print new TestGenerator("", 'io.test', 'com.test.BaseClass', "").generate() } } \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/builder/MethodBodyBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/MethodBodyBuilder.groovy new file mode 100644 index 0000000000..17c6a5cc3d --- /dev/null +++ b/src/main/groovy/eu/coderate/accurest/builder/MethodBodyBuilder.groovy @@ -0,0 +1,19 @@ +package eu.coderate.accurest.builder + +/** + * @author Jakub Kubrynski + */ +class MethodBodyBuilder { + private final Map stubDefinition + + MethodBodyBuilder(Map stubDefinition) { + this.stubDefinition = stubDefinition + } + + void appendTo(BlockBuilder blockBuilder) { + blockBuilder.startBlock() + blockBuilder.addLine("//" + stubDefinition.request.method) + blockBuilder.addLine("//" + stubDefinition.response.status) + blockBuilder.endBlock() + } +} diff --git a/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy index c98d8757f1..c9e7568a51 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy +++ b/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy @@ -1,5 +1,8 @@ package eu.coderate.accurest.builder +import eu.coderate.accurest.util.NamesUtil +import groovy.json.JsonSlurper + /** * @author Jakub Kubrynski */ @@ -7,19 +10,24 @@ class MethodBuilder { private final String methodName private final String returnType + private final Map stubContent - private MethodBuilder(String returnType, String methodName) { + private MethodBuilder(String returnType, String methodName, Map stubContent) { + this.stubContent = stubContent this.returnType = returnType this.methodName = methodName } - static MethodBuilder createVoidMethod(String methodName) { - return new MethodBuilder("void", methodName) + static MethodBuilder createVoidMethod(File stubsFile) { + Map stubContent = new JsonSlurper().parse(stubsFile) + String methodName = NamesUtil.uncapitalize(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) + return new MethodBuilder("void", methodName, stubContent) } void appendTo(BlockBuilder blockBuilder) { blockBuilder.addLine('@Test') - blockBuilder.addLine("public $returnType $methodName {") - .addLine('}') + blockBuilder.addLine("public $returnType $methodName() {") + new MethodBodyBuilder(stubContent).appendTo(blockBuilder) + blockBuilder.addLine('}') } } diff --git a/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy b/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy index 530febc6d0..d330ce6e51 100644 --- a/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy +++ b/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy @@ -4,13 +4,18 @@ package eu.coderate.accurest.util * @author Jakub Kubrynski */ class NamesUtil { - static String afterLastDot(String string) { - if (string?.indexOf('.') > -1) { - return string.substring(string.lastIndexOf('.')+1) + + static String afterLast(String string, String separator) { + if (string?.indexOf(separator) > -1) { + return string.substring(string.lastIndexOf(separator)+1) } return string } + static String afterLastDot(String string) { + return afterLast(string, '.') + } + static String uncapitalize(String className) { if (!className) { return className diff --git a/src/main/resources/wiremocks/shouldFail.json b/src/main/resources/wiremocks/shouldFail.json index 57926656a3..7fd4b69fba 100644 --- a/src/main/resources/wiremocks/shouldFail.json +++ b/src/main/resources/wiremocks/shouldFail.json @@ -1,7 +1,7 @@ { "request": { - "method": "GET", - "url": "/some/thing2" + "method": "POST", + "url": "/some/thing" }, "response": { "status": 400 From 7a68e8d7b731b6b008b2664ad85d13026964880c Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sun, 7 Dec 2014 00:50:01 +0100 Subject: [PATCH 007/719] Changed generate method name --- .../groovy/eu/coderate/accurest/TestGenerator.groovy | 4 ++-- .../eu/coderate/accurest/builder/MethodBuilder.groovy | 10 ++++------ 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy index 06264a7bed..e44342920e 100644 --- a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy +++ b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy @@ -4,7 +4,7 @@ import eu.coderate.accurest.builder.ClassBuilder import eu.coderate.accurest.util.NamesUtil import static eu.coderate.accurest.builder.ClassBuilder.createClass -import static eu.coderate.accurest.builder.MethodBuilder.createVoidMethod +import static eu.coderate.accurest.builder.MethodBuilder.createTestMethod /** * @author Jakub Kubrynski @@ -50,7 +50,7 @@ class TestGenerator { .addStaticImport('com.jayway.restassured.matcher.RestAssuredMatchers.*') .addRule('com.test.MyRule') directory.listFiles().each { - clazz.addMethod(createVoidMethod(it)) + clazz.addMethod(createTestMethod(it)) } return clazz.build() } diff --git a/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy index c9e7568a51..25692663d2 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy +++ b/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy @@ -9,24 +9,22 @@ import groovy.json.JsonSlurper class MethodBuilder { private final String methodName - private final String returnType private final Map stubContent - private MethodBuilder(String returnType, String methodName, Map stubContent) { + private MethodBuilder(String methodName, Map stubContent) { this.stubContent = stubContent - this.returnType = returnType this.methodName = methodName } - static MethodBuilder createVoidMethod(File stubsFile) { + static MethodBuilder createTestMethod(File stubsFile) { Map stubContent = new JsonSlurper().parse(stubsFile) String methodName = NamesUtil.uncapitalize(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) - return new MethodBuilder("void", methodName, stubContent) + return new MethodBuilder(methodName, stubContent) } void appendTo(BlockBuilder blockBuilder) { blockBuilder.addLine('@Test') - blockBuilder.addLine("public $returnType $methodName() {") + blockBuilder.addLine("public void $methodName() {") new MethodBodyBuilder(stubContent).appendTo(blockBuilder) blockBuilder.addLine('}') } From 94c86af499d2899c5d94ab248f8a6c6976a47805 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Fri, 23 Jan 2015 00:21:22 +0100 Subject: [PATCH 008/719] Spock basic generation strategy --- pom.xml | 12 +++++ .../eu/coderate/accurest/TestGenerator.groovy | 33 +++++++++---- .../accurest/builder/ClassBuilder.groovy | 45 +++++++++++------ .../builder/JavaMethodBodyBuilder.groovy | 18 +++++++ .../eu/coderate/accurest/builder/Lang.groovy | 10 ++++ .../accurest/builder/MethodBodyBuilder.groovy | 19 ------- .../accurest/builder/MethodBuilder.groovy | 20 +++++--- .../builder/SpockMethodBodyBuilder.groovy | 49 +++++++++++++++++++ .../{ => stubs}/wiremocks/sample.json | 2 +- .../resources/stubs/wiremocks/shouldFail.json | 17 +++++++ src/main/resources/wiremocks/shouldFail.json | 9 ---- 11 files changed, 175 insertions(+), 59 deletions(-) create mode 100644 src/main/groovy/eu/coderate/accurest/builder/JavaMethodBodyBuilder.groovy create mode 100644 src/main/groovy/eu/coderate/accurest/builder/Lang.groovy delete mode 100644 src/main/groovy/eu/coderate/accurest/builder/MethodBodyBuilder.groovy create mode 100644 src/main/groovy/eu/coderate/accurest/builder/SpockMethodBodyBuilder.groovy rename src/main/resources/{ => stubs}/wiremocks/sample.json (87%) create mode 100644 src/main/resources/stubs/wiremocks/shouldFail.json delete mode 100644 src/main/resources/wiremocks/shouldFail.json diff --git a/pom.xml b/pom.xml index 76c45c3fb3..18562cbc40 100644 --- a/pom.xml +++ b/pom.xml @@ -31,6 +31,18 @@ 2.4.0 test + + org.spockframework + spock-core + 0.7-groovy-2.0 + test + + + + com.github.tomakehurst + wiremock + 1.53 + diff --git a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy index e44342920e..d7427db151 100644 --- a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy +++ b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy @@ -1,6 +1,7 @@ package eu.coderate.accurest import eu.coderate.accurest.builder.ClassBuilder +import eu.coderate.accurest.builder.Lang import eu.coderate.accurest.util.NamesUtil import static eu.coderate.accurest.builder.ClassBuilder.createClass @@ -15,12 +16,18 @@ class TestGenerator { private final String basePackageForTests private final String baseClassForTests private final String ruleClassForTests + private final Lang lang - TestGenerator(String mocksBaseDirectory, String basePackageForTests, String baseClassForTests, String ruleClassForTests) { + TestGenerator(String mocksBaseDirectory, String basePackageForTests, String baseClassForTests, String ruleClassForTests, Lang lang) { this.mocksBaseDirectory = getClass().getClassLoader().getResource(mocksBaseDirectory).path this.basePackageForTests = basePackageForTests - this.baseClassForTests = baseClassForTests + if (lang == Lang.GROOVY && !baseClassForTests) { + this.baseClassForTests = 'spock.lang.Specification' + } else { + this.baseClassForTests = baseClassForTests + } this.ruleClassForTests = ruleClassForTests + this.lang = lang } public String generate() { @@ -42,20 +49,26 @@ class TestGenerator { } private String addClass(File directory) { - ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), basePackageForTests, baseClassForTests) - .addImport('org.junit.Test') - .addImport('org.junit.Rule') - .addStaticImport('org.hamcrest.Matchers.*') + ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), basePackageForTests, baseClassForTests, lang) .addStaticImport('com.jayway.restassured.RestAssured.*') - .addStaticImport('com.jayway.restassured.matcher.RestAssuredMatchers.*') - .addRule('com.test.MyRule') + .addImport('java.util.regex.Pattern') + + if (lang == Lang.JAVA) { + clazz.addImport('org.junit.Test') + } + + if (ruleClassForTests) { + clazz.addImport('org.junit.Rule') + .addRule(ruleClassForTests) + } + directory.listFiles().each { - clazz.addMethod(createTestMethod(it)) + clazz.addMethod(createTestMethod(it, lang)) } return clazz.build() } public static void main(String[] args) { - print new TestGenerator("", 'io.test', 'com.test.BaseClass', "").generate() + print new TestGenerator('stubs', 'io.test', '', '', Lang.GROOVY).generate() } } \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy index 32296dd222..b893cbb5a6 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy +++ b/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy @@ -14,22 +14,33 @@ class ClassBuilder { private final List staticImports = [] private final List rules = [] private final List methods = [] + private final String modifier + private final String suffix - private ClassBuilder(String className, String packageName, String baseClass) { + private ClassBuilder(String className, String packageName, String baseClass, Lang lang) { if (baseClass) { imports << baseClass } this.baseClass = NamesUtil.afterLastDot(baseClass) this.packageName = packageName this.className = className + switch (lang) { + case Lang.JAVA: + modifier = "public " + suffix = ";" + break + case Lang.GROOVY: + modifier = "" + suffix = "" + } } - static ClassBuilder createClass(String className, String packageName) { - return createClass(className, packageName, null) + static ClassBuilder createClass(String className, String packageName, Lang lang) { + return createClass(className, packageName, null, lang) } - static ClassBuilder createClass(String className, String packageName, String baseClass) { - return new ClassBuilder(className, packageName, baseClass) + static ClassBuilder createClass(String className, String packageName, String baseClass, Lang lang) { + return new ClassBuilder(className, packageName, baseClass, lang) } ClassBuilder addImport(String importToAdd) { @@ -54,21 +65,25 @@ class ClassBuilder { } String build() { - BlockBuilder clazz = new BlockBuilder(" ") - .addLine("package $packageName;") + BlockBuilder clazz = new BlockBuilder("\t") + .addLine("package $packageName" + suffix) .addEmptyLine() imports.sort().each { - clazz.addLine("import $it;") + clazz.addLine("import $it" + suffix) + } + if (!imports.empty) { + clazz.addEmptyLine() } - clazz.addEmptyLine() staticImports.sort().each { - clazz.addLine("static import $it;") + clazz.addLine("import static $it" + suffix) + } + if (!staticImports.empty) { + clazz.addEmptyLine() } - clazz.addEmptyLine() - def classLine = "public class $className" + def classLine = modifier + "class $className" if (baseClass) { classLine += " extends $baseClass" } @@ -78,10 +93,12 @@ class ClassBuilder { clazz.startBlock() rules.sort().each { clazz.addLine("@Rule") - clazz.addLine("public " + it + " " + NamesUtil.uncapitalize(it) + " = new $it();") + clazz.addLine("public " + it + " " + NamesUtil.uncapitalize(it) + " = new $it()" + suffix) } clazz.endBlock() - clazz.addEmptyLine() + if (!rules.empty) { + clazz.addEmptyLine() + } methods.each { clazz.addBlock(it) diff --git a/src/main/groovy/eu/coderate/accurest/builder/JavaMethodBodyBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/JavaMethodBodyBuilder.groovy new file mode 100644 index 0000000000..c8a54548ce --- /dev/null +++ b/src/main/groovy/eu/coderate/accurest/builder/JavaMethodBodyBuilder.groovy @@ -0,0 +1,18 @@ +package eu.coderate.accurest.builder + +/** + * @author Jakub Kubrynski + */ +class JavaMethodBodyBuilder { +/* + given() + .contentType("application/json") + .header("Accept", "application/json") + .body("{'name': 'MyApp', 'description' : 'awesome app'}".replaceAll("'", "\"")). + + expect() + .statusCode(200).body("id", is(not(nullValue()))). + + when() + .post(root.toString() + "rest/applications").asString();*/ +} diff --git a/src/main/groovy/eu/coderate/accurest/builder/Lang.groovy b/src/main/groovy/eu/coderate/accurest/builder/Lang.groovy new file mode 100644 index 0000000000..dd7f7b07ee --- /dev/null +++ b/src/main/groovy/eu/coderate/accurest/builder/Lang.groovy @@ -0,0 +1,10 @@ +package eu.coderate.accurest.builder + +/** + * @author Jakub Kubrynski + */ +enum Lang { + + JAVA, GROOVY + +} \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/builder/MethodBodyBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/MethodBodyBuilder.groovy deleted file mode 100644 index 17c6a5cc3d..0000000000 --- a/src/main/groovy/eu/coderate/accurest/builder/MethodBodyBuilder.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package eu.coderate.accurest.builder - -/** - * @author Jakub Kubrynski - */ -class MethodBodyBuilder { - private final Map stubDefinition - - MethodBodyBuilder(Map stubDefinition) { - this.stubDefinition = stubDefinition - } - - void appendTo(BlockBuilder blockBuilder) { - blockBuilder.startBlock() - blockBuilder.addLine("//" + stubDefinition.request.method) - blockBuilder.addLine("//" + stubDefinition.response.status) - blockBuilder.endBlock() - } -} diff --git a/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy index 25692663d2..07f11e3987 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy +++ b/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy @@ -10,22 +10,30 @@ class MethodBuilder { private final String methodName private final Map stubContent + private final Lang lang - private MethodBuilder(String methodName, Map stubContent) { + private MethodBuilder(String methodName, Map stubContent, Lang lang) { this.stubContent = stubContent this.methodName = methodName + this.lang = lang } - static MethodBuilder createTestMethod(File stubsFile) { + static MethodBuilder createTestMethod(File stubsFile, Lang lang) { Map stubContent = new JsonSlurper().parse(stubsFile) String methodName = NamesUtil.uncapitalize(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) - return new MethodBuilder(methodName, stubContent) + return new MethodBuilder(methodName, stubContent, lang) } void appendTo(BlockBuilder blockBuilder) { - blockBuilder.addLine('@Test') - blockBuilder.addLine("public void $methodName() {") - new MethodBodyBuilder(stubContent).appendTo(blockBuilder) + String modifier + if (lang == Lang.JAVA) { + blockBuilder.addLine('@Test') + modifier = "public void " + } else { + modifier = "def " + } + blockBuilder.addLine(modifier + "$methodName() {") + new SpockMethodBodyBuilder(stubContent).appendTo(blockBuilder) blockBuilder.addLine('}') } } diff --git a/src/main/groovy/eu/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/src/main/groovy/eu/coderate/accurest/builder/SpockMethodBodyBuilder.groovy new file mode 100644 index 0000000000..1c6fc1924e --- /dev/null +++ b/src/main/groovy/eu/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -0,0 +1,49 @@ +package eu.coderate.accurest.builder + +import groovy.transform.PackageScope + +/** + * @author Jakub Kubrynski + */ +@PackageScope +class SpockMethodBodyBuilder { + private final Map stubDefinition + + SpockMethodBodyBuilder(Map stubDefinition) { + this.stubDefinition = stubDefinition + } + + void appendTo(BlockBuilder blockBuilder) { + blockBuilder.startBlock() + blockBuilder.addLine('given:').startBlock() + blockBuilder.addLine('def request = given()') + blockBuilder.startBlock().startBlock() + stubDefinition.request.headers.each { + blockBuilder.addLine(".header('$it.key', '$it.value.equalTo')") + } + if (stubDefinition.request.bodyPatterns) { + blockBuilder.addLine('.body(\'' + stubDefinition.request.bodyPatterns[0].matches + '\')') + } + + blockBuilder.endBlock().endBlock().endBlock().addEmptyLine() + + blockBuilder.addLine('when:').startBlock() + blockBuilder.addLine('def response = given().spec(request)') + blockBuilder.startBlock().startBlock() + blockBuilder.addLine('.' + stubDefinition.request.method.toLowerCase() + '("' + stubDefinition.request.url + '")') + blockBuilder.endBlock().endBlock().endBlock().addEmptyLine() + + blockBuilder.addLine('then:').startBlock() + blockBuilder.addLine('response.statusCode == ' + stubDefinition.response.status) + + stubDefinition.response.headers.each { + blockBuilder.addLine("response.header('$it.key') == '$it.value'") + } + if (stubDefinition.response.body) { + blockBuilder.addLine("Pattern.compile('$stubDefinition.response.body', Pattern.DOTALL).matcher(response.body.asString()).matches()") + } + blockBuilder.endBlock() + + blockBuilder.endBlock() + } +} diff --git a/src/main/resources/wiremocks/sample.json b/src/main/resources/stubs/wiremocks/sample.json similarity index 87% rename from src/main/resources/wiremocks/sample.json rename to src/main/resources/stubs/wiremocks/sample.json index 1f97ce2a57..822c33c545 100644 --- a/src/main/resources/wiremocks/sample.json +++ b/src/main/resources/stubs/wiremocks/sample.json @@ -1,7 +1,7 @@ { "request": { "method": "GET", - "url": "/some/thing" + "url": "/some" }, "response": { "status": 200, diff --git a/src/main/resources/stubs/wiremocks/shouldFail.json b/src/main/resources/stubs/wiremocks/shouldFail.json new file mode 100644 index 0000000000..2325c7c614 --- /dev/null +++ b/src/main/resources/stubs/wiremocks/shouldFail.json @@ -0,0 +1,17 @@ +{ + "request": { + "method": "POST", + "url": "/some/thing", + "headers": { + "Accept": { + "equalTo": "text/plain" + } + }, + "bodyPatterns" : [ { + "matches" : "{\"client\":\"1234\"}" + } ] + }, + "response": { + "status": 400 + } +} \ No newline at end of file diff --git a/src/main/resources/wiremocks/shouldFail.json b/src/main/resources/wiremocks/shouldFail.json deleted file mode 100644 index 7fd4b69fba..0000000000 --- a/src/main/resources/wiremocks/shouldFail.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "request": { - "method": "POST", - "url": "/some/thing" - }, - "response": { - "status": 400 - } -} \ No newline at end of file From 3497e94d8d7b80660eb126e7406115a19939fe0c Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 26 Jan 2015 00:38:37 +0100 Subject: [PATCH 009/719] Moved to Gradle. Introduced gradle plugin --- build.gradle | 42 +++++ .../io/coderate/accurest/TestGenerator.groovy | 93 ++++++++++ .../accurest/builder/BlockBuilder.groovy | 2 +- .../accurest/builder/ClassBuilder.groovy | 14 +- .../builder/JavaMethodBodyBuilder.groovy | 2 +- .../accurest/builder/MethodBuilder.groovy | 12 +- .../builder/SpockMethodBodyBuilder.groovy | 2 +- .../accurest/builder/TestFramework.groovy | 10 ++ .../coderate/accurest/util/NamesUtil.groovy | 6 +- .../resources/stubs/wiremocks/sample.json | 0 .../resources/stubs/wiremocks/shouldFail.json | 0 .../plugin/AccurestGradlePlugin.groovy | 32 ++++ .../plugin/AccurestPluginExtension.groovy | 13 ++ .../gradle-plugins/accurest.properties | 1 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 51018 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 164 ++++++++++++++++++ gradlew.bat | 90 ++++++++++ pom.xml | 66 ------- settings.gradle | 2 + .../eu/coderate/accurest/TestGenerator.groovy | 74 -------- .../eu/coderate/accurest/builder/Lang.groovy | 10 -- 22 files changed, 474 insertions(+), 167 deletions(-) create mode 100644 build.gradle create mode 100644 core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy rename {src/main/groovy/eu => core/src/main/groovy/io}/coderate/accurest/builder/BlockBuilder.groovy (95%) rename {src/main/groovy/eu => core/src/main/groovy/io}/coderate/accurest/builder/ClassBuilder.groovy (90%) rename {src/main/groovy/eu => core/src/main/groovy/io}/coderate/accurest/builder/JavaMethodBodyBuilder.groovy (90%) rename {src/main/groovy/eu => core/src/main/groovy/io}/coderate/accurest/builder/MethodBuilder.groovy (71%) rename {src/main/groovy/eu => core/src/main/groovy/io}/coderate/accurest/builder/SpockMethodBodyBuilder.groovy (97%) create mode 100644 core/src/main/groovy/io/coderate/accurest/builder/TestFramework.groovy rename {src/main/groovy/eu => core/src/main/groovy/io}/coderate/accurest/util/NamesUtil.groovy (85%) rename {src => core/src}/main/resources/stubs/wiremocks/sample.json (100%) rename {src => core/src}/main/resources/stubs/wiremocks/shouldFail.json (100%) create mode 100644 gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy create mode 100644 gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy create mode 100644 gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat delete mode 100644 pom.xml create mode 100644 settings.gradle delete mode 100644 src/main/groovy/eu/coderate/accurest/TestGenerator.groovy delete mode 100644 src/main/groovy/eu/coderate/accurest/builder/Lang.groovy diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000000..62d59ce6a8 --- /dev/null +++ b/build.gradle @@ -0,0 +1,42 @@ +subprojects { + apply plugin: 'groovy' + apply plugin: 'maven-publish' + + group = 'io.codearte.accurest' + version = '1.0.0-SNAPSHOT' + + sourceCompatibility = 1.7 + targetCompatibility = 1.7 + + repositories { + mavenLocal() + mavenCentral() + } + + dependencies { + compile 'org.codehaus.groovy:groovy-all:2.3.6' + testCompile 'org.spockframework:spock-core:0.7-groovy-2.0' + } + + publishing { + publications { + maven(MavenPublication) { + groupId 'io.codearte.accurest' + version '1.0.0-SNAPSHOT' + + from components.java + } + } + } +} + +project(':gradle-plugin') { + dependencies { + compile project(':core') + compile gradleApi() + } +} + +task wrapper(type: Wrapper) { + gradleVersion = '2.2.1' +} \ No newline at end of file diff --git a/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy new file mode 100644 index 0000000000..ae7cad56bd --- /dev/null +++ b/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -0,0 +1,93 @@ +package io.coderate.accurest + +import io.coderate.accurest.builder.ClassBuilder +import io.coderate.accurest.builder.TestFramework +import io.coderate.accurest.util.NamesUtil + +import java.nio.file.Files +import java.nio.file.Paths + +import static ClassBuilder.createClass +import static io.coderate.accurest.builder.MethodBuilder.createTestMethod + +/** + * @author Jakub Kubrynski + */ +class TestGenerator { + + private final String stubsBaseDirectory + private final String basePackageForTests + private final String baseClassForTests + private final String ruleClassForTests + private final TestFramework lang + private final String targetDirectory + + TestGenerator(String stubsBaseDirectory, String basePackageForTests, String baseClassForTests, + String ruleClassForTests, String testFramework, String targetDirectory) { +// URL stubsResource = getClass().getClassLoader().getResource(stubsBaseDirectory) + this.targetDirectory = targetDirectory + File stubsResource = new File(stubsBaseDirectory) + if (stubsResource == null) { + throw new IllegalStateException("Stubs directory not found under " + stubsBaseDirectory) + } + this.stubsBaseDirectory = stubsResource.path + this.basePackageForTests = basePackageForTests + if (testFramework == 'Spock' && !baseClassForTests) { + this.baseClassForTests = 'spock.lang.Specification' + } else { + this.baseClassForTests = baseClassForTests + } + this.ruleClassForTests = ruleClassForTests + this.lang = testFramework == 'Spock' ? TestFramework.SPOCK : TestFramework.JUNIT + } + + public String generate() { + StringBuilder builder = new StringBuilder() + List files = new File(stubsBaseDirectory).listFiles() + files.grep({ File file -> file.isDirectory() && containsStubs(file) }).each { + builder << addClass(it) + def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(basePackageForTests)) + Files.createDirectories(testBaseDir) + Files.write(Paths.get(testBaseDir.toString(), NamesUtil.capitalize(it.name) + getTestClassExtension()), addClass(it).bytes) + println testBaseDir + } + return builder + } + + private String getTestClassExtension() { + return lang == TestFramework.SPOCK ? '.groovy' : '.java' + } + + boolean containsStubs(File file) { + return file.list(new FilenameFilter() { + @Override + boolean accept(File dir, String name) { + return "json".equalsIgnoreCase(NamesUtil.afterLastDot(name)) + } + }).size() > 0 + } + + private String addClass(File directory) { + ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), basePackageForTests, baseClassForTests, lang) + .addStaticImport('com.jayway.restassured.RestAssured.*') + .addImport('java.util.regex.Pattern') + + if (lang == TestFramework.JUNIT) { + clazz.addImport('org.junit.Test') + } + + if (ruleClassForTests) { + clazz.addImport('org.junit.Rule') + .addRule(ruleClassForTests) + } + + directory.listFiles().each { + clazz.addMethod(createTestMethod(it, lang)) + } + return clazz.build() + } + + public static void main(String[] args) { + print new TestGenerator('stubs', 'io.test', '', '', 'Spock').generate() + } +} \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/builder/BlockBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy similarity index 95% rename from src/main/groovy/eu/coderate/accurest/builder/BlockBuilder.groovy rename to core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy index 3d159f139c..22f5247a5d 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/BlockBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy @@ -1,4 +1,4 @@ -package eu.coderate.accurest.builder +package io.coderate.accurest.builder import groovy.transform.PackageScope diff --git a/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy similarity index 90% rename from src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy rename to core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy index b893cbb5a6..690ae0c735 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/ClassBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy @@ -1,6 +1,6 @@ -package eu.coderate.accurest.builder +package io.coderate.accurest.builder -import eu.coderate.accurest.util.NamesUtil +import io.coderate.accurest.util.NamesUtil /** * @author Jakub Kubrynski @@ -17,7 +17,7 @@ class ClassBuilder { private final String modifier private final String suffix - private ClassBuilder(String className, String packageName, String baseClass, Lang lang) { + private ClassBuilder(String className, String packageName, String baseClass, TestFramework lang) { if (baseClass) { imports << baseClass } @@ -25,21 +25,21 @@ class ClassBuilder { this.packageName = packageName this.className = className switch (lang) { - case Lang.JAVA: + case TestFramework.JUNIT: modifier = "public " suffix = ";" break - case Lang.GROOVY: + case TestFramework.SPOCK: modifier = "" suffix = "" } } - static ClassBuilder createClass(String className, String packageName, Lang lang) { + static ClassBuilder createClass(String className, String packageName, TestFramework lang) { return createClass(className, packageName, null, lang) } - static ClassBuilder createClass(String className, String packageName, String baseClass, Lang lang) { + static ClassBuilder createClass(String className, String packageName, String baseClass, TestFramework lang) { return new ClassBuilder(className, packageName, baseClass, lang) } diff --git a/src/main/groovy/eu/coderate/accurest/builder/JavaMethodBodyBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/JavaMethodBodyBuilder.groovy similarity index 90% rename from src/main/groovy/eu/coderate/accurest/builder/JavaMethodBodyBuilder.groovy rename to core/src/main/groovy/io/coderate/accurest/builder/JavaMethodBodyBuilder.groovy index c8a54548ce..ec459370e8 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/JavaMethodBodyBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/JavaMethodBodyBuilder.groovy @@ -1,4 +1,4 @@ -package eu.coderate.accurest.builder +package io.coderate.accurest.builder /** * @author Jakub Kubrynski diff --git a/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy similarity index 71% rename from src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy rename to core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy index 07f11e3987..3df9cf8146 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/MethodBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy @@ -1,6 +1,6 @@ -package eu.coderate.accurest.builder +package io.coderate.accurest.builder -import eu.coderate.accurest.util.NamesUtil +import io.coderate.accurest.util.NamesUtil import groovy.json.JsonSlurper /** @@ -10,15 +10,15 @@ class MethodBuilder { private final String methodName private final Map stubContent - private final Lang lang + private final TestFramework lang - private MethodBuilder(String methodName, Map stubContent, Lang lang) { + private MethodBuilder(String methodName, Map stubContent, TestFramework lang) { this.stubContent = stubContent this.methodName = methodName this.lang = lang } - static MethodBuilder createTestMethod(File stubsFile, Lang lang) { + static MethodBuilder createTestMethod(File stubsFile, TestFramework lang) { Map stubContent = new JsonSlurper().parse(stubsFile) String methodName = NamesUtil.uncapitalize(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) return new MethodBuilder(methodName, stubContent, lang) @@ -26,7 +26,7 @@ class MethodBuilder { void appendTo(BlockBuilder blockBuilder) { String modifier - if (lang == Lang.JAVA) { + if (lang == TestFramework.JUNIT) { blockBuilder.addLine('@Test') modifier = "public void " } else { diff --git a/src/main/groovy/eu/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy similarity index 97% rename from src/main/groovy/eu/coderate/accurest/builder/SpockMethodBodyBuilder.groovy rename to core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 1c6fc1924e..9b1a1d868d 100644 --- a/src/main/groovy/eu/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,4 +1,4 @@ -package eu.coderate.accurest.builder +package io.coderate.accurest.builder import groovy.transform.PackageScope diff --git a/core/src/main/groovy/io/coderate/accurest/builder/TestFramework.groovy b/core/src/main/groovy/io/coderate/accurest/builder/TestFramework.groovy new file mode 100644 index 0000000000..9c7e5e5b78 --- /dev/null +++ b/core/src/main/groovy/io/coderate/accurest/builder/TestFramework.groovy @@ -0,0 +1,10 @@ +package io.coderate.accurest.builder + +/** + * @author Jakub Kubrynski + */ +enum TestFramework { + + JUNIT, SPOCK + +} \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy b/core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy similarity index 85% rename from src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy rename to core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy index d330ce6e51..c15f143d14 100644 --- a/src/main/groovy/eu/coderate/accurest/util/NamesUtil.groovy +++ b/core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy @@ -1,4 +1,4 @@ -package eu.coderate.accurest.util +package io.coderate.accurest.util /** * @author Jakub Kubrynski @@ -38,4 +38,8 @@ class NamesUtil { } return string } + + static String packageToDirectory(String packageName) { + return packageName.replaceAll('\\.', File.separator) + } } diff --git a/src/main/resources/stubs/wiremocks/sample.json b/core/src/main/resources/stubs/wiremocks/sample.json similarity index 100% rename from src/main/resources/stubs/wiremocks/sample.json rename to core/src/main/resources/stubs/wiremocks/sample.json diff --git a/src/main/resources/stubs/wiremocks/shouldFail.json b/core/src/main/resources/stubs/wiremocks/shouldFail.json similarity index 100% rename from src/main/resources/stubs/wiremocks/shouldFail.json rename to core/src/main/resources/stubs/wiremocks/shouldFail.json diff --git a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy new file mode 100644 index 0000000000..c2cd342d4f --- /dev/null +++ b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy @@ -0,0 +1,32 @@ +package io.codearte.accurest.plugin + +import io.coderate.accurest.TestGenerator +import org.gradle.api.Plugin +import org.gradle.api.Project + +/** + * @author Jakub Kubrynski + */ +class AccurestGradlePlugin implements Plugin { + + @Override + void apply(Project project) { + project.extensions.create('accurest', AccurestPluginExtension) + project.task('generateAccurest') << { + AccurestPluginExtension accurest = project.accurest + project.logger.info("Accurest Plugin: Invoking test sources generation") + +// project.sourceSets.test.allSource.class.getDeclaredMethods().each {println it.name} + + try { + TestGenerator generator = new TestGenerator(project.projectDir.path + '/src/test/resources/' + accurest.stubsBaseDirectory, accurest.basePackageForTests, + accurest.baseClassForTests, accurest.ruleClassForTests, + accurest.targetFramework, project.buildDir.path + '/' + accurest.generatedTestSourcesDir) + generator.generate() + } catch (IllegalStateException e) { + project.logger.error("Accurest Plugin: {}", e.getMessage()) + } + } + } + +} diff --git a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy new file mode 100644 index 0000000000..d873cf71c1 --- /dev/null +++ b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy @@ -0,0 +1,13 @@ +package io.codearte.accurest.plugin + +/** + * @author Jakub Kubrynski + */ +class AccurestPluginExtension { + String targetFramework = 'Spock' + String stubsBaseDirectory = 'mappings' + String basePackageForTests = 'io.codearte.accurest.tests' + String baseClassForTests + String ruleClassForTests + String generatedTestSourcesDir = "generated-test-sources" +} diff --git a/gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties b/gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties new file mode 100644 index 0000000000..edfd566c2c --- /dev/null +++ b/gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties @@ -0,0 +1 @@ +implementation-class=io.codearte.accurest.plugin.AccurestGradlePlugin \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..c97a8bdb9088d370da7e88784a7a093b971aa23a GIT binary patch literal 51018 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +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"` + + # 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 "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000000..8a0b282aa6 --- /dev/null +++ b/gradlew.bat @@ -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 Windowz 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 diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 18562cbc40..0000000000 --- a/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - 4.0.0 - - eu.codearte.accurest - accurest - 1.0.0-SNAPSHOT - - - 2.3.7 - - - - - org.codehaus.groovy - groovy-all - ${groovy.version} - - - - junit - junit - 4.11 - test - - - com.jayway.restassured - rest-assured - 2.4.0 - test - - - org.spockframework - spock-core - 0.7-groovy-2.0 - test - - - - com.github.tomakehurst - wiremock - 1.53 - - - - - - - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.2 - - - - compile - testCompile - - - - - - - \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000000..f27693d39b --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +include "core", "gradle-plugin" +rootProject.name = "accurest" \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy b/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy deleted file mode 100644 index d7427db151..0000000000 --- a/src/main/groovy/eu/coderate/accurest/TestGenerator.groovy +++ /dev/null @@ -1,74 +0,0 @@ -package eu.coderate.accurest - -import eu.coderate.accurest.builder.ClassBuilder -import eu.coderate.accurest.builder.Lang -import eu.coderate.accurest.util.NamesUtil - -import static eu.coderate.accurest.builder.ClassBuilder.createClass -import static eu.coderate.accurest.builder.MethodBuilder.createTestMethod - -/** - * @author Jakub Kubrynski - */ -class TestGenerator { - - private final String mocksBaseDirectory - private final String basePackageForTests - private final String baseClassForTests - private final String ruleClassForTests - private final Lang lang - - TestGenerator(String mocksBaseDirectory, String basePackageForTests, String baseClassForTests, String ruleClassForTests, Lang lang) { - this.mocksBaseDirectory = getClass().getClassLoader().getResource(mocksBaseDirectory).path - this.basePackageForTests = basePackageForTests - if (lang == Lang.GROOVY && !baseClassForTests) { - this.baseClassForTests = 'spock.lang.Specification' - } else { - this.baseClassForTests = baseClassForTests - } - this.ruleClassForTests = ruleClassForTests - this.lang = lang - } - - public String generate() { - StringBuilder builder = new StringBuilder() - List files = new File(mocksBaseDirectory).listFiles() - files.grep({ File file -> file.isDirectory() && containsStubs(file) }).each { - builder << addClass(it) - } - return builder - } - - boolean containsStubs(File file) { - return file.list(new FilenameFilter() { - @Override - boolean accept(File dir, String name) { - return "json".equalsIgnoreCase(NamesUtil.afterLastDot(name)) - } - }).size() > 0 - } - - private String addClass(File directory) { - ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), basePackageForTests, baseClassForTests, lang) - .addStaticImport('com.jayway.restassured.RestAssured.*') - .addImport('java.util.regex.Pattern') - - if (lang == Lang.JAVA) { - clazz.addImport('org.junit.Test') - } - - if (ruleClassForTests) { - clazz.addImport('org.junit.Rule') - .addRule(ruleClassForTests) - } - - directory.listFiles().each { - clazz.addMethod(createTestMethod(it, lang)) - } - return clazz.build() - } - - public static void main(String[] args) { - print new TestGenerator('stubs', 'io.test', '', '', Lang.GROOVY).generate() - } -} \ No newline at end of file diff --git a/src/main/groovy/eu/coderate/accurest/builder/Lang.groovy b/src/main/groovy/eu/coderate/accurest/builder/Lang.groovy deleted file mode 100644 index dd7f7b07ee..0000000000 --- a/src/main/groovy/eu/coderate/accurest/builder/Lang.groovy +++ /dev/null @@ -1,10 +0,0 @@ -package eu.coderate.accurest.builder - -/** - * @author Jakub Kubrynski - */ -enum Lang { - - JAVA, GROOVY - -} \ No newline at end of file From 375039fe4562fa8d2cf987c6d2b3546c4b2b5181 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 26 Jan 2015 22:47:28 +0100 Subject: [PATCH 010/719] Gradle plugin sources sets are now treated correctly --- build.gradle | 61 ++++++++++--------- .../accurest/builder/ClassBuilder.groovy | 6 +- ...r.groovy => JUnitMethodBodyBuilder.groovy} | 2 +- .../accurest/builder/MethodBuilder.groovy | 6 +- .../coderate/accurest/util/NamesUtil.groovy | 4 +- .../accurest/util/StubMappingConverter.groovy | 41 +++++++++++++ .../resources/stubs/wiremocks/shouldFail.json | 8 ++- .../plugin/AccurestGradlePlugin.groovy | 34 ++++++++--- .../plugin/AccurestPluginExtension.groovy | 2 +- 9 files changed, 116 insertions(+), 48 deletions(-) rename core/src/main/groovy/io/coderate/accurest/builder/{JavaMethodBodyBuilder.groovy => JUnitMethodBodyBuilder.groovy} (92%) create mode 100644 core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy diff --git a/build.gradle b/build.gradle index 62d59ce6a8..17185ff7a0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,42 +1,47 @@ subprojects { - apply plugin: 'groovy' - apply plugin: 'maven-publish' + apply plugin: 'groovy' + apply plugin: 'maven-publish' - group = 'io.codearte.accurest' - version = '1.0.0-SNAPSHOT' + group = 'io.codearte.accurest' + version = '1.0.0-SNAPSHOT' - sourceCompatibility = 1.7 - targetCompatibility = 1.7 + sourceCompatibility = 1.7 + targetCompatibility = 1.7 - repositories { - mavenLocal() - mavenCentral() - } + repositories { + mavenLocal() + mavenCentral() + } - dependencies { - compile 'org.codehaus.groovy:groovy-all:2.3.6' - testCompile 'org.spockframework:spock-core:0.7-groovy-2.0' - } + dependencies { + compile 'org.codehaus.groovy:groovy-all:2.3.6' + testCompile 'org.spockframework:spock-core:0.7-groovy-2.0' + } - publishing { - publications { - maven(MavenPublication) { - groupId 'io.codearte.accurest' - version '1.0.0-SNAPSHOT' + publishing { + publications { + maven(MavenPublication) { + groupId 'io.codearte.accurest' + version '1.0.0-SNAPSHOT' - from components.java - } - } - } + from components.java + } + } + } +} + +project(':core') { + dependencies { + } } project(':gradle-plugin') { - dependencies { - compile project(':core') - compile gradleApi() - } + dependencies { + compile project(':core') + compile gradleApi() + } } task wrapper(type: Wrapper) { - gradleVersion = '2.2.1' + gradleVersion = '2.2.1' } \ No newline at end of file diff --git a/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy index 690ae0c735..361d9cdfb2 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy @@ -66,8 +66,8 @@ class ClassBuilder { String build() { BlockBuilder clazz = new BlockBuilder("\t") - .addLine("package $packageName" + suffix) - .addEmptyLine() + .addLine("package $packageName" + suffix) + .addEmptyLine() imports.sort().each { clazz.addLine("import $it" + suffix) @@ -93,7 +93,7 @@ class ClassBuilder { clazz.startBlock() rules.sort().each { clazz.addLine("@Rule") - clazz.addLine("public " + it + " " + NamesUtil.uncapitalize(it) + " = new $it()" + suffix) + clazz.addLine("public " + it + " " + NamesUtil.camelCase(it) + " = new $it()" + suffix) } clazz.endBlock() if (!rules.empty) { diff --git a/core/src/main/groovy/io/coderate/accurest/builder/JavaMethodBodyBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy similarity index 92% rename from core/src/main/groovy/io/coderate/accurest/builder/JavaMethodBodyBuilder.groovy rename to core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy index ec459370e8..b81628533b 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/JavaMethodBodyBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -3,7 +3,7 @@ package io.coderate.accurest.builder /** * @author Jakub Kubrynski */ -class JavaMethodBodyBuilder { +class JUnitMethodBodyBuilder { /* given() .contentType("application/json") diff --git a/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy index 3df9cf8146..137e0d1066 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy @@ -1,7 +1,7 @@ package io.coderate.accurest.builder import io.coderate.accurest.util.NamesUtil -import groovy.json.JsonSlurper +import io.coderate.accurest.util.StubMappingConverter /** * @author Jakub Kubrynski @@ -19,8 +19,8 @@ class MethodBuilder { } static MethodBuilder createTestMethod(File stubsFile, TestFramework lang) { - Map stubContent = new JsonSlurper().parse(stubsFile) - String methodName = NamesUtil.uncapitalize(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) + Map stubContent = StubMappingConverter.toStubMappingOnServerSide(stubsFile) + String methodName = NamesUtil.camelCase(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) return new MethodBuilder(methodName, stubContent, lang) } diff --git a/core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy b/core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy index c15f143d14..f40034e002 100644 --- a/core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy +++ b/core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy @@ -7,7 +7,7 @@ class NamesUtil { static String afterLast(String string, String separator) { if (string?.indexOf(separator) > -1) { - return string.substring(string.lastIndexOf(separator)+1) + return string.substring(string.lastIndexOf(separator) + 1) } return string } @@ -16,7 +16,7 @@ class NamesUtil { return afterLast(string, '.') } - static String uncapitalize(String className) { + static String camelCase(String className) { if (!className) { return className } diff --git a/core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy b/core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy new file mode 100644 index 0000000000..2315d5bc18 --- /dev/null +++ b/core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy @@ -0,0 +1,41 @@ +package io.coderate.accurest.util + +import groovy.json.JsonSlurper + +import java.util.regex.Pattern + +/** + * @author Marcin Grzejszczak + */ +class StubMappingConverter { + + private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(/^\$\{(.*)\}:\$\{(.*)\}$/) + public static final int SERVER_SIDE_GROUP = 2 + + static Map toStubMappingOnServerSide(File stubMapping) { + def json = new JsonSlurper().parse(stubMapping) + convertPlaceholders(json as Map, { String value -> + getGroupFromMatchingPattern(value) + }) + return json + } + + private static void convertPlaceholders(Map map, Closure closure) { + map.each { + if (it instanceof Map.Entry) { + Map.Entry entry = it as Map.Entry + if (entry.value instanceof String) { + String value = entry.value as String + entry.value = closure(value) + } else if (entry.value instanceof Map) { + convertPlaceholders(entry.value as Map, closure) + } + } + } + } + + private static Object getGroupFromMatchingPattern(String value) { + return value.matches(PLACEHOLDER_PATTERN) ? PLACEHOLDER_PATTERN.matcher(value)[0][SERVER_SIDE_GROUP] : value + } + +} diff --git a/core/src/main/resources/stubs/wiremocks/shouldFail.json b/core/src/main/resources/stubs/wiremocks/shouldFail.json index 2325c7c614..9262423d68 100644 --- a/core/src/main/resources/stubs/wiremocks/shouldFail.json +++ b/core/src/main/resources/stubs/wiremocks/shouldFail.json @@ -7,9 +7,11 @@ "equalTo": "text/plain" } }, - "bodyPatterns" : [ { - "matches" : "{\"client\":\"1234\"}" - } ] + "bodyPatterns": [ + { + "matches": "{\"client\":\"1234\"}" + } + ] }, "response": { "status": 400 diff --git a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy index c2cd342d4f..aab99400f8 100644 --- a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy +++ b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy @@ -9,24 +9,44 @@ import org.gradle.api.Project */ class AccurestGradlePlugin implements Plugin { + private static final String TASK_NAME = 'generateAccurest' + + private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin + @Override void apply(Project project) { - project.extensions.create('accurest', AccurestPluginExtension) - project.task('generateAccurest') << { - AccurestPluginExtension accurest = project.accurest + AccurestPluginExtension extension = project.extensions.create('accurest', AccurestPluginExtension) + + project.compileTestGroovy.dependsOn(TASK_NAME) + + project.task(TASK_NAME) << { project.logger.info("Accurest Plugin: Invoking test sources generation") -// project.sourceSets.test.allSource.class.getDeclaredMethods().each {println it.name} + project.sourceSets.test.groovy { + srcDir extension.generatedTestSourcesDir + } try { - TestGenerator generator = new TestGenerator(project.projectDir.path + '/src/test/resources/' + accurest.stubsBaseDirectory, accurest.basePackageForTests, - accurest.baseClassForTests, accurest.ruleClassForTests, - accurest.targetFramework, project.buildDir.path + '/' + accurest.generatedTestSourcesDir) + TestGenerator generator = new TestGenerator(project.projectDir.path + '/src/test/resources/' + extension.stubsBaseDirectory, extension.basePackageForTests, + extension.baseClassForTests, extension.ruleClassForTests, + extension.targetFramework, extension.generatedTestSourcesDir) generator.generate() } catch (IllegalStateException e) { project.logger.error("Accurest Plugin: {}", e.getMessage()) } } + + project.afterEvaluate { + def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) + if (hasIdea) { + project.idea { + module { + testSourceDirs += new File(extension.generatedTestSourcesDir) + } + } + } + } + } } diff --git a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy index d873cf71c1..f12f072f47 100644 --- a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy +++ b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy @@ -9,5 +9,5 @@ class AccurestPluginExtension { String basePackageForTests = 'io.codearte.accurest.tests' String baseClassForTests String ruleClassForTests - String generatedTestSourcesDir = "generated-test-sources" + String generatedTestSourcesDir = 'build/generated-sources/accurest' } From 7bd5269cf76f98a4b2eb747b4a1650af0ef11007 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 01:16:19 +0100 Subject: [PATCH 011/719] Generating test cases for simple stubs --- build.gradle | 13 +++++++---- .../io/coderate/accurest/TestGenerator.groovy | 23 ++++++++++++------- .../accurest/builder/ClassBuilder.groovy | 1 + .../accurest/builder/MethodBuilder.groovy | 1 + .../builder/SpockMethodBodyBuilder.groovy | 9 +++++++- .../{builder => config}/TestFramework.groovy | 4 +--- .../coderate/accurest/config/TestMode.groovy | 8 +++++++ .../resources/stubs/wiremocks/sample.json | 2 +- .../resources/stubs/wiremocks/shouldFail.json | 19 --------------- .../plugin/AccurestGradlePlugin.groovy | 8 ++++--- .../plugin/AccurestPluginExtension.groovy | 6 ++++- 11 files changed, 54 insertions(+), 40 deletions(-) rename core/src/main/groovy/io/coderate/accurest/{builder => config}/TestFramework.groovy (64%) create mode 100644 core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy delete mode 100644 core/src/main/resources/stubs/wiremocks/shouldFail.json diff --git a/build.gradle b/build.gradle index 17185ff7a0..4ad2b60479 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,14 @@ +ext { + projectVersion = '0.1.0-SNAPSHOT' + projectGroup = 'io.codearte.accurest' +} + subprojects { apply plugin: 'groovy' apply plugin: 'maven-publish' - group = 'io.codearte.accurest' - version = '1.0.0-SNAPSHOT' + group = projectGroup + version = projectVersion sourceCompatibility = 1.7 targetCompatibility = 1.7 @@ -21,8 +26,8 @@ subprojects { publishing { publications { maven(MavenPublication) { - groupId 'io.codearte.accurest' - version '1.0.0-SNAPSHOT' + groupId projectGroup + version projectVersion from components.java } diff --git a/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index ae7cad56bd..be40bc05ba 100644 --- a/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -1,7 +1,8 @@ package io.coderate.accurest import io.coderate.accurest.builder.ClassBuilder -import io.coderate.accurest.builder.TestFramework +import io.coderate.accurest.config.TestFramework +import io.coderate.accurest.config.TestMode import io.coderate.accurest.util.NamesUtil import java.nio.file.Files @@ -21,10 +22,11 @@ class TestGenerator { private final String ruleClassForTests private final TestFramework lang private final String targetDirectory + private final TestMode testMode TestGenerator(String stubsBaseDirectory, String basePackageForTests, String baseClassForTests, - String ruleClassForTests, String testFramework, String targetDirectory) { -// URL stubsResource = getClass().getClassLoader().getResource(stubsBaseDirectory) + String ruleClassForTests, TestFramework testFramework, TestMode testMode, String targetDirectory) { + this.testMode = testMode this.targetDirectory = targetDirectory File stubsResource = new File(stubsBaseDirectory) if (stubsResource == null) { @@ -38,7 +40,7 @@ class TestGenerator { this.baseClassForTests = baseClassForTests } this.ruleClassForTests = ruleClassForTests - this.lang = testFramework == 'Spock' ? TestFramework.SPOCK : TestFramework.JUNIT + this.lang = testFramework } public String generate() { @@ -49,7 +51,6 @@ class TestGenerator { def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(basePackageForTests)) Files.createDirectories(testBaseDir) Files.write(Paths.get(testBaseDir.toString(), NamesUtil.capitalize(it.name) + getTestClassExtension()), addClass(it).bytes) - println testBaseDir } return builder } @@ -69,11 +70,17 @@ class TestGenerator { private String addClass(File directory) { ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), basePackageForTests, baseClassForTests, lang) - .addStaticImport('com.jayway.restassured.RestAssured.*') - .addImport('java.util.regex.Pattern') + + if (testMode == TestMode.MOCKMVC) { + clazz.addStaticImport('com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*') + } else { + clazz.addStaticImport('com.jayway.restassured.RestAssured.*') + } if (lang == TestFramework.JUNIT) { clazz.addImport('org.junit.Test') + } else { + clazz.addImport('groovy.json.JsonSlurper') } if (ruleClassForTests) { @@ -88,6 +95,6 @@ class TestGenerator { } public static void main(String[] args) { - print new TestGenerator('stubs', 'io.test', '', '', 'Spock').generate() + print new TestGenerator('/home/devel/projects/codearte/accurest/core/src/main/resources/stubs', 'io.test', '', '', TestFramework.SPOCK, TestMode.MOCKMVC, "").generate() } } \ No newline at end of file diff --git a/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy index 361d9cdfb2..7a07910bff 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy @@ -1,5 +1,6 @@ package io.coderate.accurest.builder +import io.coderate.accurest.config.TestFramework import io.coderate.accurest.util.NamesUtil /** diff --git a/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy index 137e0d1066..60cd6a074b 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy @@ -1,5 +1,6 @@ package io.coderate.accurest.builder +import io.coderate.accurest.config.TestFramework import io.coderate.accurest.util.NamesUtil import io.coderate.accurest.util.StubMappingConverter diff --git a/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 9b1a1d868d..528202f41d 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -40,7 +40,14 @@ class SpockMethodBodyBuilder { blockBuilder.addLine("response.header('$it.key') == '$it.value'") } if (stubDefinition.response.body) { - blockBuilder.addLine("Pattern.compile('$stubDefinition.response.body', Pattern.DOTALL).matcher(response.body.asString()).matches()") + blockBuilder.addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') + new groovy.json.JsonSlurper().parseText(stubDefinition.response.body).each { + def value = it.value + if (value instanceof String) { + value = '"' + value + '"' + } + blockBuilder.addLine('responseBody.' + it.key + ' == ' + value) + } } blockBuilder.endBlock() diff --git a/core/src/main/groovy/io/coderate/accurest/builder/TestFramework.groovy b/core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy similarity index 64% rename from core/src/main/groovy/io/coderate/accurest/builder/TestFramework.groovy rename to core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy index 9c7e5e5b78..1a468b1fcb 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/TestFramework.groovy +++ b/core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy @@ -1,10 +1,8 @@ -package io.coderate.accurest.builder +package io.coderate.accurest.config /** * @author Jakub Kubrynski */ enum TestFramework { - JUNIT, SPOCK - } \ No newline at end of file diff --git a/core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy b/core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy new file mode 100644 index 0000000000..f5a7b86389 --- /dev/null +++ b/core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy @@ -0,0 +1,8 @@ +package io.coderate.accurest.config + +/** + * @author Jakub Kubrynski + */ +enum TestMode { + MOCKMVC, EXPLICIT +} \ No newline at end of file diff --git a/core/src/main/resources/stubs/wiremocks/sample.json b/core/src/main/resources/stubs/wiremocks/sample.json index 822c33c545..7ad5ef1a63 100644 --- a/core/src/main/resources/stubs/wiremocks/sample.json +++ b/core/src/main/resources/stubs/wiremocks/sample.json @@ -5,7 +5,7 @@ }, "response": { "status": 200, - "body": "Hello world!", + "body": "{\"loanApplicationStatus\":\"LOAN_APPLIED\",\"loanApplicationId\":123123123}", "headers": { "Content-Type": "text/plain" } diff --git a/core/src/main/resources/stubs/wiremocks/shouldFail.json b/core/src/main/resources/stubs/wiremocks/shouldFail.json deleted file mode 100644 index 9262423d68..0000000000 --- a/core/src/main/resources/stubs/wiremocks/shouldFail.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "request": { - "method": "POST", - "url": "/some/thing", - "headers": { - "Accept": { - "equalTo": "text/plain" - } - }, - "bodyPatterns": [ - { - "matches": "{\"client\":\"1234\"}" - } - ] - }, - "response": { - "status": 400 - } -} \ No newline at end of file diff --git a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy index aab99400f8..38f5567c29 100644 --- a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy +++ b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy @@ -27,9 +27,11 @@ class AccurestGradlePlugin implements Plugin { } try { - TestGenerator generator = new TestGenerator(project.projectDir.path + '/src/test/resources/' + extension.stubsBaseDirectory, extension.basePackageForTests, - extension.baseClassForTests, extension.ruleClassForTests, - extension.targetFramework, extension.generatedTestSourcesDir) + String resourceDirectory = project.projectDir.path + '/src/test/resources/' + extension.stubsBaseDirectory + TestGenerator generator = new TestGenerator(resourceDirectory, + extension.basePackageForTests, extension.baseClassForTests, extension.ruleClassForTests, + extension.targetFramework, extension.testMode, + extension.generatedTestSourcesDir) generator.generate() } catch (IllegalStateException e) { project.logger.error("Accurest Plugin: {}", e.getMessage()) diff --git a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy index f12f072f47..970834d9cb 100644 --- a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy +++ b/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy @@ -1,10 +1,14 @@ package io.codearte.accurest.plugin +import io.coderate.accurest.config.TestFramework +import io.coderate.accurest.config.TestMode + /** * @author Jakub Kubrynski */ class AccurestPluginExtension { - String targetFramework = 'Spock' + TestFramework targetFramework = TestFramework.SPOCK + TestMode testMode = TestMode.EXPLICIT String stubsBaseDirectory = 'mappings' String basePackageForTests = 'io.codearte.accurest.tests' String baseClassForTests From a47b2134bfc803756810ccd3a5cf9a37fc30ba74 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 01:37:40 +0100 Subject: [PATCH 012/719] Release version 0.1.0 --- build.gradle | 5 ++-- release.gradle | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 release.gradle diff --git a/build.gradle b/build.gradle index 4ad2b60479..2707aedf5a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,12 @@ ext { - projectVersion = '0.1.0-SNAPSHOT' + projectVersion = '0.1.0' projectGroup = 'io.codearte.accurest' } subprojects { apply plugin: 'groovy' apply plugin: 'maven-publish' + apply from: "$rootDir/release.gradle" group = projectGroup version = projectVersion @@ -36,8 +37,6 @@ subprojects { } project(':core') { - dependencies { - } } project(':gradle-plugin') { diff --git a/release.gradle b/release.gradle new file mode 100644 index 0000000000..e772848864 --- /dev/null +++ b/release.gradle @@ -0,0 +1,64 @@ +apply plugin: 'maven' +apply plugin: 'signing' + +task javadocJar(type: Jar) { + classifier = 'javadoc' + from javadoc +} + +task sourcesJar(type: Jar) { + classifier = 'sources' + from sourceSets.main.allSource +} + +artifacts { + archives javadocJar, sourcesJar +} + +signing { + sign configurations.archives +} + +uploadArchives { + repositories { + mavenDeployer { + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + + repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { + authentication(userName: sonatypeUsername, password: sonatypePassword) + } + + snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { + authentication(userName: sonatypeUsername, password: sonatypePassword) + } + + pom.project { + name "$project.name" + packaging 'jar' + description 'RESTful Contract Verifier' + url 'http://codearte.github.io/accurest' + + scm { + connection 'scm:git:git@github.com:Codearte/accurest.git' + developerConnection 'scm:git:git@github.com:Codearte/accurest.git' + url 'https://github.com/Codearte/accurest' + } + + licenses { + license { + name 'The Apache License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + + developers { + developer { + id 'jkubrynski' + name 'Jakub Kubrynski' + email 'jk ATT codearte DOTT io' + } + } + } + } + } +} \ No newline at end of file From 566e2f98bbefd8f97895bde2d54877d2072dabab Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 01:38:19 +0100 Subject: [PATCH 013/719] Next development version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2707aedf5a..3abfb5433a 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.1.0' + projectVersion = '0.2.0-SNAPSHOT' projectGroup = 'io.codearte.accurest' } From a2763f7c1c8d4f5ce09ada8f175cfbf15c286849 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 14:48:25 +0100 Subject: [PATCH 014/719] Refactoring to GString and fixed StubMappingConverter --- .../io/coderate/accurest/TestGenerator.groovy | 7 ++--- .../accurest/builder/BlockBuilder.groovy | 12 +++++++- .../accurest/builder/ClassBuilder.groovy | 10 +++---- .../builder/SpockMethodBodyBuilder.groovy | 26 ++++++++++------- .../accurest/util/StubMappingConverter.groovy | 29 ++++++++++--------- .../resources/stubs/wiremocks/sample.json | 2 +- 6 files changed, 51 insertions(+), 35 deletions(-) diff --git a/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index be40bc05ba..bca414595f 100644 --- a/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -43,16 +43,13 @@ class TestGenerator { this.lang = testFramework } - public String generate() { - StringBuilder builder = new StringBuilder() + public void generate() { List files = new File(stubsBaseDirectory).listFiles() files.grep({ File file -> file.isDirectory() && containsStubs(file) }).each { - builder << addClass(it) def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(basePackageForTests)) Files.createDirectories(testBaseDir) Files.write(Paths.get(testBaseDir.toString(), NamesUtil.capitalize(it.name) + getTestClassExtension()), addClass(it).bytes) } - return builder } private String getTestClassExtension() { @@ -95,6 +92,6 @@ class TestGenerator { } public static void main(String[] args) { - print new TestGenerator('/home/devel/projects/codearte/accurest/core/src/main/resources/stubs', 'io.test', '', '', TestFramework.SPOCK, TestMode.MOCKMVC, "").generate() + new TestGenerator('/home/devel/projects/codearte/accurest/core/src/main/resources/stubs', 'io.test', '', '', TestFramework.SPOCK, TestMode.MOCKMVC, "").generate() } } \ No newline at end of file diff --git a/core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy index 22f5247a5d..31e8a05aac 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy @@ -27,6 +27,16 @@ class BlockBuilder { return this } + BlockBuilder indent() { + startBlock().startBlock() + return this + } + + BlockBuilder unindent() { + endBlock().endBlock() + return this + } + BlockBuilder addLine(String line) { addIndentation() builder << "$line\n" @@ -38,7 +48,7 @@ class BlockBuilder { return this } - void addIndentation() { + private void addIndentation() { indents.times { builder << spacer } diff --git a/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy index 7a07910bff..7e368f8490 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy @@ -67,24 +67,24 @@ class ClassBuilder { String build() { BlockBuilder clazz = new BlockBuilder("\t") - .addLine("package $packageName" + suffix) + .addLine("package $packageName$suffix") .addEmptyLine() imports.sort().each { - clazz.addLine("import $it" + suffix) + clazz.addLine("import $it$suffix") } if (!imports.empty) { clazz.addEmptyLine() } staticImports.sort().each { - clazz.addLine("import static $it" + suffix) + clazz.addLine("import static $it$suffix") } if (!staticImports.empty) { clazz.addEmptyLine() } - def classLine = modifier + "class $className" + def classLine = "${modifier}class $className" if (baseClass) { classLine += " extends $baseClass" } @@ -94,7 +94,7 @@ class ClassBuilder { clazz.startBlock() rules.sort().each { clazz.addLine("@Rule") - clazz.addLine("public " + it + " " + NamesUtil.camelCase(it) + " = new $it()" + suffix) + clazz.addLine("public $it ${NamesUtil.camelCase(it)} = new $it()$suffix") } clazz.endBlock() if (!rules.empty) { diff --git a/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 528202f41d..85316e747a 100644 --- a/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -17,36 +17,42 @@ class SpockMethodBodyBuilder { blockBuilder.startBlock() blockBuilder.addLine('given:').startBlock() blockBuilder.addLine('def request = given()') - blockBuilder.startBlock().startBlock() + blockBuilder.indent() stubDefinition.request.headers.each { blockBuilder.addLine(".header('$it.key', '$it.value.equalTo')") } if (stubDefinition.request.bodyPatterns) { - blockBuilder.addLine('.body(\'' + stubDefinition.request.bodyPatterns[0].matches + '\')') + blockBuilder.addLine(".body('${stubDefinition.request.bodyPatterns[0].matches}')") } - blockBuilder.endBlock().endBlock().endBlock().addEmptyLine() + blockBuilder.unindent().endBlock().addEmptyLine() blockBuilder.addLine('when:').startBlock() blockBuilder.addLine('def response = given().spec(request)') - blockBuilder.startBlock().startBlock() - blockBuilder.addLine('.' + stubDefinition.request.method.toLowerCase() + '("' + stubDefinition.request.url + '")') - blockBuilder.endBlock().endBlock().endBlock().addEmptyLine() + blockBuilder.indent() + blockBuilder.addLine(".${stubDefinition.request.method.toLowerCase()}(\"$stubDefinition.request.url\")") + blockBuilder.unindent().endBlock().addEmptyLine() blockBuilder.addLine('then:').startBlock() - blockBuilder.addLine('response.statusCode == ' + stubDefinition.response.status) + blockBuilder.addLine("response.statusCode == $stubDefinition.response.status") stubDefinition.response.headers.each { blockBuilder.addLine("response.header('$it.key') == '$it.value'") } if (stubDefinition.response.body) { blockBuilder.addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') - new groovy.json.JsonSlurper().parseText(stubDefinition.response.body).each { + stubDefinition.response.body.each { def value = it.value if (value instanceof String) { - value = '"' + value + '"' + if (value.startsWith('$')) { + value = value.substring(1).replaceAll('\\$it', "responseBody.$it.key") + blockBuilder.addLine(value) + } else { + blockBuilder.addLine("responseBody.$it.key == \"$value\"") + } + } else { + blockBuilder.addLine("responseBody.$it.key == $value") } - blockBuilder.addLine('responseBody.' + it.key + ' == ' + value) } } blockBuilder.endBlock() diff --git a/core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy b/core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy index 2315d5bc18..198c5ca99c 100644 --- a/core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy +++ b/core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy @@ -1,5 +1,6 @@ package io.coderate.accurest.util +import groovy.json.JsonException import groovy.json.JsonSlurper import java.util.regex.Pattern @@ -9,28 +10,30 @@ import java.util.regex.Pattern */ class StubMappingConverter { - private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(/^\$\{(.*)\}:\$\{(.*)\}$/) + private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(/^\$\{(.*):(.*)\}$/) public static final int SERVER_SIDE_GROUP = 2 static Map toStubMappingOnServerSide(File stubMapping) { def json = new JsonSlurper().parse(stubMapping) - convertPlaceholders(json as Map, { String value -> + return convertPlaceholders(json as Map, { String value -> getGroupFromMatchingPattern(value) }) - return json } - private static void convertPlaceholders(Map map, Closure closure) { - map.each { - if (it instanceof Map.Entry) { - Map.Entry entry = it as Map.Entry - if (entry.value instanceof String) { - String value = entry.value as String - entry.value = closure(value) - } else if (entry.value instanceof Map) { - convertPlaceholders(entry.value as Map, closure) - } + private static Map convertPlaceholders(Map map, Closure closure) { + return map.collectEntries { key, value -> [ key, transformValue(value, closure) ] } + } + + static def transformValue(def value, Closure closure) { + if (value instanceof String) { + try { + def json = new JsonSlurper().parseText(value as String) as Map + return convertPlaceholders(json, closure) + } catch (JsonException ignore) { + return closure(value) } + } else if (value instanceof Map) { + return convertPlaceholders(value as Map, closure) } } diff --git a/core/src/main/resources/stubs/wiremocks/sample.json b/core/src/main/resources/stubs/wiremocks/sample.json index 7ad5ef1a63..b6d6af2f50 100644 --- a/core/src/main/resources/stubs/wiremocks/sample.json +++ b/core/src/main/resources/stubs/wiremocks/sample.json @@ -5,7 +5,7 @@ }, "response": { "status": 200, - "body": "{\"loanApplicationStatus\":\"LOAN_APPLIED\",\"loanApplicationId\":123123123}", + "body": "{\"loanApplicationStatus\":\"LOAN_APPLIED\",\"loanApplicationId\":\"${123123123:$anyInt($it)}\"}", "headers": { "Content-Type": "text/plain" } From af91a9c452bc9f2a1299d906cba5d5b76c9a0db9 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 14:55:09 +0100 Subject: [PATCH 015/719] All module names now have an accurest prefix --- .../io/coderate/accurest/TestGenerator.groovy | 0 .../accurest/builder/BlockBuilder.groovy | 0 .../accurest/builder/ClassBuilder.groovy | 0 .../builder/JUnitMethodBodyBuilder.groovy | 0 .../accurest/builder/MethodBuilder.groovy | 0 .../builder/SpockMethodBodyBuilder.groovy | 0 .../accurest/config/TestFramework.groovy | 0 .../coderate/accurest/config/TestMode.groovy | 0 .../coderate/accurest/util/NamesUtil.groovy | 0 .../accurest/util/StubMappingConverter.groovy | 0 .../resources/stubs/wiremocks/sample.json | 0 .../plugin/AccurestGradlePlugin.groovy | 0 .../plugin/AccurestPluginExtension.groovy | 0 .../gradle-plugins/accurest.properties | 0 .../plugin/AccurestGradlePluginTest.groovy | 22 +++++++++++++++++++ build.gradle | 6 ++--- settings.gradle | 2 +- 17 files changed, 26 insertions(+), 4 deletions(-) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/TestGenerator.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/config/TestMode.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy (100%) rename {core => accurest-core}/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy (100%) rename {core => accurest-core}/src/main/resources/stubs/wiremocks/sample.json (100%) rename {gradle-plugin => accurest-gradle-plugin}/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy (100%) rename {gradle-plugin => accurest-gradle-plugin}/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy (100%) rename {gradle-plugin => accurest-gradle-plugin}/src/main/resources/META-INF/gradle-plugins/accurest.properties (100%) create mode 100644 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestGradlePluginTest.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/builder/BlockBuilder.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/builder/JUnitMethodBodyBuilder.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/config/TestMode.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/util/NamesUtil.groovy diff --git a/core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy similarity index 100% rename from core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy diff --git a/core/src/main/resources/stubs/wiremocks/sample.json b/accurest-core/src/main/resources/stubs/wiremocks/sample.json similarity index 100% rename from core/src/main/resources/stubs/wiremocks/sample.json rename to accurest-core/src/main/resources/stubs/wiremocks/sample.json diff --git a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy similarity index 100% rename from gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy rename to accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy diff --git a/gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy similarity index 100% rename from gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy rename to accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy diff --git a/gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties b/accurest-gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties similarity index 100% rename from gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties rename to accurest-gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestGradlePluginTest.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestGradlePluginTest.groovy new file mode 100644 index 0000000000..e5ef0640ff --- /dev/null +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestGradlePluginTest.groovy @@ -0,0 +1,22 @@ +package io.codearte.accurest.plugin + +import org.gradle.api.Project +import org.gradle.testfixtures.ProjectBuilder +import spock.lang.Ignore +import spock.lang.Specification + +/** + * @author Jakub Kubrynski + */ +@Ignore +class AccurestGradlePluginTest extends Specification { + + def void greeterPluginAddsGreetingTaskToProject() { + when: + Project project = ProjectBuilder.builder().build() + project.apply plugin: 'accurest' + + then: + project.tasks.generateAccurest + } +} diff --git a/build.gradle b/build.gradle index 3abfb5433a..db0e0309c8 100644 --- a/build.gradle +++ b/build.gradle @@ -36,12 +36,12 @@ subprojects { } } -project(':core') { +project(':accurest-core') { } -project(':gradle-plugin') { +project(':accurest-gradle-plugin') { dependencies { - compile project(':core') + compile project(':accurest-core') compile gradleApi() } } diff --git a/settings.gradle b/settings.gradle index f27693d39b..dff32d91dd 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ -include "core", "gradle-plugin" +include "accurest-core", "accurest-gradle-plugin" rootProject.name = "accurest" \ No newline at end of file From e813b83b98b417411379003543a1c0772458eed8 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 15:40:18 +0100 Subject: [PATCH 016/719] Support for transforming lists as stub elements --- .../io/coderate/accurest/TestGenerator.groovy | 2 +- .../builder/SpockMethodBodyBuilder.groovy | 5 +++-- .../accurest/util/StubMappingConverter.groovy | 15 ++++++++++++--- .../main/resources/stubs/wiremocks/sample.json | 16 +++++++++++++--- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index bca414595f..34847cad64 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -92,6 +92,6 @@ class TestGenerator { } public static void main(String[] args) { - new TestGenerator('/home/devel/projects/codearte/accurest/core/src/main/resources/stubs', 'io.test', '', '', TestFramework.SPOCK, TestMode.MOCKMVC, "").generate() + new TestGenerator('/home/devel/projects/codearte/accurest/accurest-core/src/main/resources/stubs', 'io.test', '', '', TestFramework.SPOCK, TestMode.MOCKMVC, "").generate() } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 85316e747a..23fff1791c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,5 +1,6 @@ package io.coderate.accurest.builder +import groovy.json.JsonOutput import groovy.transform.PackageScope /** @@ -22,7 +23,7 @@ class SpockMethodBodyBuilder { blockBuilder.addLine(".header('$it.key', '$it.value.equalTo')") } if (stubDefinition.request.bodyPatterns) { - blockBuilder.addLine(".body('${stubDefinition.request.bodyPatterns[0].matches}')") + blockBuilder.addLine(".body('${JsonOutput.toJson(stubDefinition.request.bodyPatterns[0].matches)}')") } blockBuilder.unindent().endBlock().addEmptyLine() @@ -51,7 +52,7 @@ class SpockMethodBodyBuilder { blockBuilder.addLine("responseBody.$it.key == \"$value\"") } } else { - blockBuilder.addLine("responseBody.$it.key == $value") + blockBuilder.addLine("responseBody.$it == $value") } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy index 198c5ca99c..ee2528c7c6 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy @@ -21,20 +21,29 @@ class StubMappingConverter { } private static Map convertPlaceholders(Map map, Closure closure) { - return map.collectEntries { key, value -> [ key, transformValue(value, closure) ] } + return map.collectEntries { + key, value -> + [key, transformValue(value, closure)] + } } static def transformValue(def value, Closure closure) { if (value instanceof String) { try { - def json = new JsonSlurper().parseText(value as String) as Map - return convertPlaceholders(json, closure) + def json = new JsonSlurper().parseText(value as String) + if (json instanceof Map) { + return convertPlaceholders(json, closure) + } } catch (JsonException ignore) { return closure(value) } } else if (value instanceof Map) { return convertPlaceholders(value as Map, closure) + } else if (value instanceof List) { + return value.collect({ transformValue(it, closure) }) } + + return value } private static Object getGroupFromMatchingPattern(String value) { diff --git a/accurest-core/src/main/resources/stubs/wiremocks/sample.json b/accurest-core/src/main/resources/stubs/wiremocks/sample.json index b6d6af2f50..f4eca9faad 100644 --- a/accurest-core/src/main/resources/stubs/wiremocks/sample.json +++ b/accurest-core/src/main/resources/stubs/wiremocks/sample.json @@ -1,13 +1,23 @@ { "request": { - "method": "GET", - "url": "/some" + "method": "PUT", + "url": "/loanApplication", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.loanapplicationservice.v1+json" + } + }, + "bodyPatterns": [ + { + "matches": "{\"client\":{\"pesel\":\"1234567890\"},\"loanApplicationId\":123123123,\"amount\":123.123}" + } + ] }, "response": { "status": 200, "body": "{\"loanApplicationStatus\":\"LOAN_APPLIED\",\"loanApplicationId\":\"${123123123:$anyInt($it)}\"}", "headers": { - "Content-Type": "text/plain" + "Content-Type": "application/vnd.loanapplicationservice.v1+json" } } } \ No newline at end of file From 30ba8ce6398b0fe693a5fa2dfbb01ba89c623f56 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 16:19:27 +0100 Subject: [PATCH 017/719] Configuration contains additional imports that should be added to generated classes --- .../io/coderate/accurest/TestGenerator.groovy | 60 ++++++++++--------- .../accurest/builder/ClassBuilder.groovy | 15 +++-- .../config/AccurestConfigProperties.groovy | 11 ++-- .../plugin/AccurestGradlePlugin.groovy | 10 ++-- 4 files changed, 49 insertions(+), 47 deletions(-) rename accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy => accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy (60%) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 34847cad64..e786a9c0a8 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -1,6 +1,7 @@ package io.coderate.accurest 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.coderate.accurest.util.NamesUtil @@ -16,44 +17,31 @@ import static io.coderate.accurest.builder.MethodBuilder.createTestMethod */ class TestGenerator { - private final String stubsBaseDirectory - private final String basePackageForTests - private final String baseClassForTests - private final String ruleClassForTests - private final TestFramework lang private final String targetDirectory - private final TestMode testMode + private final AccurestConfigProperties configProperties + private final String stubsBaseDirectory - TestGenerator(String stubsBaseDirectory, String basePackageForTests, String baseClassForTests, - String ruleClassForTests, TestFramework testFramework, TestMode testMode, String targetDirectory) { - this.testMode = testMode - this.targetDirectory = targetDirectory - File stubsResource = new File(stubsBaseDirectory) + TestGenerator(AccurestConfigProperties accurestConfigProperties) { + this.configProperties = accurestConfigProperties + this.targetDirectory = accurestConfigProperties.generatedTestSourcesDir + File stubsResource = new File(accurestConfigProperties.stubsBaseDirectory) if (stubsResource == null) { - throw new IllegalStateException("Stubs directory not found under " + stubsBaseDirectory) + throw new IllegalStateException("Stubs directory not found under " + accurestConfigProperties.stubsBaseDirectory) } this.stubsBaseDirectory = stubsResource.path - this.basePackageForTests = basePackageForTests - if (testFramework == 'Spock' && !baseClassForTests) { - this.baseClassForTests = 'spock.lang.Specification' - } else { - this.baseClassForTests = baseClassForTests - } - this.ruleClassForTests = ruleClassForTests - this.lang = testFramework } public void generate() { List files = new File(stubsBaseDirectory).listFiles() files.grep({ File file -> file.isDirectory() && containsStubs(file) }).each { - def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(basePackageForTests)) + def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(configProperties.basePackageForTests)) Files.createDirectories(testBaseDir) Files.write(Paths.get(testBaseDir.toString(), NamesUtil.capitalize(it.name) + getTestClassExtension()), addClass(it).bytes) } } private String getTestClassExtension() { - return lang == TestFramework.SPOCK ? '.groovy' : '.java' + return configProperties.targetFramework == TestFramework.SPOCK ? '.groovy' : '.java' } boolean containsStubs(File file) { @@ -66,32 +54,46 @@ class TestGenerator { } private String addClass(File directory) { - ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), basePackageForTests, baseClassForTests, lang) + ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), configProperties) - if (testMode == TestMode.MOCKMVC) { + if (configProperties.imports) { + configProperties.imports.each { + clazz.addImport(it) + } + } + + if (configProperties.staticImports) { + configProperties.staticImports.each { + clazz.addStaticImport(it) + } + } + + if (configProperties.testMode == TestMode.MOCKMVC) { clazz.addStaticImport('com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*') } else { clazz.addStaticImport('com.jayway.restassured.RestAssured.*') } - if (lang == TestFramework.JUNIT) { + if (configProperties.targetFramework == TestFramework.JUNIT) { clazz.addImport('org.junit.Test') } else { clazz.addImport('groovy.json.JsonSlurper') } - if (ruleClassForTests) { + if (configProperties.ruleClassForTests) { clazz.addImport('org.junit.Rule') - .addRule(ruleClassForTests) + .addRule(configProperties.ruleClassForTests) } directory.listFiles().each { - clazz.addMethod(createTestMethod(it, lang)) + clazz.addMethod(createTestMethod(it, configProperties.targetFramework)) } return clazz.build() } public static void main(String[] args) { - new TestGenerator('/home/devel/projects/codearte/accurest/accurest-core/src/main/resources/stubs', 'io.test', '', '', TestFramework.SPOCK, TestMode.MOCKMVC, "").generate() + AccurestConfigProperties properties = new AccurestConfigProperties(stubsBaseDirectory: '/home/devel/projects/codearte/accurest/accurest-core/src/main/resources/stubs', + targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test']) + new TestGenerator(properties).generate() } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy index 7e368f8490..7abb630741 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy @@ -1,5 +1,6 @@ package io.coderate.accurest.builder +import io.coderate.accurest.config.AccurestConfigProperties import io.coderate.accurest.config.TestFramework import io.coderate.accurest.util.NamesUtil @@ -36,12 +37,14 @@ class ClassBuilder { } } - static ClassBuilder createClass(String className, String packageName, TestFramework lang) { - return createClass(className, packageName, null, lang) - } - - static ClassBuilder createClass(String className, String packageName, String baseClass, TestFramework lang) { - return new ClassBuilder(className, packageName, baseClass, lang) + static ClassBuilder createClass(String className, AccurestConfigProperties properties) { + String baseClassForTests + if (properties.targetFramework == TestFramework.SPOCK && !properties.baseClassForTests) { + baseClassForTests = 'spock.lang.Specification' + } else { + baseClassForTests = properties.baseClassForTests + } + return new ClassBuilder(className, properties.basePackageForTests, baseClassForTests, properties.targetFramework) } ClassBuilder addImport(String importToAdd) { diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy similarity index 60% rename from accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy index 970834d9cb..eb677b16b5 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestPluginExtension.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy @@ -1,17 +1,16 @@ -package io.codearte.accurest.plugin - -import io.coderate.accurest.config.TestFramework -import io.coderate.accurest.config.TestMode +package io.coderate.accurest.config /** * @author Jakub Kubrynski */ -class AccurestPluginExtension { +class AccurestConfigProperties { TestFramework targetFramework = TestFramework.SPOCK - TestMode testMode = TestMode.EXPLICIT + TestMode testMode = TestMode.MOCKMVC String stubsBaseDirectory = 'mappings' String basePackageForTests = 'io.codearte.accurest.tests' String baseClassForTests String ruleClassForTests String generatedTestSourcesDir = 'build/generated-sources/accurest' + String[] imports = [] + String[] staticImports = [] } 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 38f5567c29..c27b13870d 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,7 @@ package io.codearte.accurest.plugin import io.coderate.accurest.TestGenerator +import io.coderate.accurest.config.AccurestConfigProperties import org.gradle.api.Plugin import org.gradle.api.Project @@ -15,7 +16,7 @@ class AccurestGradlePlugin implements Plugin { @Override void apply(Project project) { - AccurestPluginExtension extension = project.extensions.create('accurest', AccurestPluginExtension) + AccurestConfigProperties extension = project.extensions.create('accurest', AccurestConfigProperties) project.compileTestGroovy.dependsOn(TASK_NAME) @@ -27,11 +28,8 @@ class AccurestGradlePlugin implements Plugin { } try { - String resourceDirectory = project.projectDir.path + '/src/test/resources/' + extension.stubsBaseDirectory - TestGenerator generator = new TestGenerator(resourceDirectory, - extension.basePackageForTests, extension.baseClassForTests, extension.ruleClassForTests, - extension.targetFramework, extension.testMode, - extension.generatedTestSourcesDir) + extension.stubsBaseDirectory = project.projectDir.path + '/src/test/resources/' + extension.stubsBaseDirectory + TestGenerator generator = new TestGenerator(extension) generator.generate() } catch (IllegalStateException e) { project.logger.error("Accurest Plugin: {}", e.getMessage()) From eaa531ef10b090d66baf7d8983d54d422cb9bc4d Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 16:52:06 +0100 Subject: [PATCH 018/719] Release version 0.2.0 --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index db0e0309c8..ade824b5fd 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.2.0-SNAPSHOT' + projectVersion = '0.2.0' projectGroup = 'io.codearte.accurest' } @@ -20,7 +20,7 @@ subprojects { } dependencies { - compile 'org.codehaus.groovy:groovy-all:2.3.6' + compile localGroovy() testCompile 'org.spockframework:spock-core:0.7-groovy-2.0' } From bb8217e435cf12eda7692890ea87ae2511b23bb3 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 27 Jan 2015 16:53:05 +0100 Subject: [PATCH 019/719] Next development version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index ade824b5fd..a96b809018 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.2.0' + projectVersion = '0.3.0-SNAPSHOT' projectGroup = 'io.codearte.accurest' } From cde720a613913ba2dfd63a6a7660f463b6b4a3be Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 27 Jan 2015 23:56:16 +0100 Subject: [PATCH 020/719] Readme with definition of our approach --- README.md | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6937ee468a..34cef3cd65 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,128 @@ Accurate REST ============= -Consumer Driven Contracts verifier for Java \ No newline at end of file +Consumer Driven Contracts verifier for Java + +# Introduction + +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. + +# 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\"}:$isCurrentDate($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: + +``` +${123456789:$isPersonalIdValid($it)} +``` + +#### Example of generated specification + +``` +class AcceptanceSpec extends AssurestSpec { + + // TODO: Define how it's going to look like + +} + +``` From 89ed2dcefc847712dffad0397acd501c1a8d494c Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 20:01:49 +0100 Subject: [PATCH 021/719] Fixed running on multi-module projects --- .../accurest/config/AccurestConfigProperties.groovy | 2 +- .../accurest/plugin/AccurestGradlePlugin.groovy | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy index eb677b16b5..24a69b1e09 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy @@ -6,7 +6,7 @@ package io.coderate.accurest.config class AccurestConfigProperties { TestFramework targetFramework = TestFramework.SPOCK TestMode testMode = TestMode.MOCKMVC - String stubsBaseDirectory = 'mappings' + String stubsBaseDirectory = 'stubs' String basePackageForTests = 'io.codearte.accurest.tests' String baseClassForTests String ruleClassForTests 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 c27b13870d..d086084931 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 @@ -17,6 +17,8 @@ class AccurestGradlePlugin implements Plugin { @Override void apply(Project project) { AccurestConfigProperties extension = project.extensions.create('accurest', AccurestConfigProperties) + extension.stubsBaseDirectory = project.projectDir.path + '/src/test/resources/' + extension.stubsBaseDirectory + extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) project.compileTestGroovy.dependsOn(TASK_NAME) @@ -28,7 +30,6 @@ class AccurestGradlePlugin implements Plugin { } try { - extension.stubsBaseDirectory = project.projectDir.path + '/src/test/resources/' + extension.stubsBaseDirectory TestGenerator generator = new TestGenerator(extension) generator.generate() } catch (IllegalStateException e) { @@ -49,4 +50,14 @@ class AccurestGradlePlugin implements Plugin { } + private String buildGeneratedSourcesDir(Project project, def extension) { + String moduleDir + if (project.getParent()) { + moduleDir = project.name + File.separator + extension.generatedTestSourcesDir + } else { + moduleDir = extension.generatedTestSourcesDir + } + moduleDir + } + } From 8836ee3444816155562499dfe10908013423036e Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 20:32:31 +0100 Subject: [PATCH 022/719] Support for nested directories with stubs --- .../io/coderate/accurest/TestGenerator.groovy | 31 +++++++++++++------ .../accurest/builder/ClassBuilder.groovy | 4 +-- .../config/AccurestConfigProperties.groovy | 2 +- .../stubs/wiremocks/other/sample.json | 23 ++++++++++++++ .../plugin/AccurestGradlePlugin.groovy | 2 +- 5 files changed, 49 insertions(+), 13 deletions(-) create mode 100644 accurest-core/src/main/resources/stubs/wiremocks/other/sample.json diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index e786a9c0a8..cf1ec48ab9 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -11,6 +11,8 @@ import java.nio.file.Paths import static ClassBuilder.createClass import static io.coderate.accurest.builder.MethodBuilder.createTestMethod +import static io.coderate.accurest.util.NamesUtil.afterLast +import static io.coderate.accurest.util.NamesUtil.capitalize /** * @author Jakub Kubrynski @@ -32,11 +34,22 @@ class TestGenerator { } public void generate() { - List files = new File(stubsBaseDirectory).listFiles() - files.grep({ File file -> file.isDirectory() && containsStubs(file) }).each { - def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(configProperties.basePackageForTests)) - Files.createDirectories(testBaseDir) - Files.write(Paths.get(testBaseDir.toString(), NamesUtil.capitalize(it.name) + getTestClassExtension()), addClass(it).bytes) + generateTestClasses(new File(stubsBaseDirectory), configProperties.basePackageForTests) + } + + protected void generateTestClasses(File baseFile, String packageName) { + List files = baseFile.listFiles() + + files.each { + if (it.isDirectory()) { + generateTestClasses(it, "$packageName.$it.name") + if (containsStubs(it)) { + def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(packageName)) + Files.createDirectories(testBaseDir) + Files.write(Paths.get(testBaseDir.toString(), capitalize(it.name) + getTestClassExtension()), + buildClass(it, packageName).bytes) + } + } } } @@ -53,8 +66,8 @@ class TestGenerator { }).size() > 0 } - private String addClass(File directory) { - ClassBuilder clazz = createClass(NamesUtil.capitalize(NamesUtil.afterLast(directory.path, '/')), configProperties) + private String buildClass(File directory, String classPackage) { + ClassBuilder clazz = createClass(capitalize(afterLast(directory.path, '/')), classPackage, configProperties) if (configProperties.imports) { configProperties.imports.each { @@ -85,7 +98,7 @@ class TestGenerator { .addRule(configProperties.ruleClassForTests) } - directory.listFiles().each { + directory.listFiles().grep({ File file -> !file.isDirectory()}).each { clazz.addMethod(createTestMethod(it, configProperties.targetFramework)) } return clazz.build() @@ -93,7 +106,7 @@ class TestGenerator { public static void main(String[] args) { AccurestConfigProperties properties = new AccurestConfigProperties(stubsBaseDirectory: '/home/devel/projects/codearte/accurest/accurest-core/src/main/resources/stubs', - targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test']) + targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test']) new TestGenerator(properties).generate() } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy index 7abb630741..7bf11cc9ee 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy @@ -37,14 +37,14 @@ class ClassBuilder { } } - static ClassBuilder createClass(String className, AccurestConfigProperties properties) { + static ClassBuilder createClass(String className, String classPackage, AccurestConfigProperties properties) { String baseClassForTests if (properties.targetFramework == TestFramework.SPOCK && !properties.baseClassForTests) { baseClassForTests = 'spock.lang.Specification' } else { baseClassForTests = properties.baseClassForTests } - return new ClassBuilder(className, properties.basePackageForTests, baseClassForTests, properties.targetFramework) + return new ClassBuilder(className, classPackage, baseClassForTests, properties.targetFramework) } ClassBuilder addImport(String importToAdd) { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy index 24a69b1e09..e77d4bb9a0 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy @@ -6,7 +6,7 @@ package io.coderate.accurest.config class AccurestConfigProperties { TestFramework targetFramework = TestFramework.SPOCK TestMode testMode = TestMode.MOCKMVC - String stubsBaseDirectory = 'stubs' + String stubsBaseDirectory = 'src/test/resources/stubs' String basePackageForTests = 'io.codearte.accurest.tests' String baseClassForTests String ruleClassForTests diff --git a/accurest-core/src/main/resources/stubs/wiremocks/other/sample.json b/accurest-core/src/main/resources/stubs/wiremocks/other/sample.json new file mode 100644 index 0000000000..f4eca9faad --- /dev/null +++ b/accurest-core/src/main/resources/stubs/wiremocks/other/sample.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "PUT", + "url": "/loanApplication", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.loanapplicationservice.v1+json" + } + }, + "bodyPatterns": [ + { + "matches": "{\"client\":{\"pesel\":\"1234567890\"},\"loanApplicationId\":123123123,\"amount\":123.123}" + } + ] + }, + "response": { + "status": 200, + "body": "{\"loanApplicationStatus\":\"LOAN_APPLIED\",\"loanApplicationId\":\"${123123123:$anyInt($it)}\"}", + "headers": { + "Content-Type": "application/vnd.loanapplicationservice.v1+json" + } + } +} \ No newline at end of file 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 d086084931..7c610e441a 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 @@ -17,7 +17,7 @@ class AccurestGradlePlugin implements Plugin { @Override void apply(Project project) { AccurestConfigProperties extension = project.extensions.create('accurest', AccurestConfigProperties) - extension.stubsBaseDirectory = project.projectDir.path + '/src/test/resources/' + extension.stubsBaseDirectory + extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) project.compileTestGroovy.dependsOn(TASK_NAME) From 7f02a5aa7871a92139a77649754e73bd7f53bd7f Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 20:36:24 +0100 Subject: [PATCH 023/719] Added empty sonatype settings --- gradle.properties | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 gradle.properties diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000000..87021638cf --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +sonatypeUsername = +sonatypePassword = \ No newline at end of file From 7386fbc519f7340847193daaa7a4fa80b0a974d2 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 20:45:49 +0100 Subject: [PATCH 024/719] Release plugins are applied only for non-snapshot versions --- build.gradle | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a96b809018..701ea81137 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,10 @@ ext { subprojects { apply plugin: 'groovy' apply plugin: 'maven-publish' - apply from: "$rootDir/release.gradle" + + if (!projectVersion.contains('SNAPSHOT')) { + apply from: "$rootDir/release.gradle" + } group = projectGroup version = projectVersion From 0ea55320cee10673660e7a4a328c4e0124429a4e Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 21:48:09 +0100 Subject: [PATCH 025/719] Fixed #3 Having empty String breaks JSON parsing --- .../io/coderate/accurest/util/StubMappingConverter.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy index ee2528c7c6..439224eccd 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/util/StubMappingConverter.groovy @@ -28,9 +28,9 @@ class StubMappingConverter { } static def transformValue(def value, Closure closure) { - if (value instanceof String) { + if (value instanceof String && value) { try { - def json = new JsonSlurper().parseText(value as String) + def json = new JsonSlurper().parseText(value) if (json instanceof Map) { return convertPlaceholders(json, closure) } From 09f778c7e1bdc5cf3002deb5c0103971ece7df26 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 21:48:46 +0100 Subject: [PATCH 026/719] Cleared source directory resolving --- .../codearte/accurest/plugin/AccurestGradlePlugin.groovy | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 7c610e441a..63a5983e3a 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 @@ -17,14 +17,15 @@ class AccurestGradlePlugin implements Plugin { @Override void apply(Project project) { AccurestConfigProperties extension = project.extensions.create('accurest', AccurestConfigProperties) - extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory - extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) project.compileTestGroovy.dependsOn(TASK_NAME) project.task(TASK_NAME) << { project.logger.info("Accurest Plugin: Invoking test sources generation") + extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory + extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) + project.sourceSets.test.groovy { srcDir extension.generatedTestSourcesDir } @@ -42,7 +43,7 @@ class AccurestGradlePlugin implements Plugin { if (hasIdea) { project.idea { module { - testSourceDirs += new File(extension.generatedTestSourcesDir) + testSourceDirs += new File(buildGeneratedSourcesDir(project, extension)) } } } From c0cdbdec27871e523f7904c7534f54d931efc799 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 23:20:51 +0100 Subject: [PATCH 027/719] Fixed directory walking --- .../groovy/io/coderate/accurest/TestGenerator.groovy | 7 +++++-- accurest-core/src/main/resources/stubs/some.json | 0 .../accurest/plugin/AccurestGradlePlugin.groovy | 12 +----------- 3 files changed, 6 insertions(+), 13 deletions(-) create mode 100644 accurest-core/src/main/resources/stubs/some.json diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index cf1ec48ab9..7dabd60b18 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -7,7 +7,9 @@ import io.coderate.accurest.config.TestMode import io.coderate.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 ClassBuilder.createClass import static io.coderate.accurest.builder.MethodBuilder.createTestMethod @@ -46,8 +48,9 @@ class TestGenerator { if (containsStubs(it)) { def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(packageName)) Files.createDirectories(testBaseDir) - Files.write(Paths.get(testBaseDir.toString(), capitalize(it.name) + getTestClassExtension()), - buildClass(it, packageName).bytes) + def classPath = Paths.get(testBaseDir.toString(), capitalize(it.name) + getTestClassExtension()).toAbsolutePath() + def classBytes = buildClass(it, packageName).bytes + Files.write(classPath, classBytes, StandardOpenOption.CREATE) } } } diff --git a/accurest-core/src/main/resources/stubs/some.json b/accurest-core/src/main/resources/stubs/some.json new file mode 100644 index 0000000000..e69de29bb2 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 63a5983e3a..0c198de1a5 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 @@ -24,7 +24,6 @@ class AccurestGradlePlugin implements Plugin { project.logger.info("Accurest Plugin: Invoking test sources generation") extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory - extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) project.sourceSets.test.groovy { srcDir extension.generatedTestSourcesDir @@ -43,7 +42,7 @@ class AccurestGradlePlugin implements Plugin { if (hasIdea) { project.idea { module { - testSourceDirs += new File(buildGeneratedSourcesDir(project, extension)) + testSourceDirs += new File(extension.generatedTestSourcesDir) } } } @@ -51,14 +50,5 @@ class AccurestGradlePlugin implements Plugin { } - private String buildGeneratedSourcesDir(Project project, def extension) { - String moduleDir - if (project.getParent()) { - moduleDir = project.name + File.separator + extension.generatedTestSourcesDir - } else { - moduleDir = extension.generatedTestSourcesDir - } - moduleDir - } } From 0fc5ae2253e568788ed62eb11189d77ce64c1a02 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 23:23:14 +0100 Subject: [PATCH 028/719] Restored multi-module --- .../accurest/plugin/AccurestGradlePlugin.groovy | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) 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 0c198de1a5..63a5983e3a 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 @@ -24,6 +24,7 @@ class AccurestGradlePlugin implements Plugin { project.logger.info("Accurest Plugin: Invoking test sources generation") extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory + extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) project.sourceSets.test.groovy { srcDir extension.generatedTestSourcesDir @@ -42,7 +43,7 @@ class AccurestGradlePlugin implements Plugin { if (hasIdea) { project.idea { module { - testSourceDirs += new File(extension.generatedTestSourcesDir) + testSourceDirs += new File(buildGeneratedSourcesDir(project, extension)) } } } @@ -50,5 +51,14 @@ class AccurestGradlePlugin implements Plugin { } + private String buildGeneratedSourcesDir(Project project, def extension) { + String moduleDir + if (project.getParent()) { + moduleDir = project.name + File.separator + extension.generatedTestSourcesDir + } else { + moduleDir = extension.generatedTestSourcesDir + } + moduleDir + } } From d50d56dff229bd7796af5c2b146d917711fdf7f7 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 28 Jan 2015 23:38:07 +0100 Subject: [PATCH 029/719] Fixed Invalid null JSON parts processing #4 --- .../io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy | 2 +- accurest-core/src/main/resources/stubs/wiremocks/sample.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 23fff1791c..75033ba3ff 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -52,7 +52,7 @@ class SpockMethodBodyBuilder { blockBuilder.addLine("responseBody.$it.key == \"$value\"") } } else { - blockBuilder.addLine("responseBody.$it == $value") + blockBuilder.addLine("responseBody.$it.key == $value") } } } diff --git a/accurest-core/src/main/resources/stubs/wiremocks/sample.json b/accurest-core/src/main/resources/stubs/wiremocks/sample.json index f4eca9faad..250e54b85a 100644 --- a/accurest-core/src/main/resources/stubs/wiremocks/sample.json +++ b/accurest-core/src/main/resources/stubs/wiremocks/sample.json @@ -15,7 +15,7 @@ }, "response": { "status": 200, - "body": "{\"loanApplicationStatus\":\"LOAN_APPLIED\",\"loanApplicationId\":\"${123123123:$anyInt($it)}\"}", + "body": "{\"loanApplicationStatus\":\"LOAN_APPLIED\",\"loanApplicationId\":\"${123123123:$anyInt($it)}\",\"rejectionReason\":null}", "headers": { "Content-Type": "application/vnd.loanapplicationservice.v1+json" } From 76ffce6fc4627e67b59b4f5389629e5df354faa5 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 29 Jan 2015 00:20:19 +0100 Subject: [PATCH 030/719] Added regex escaping for request body matching --- .../coderate/accurest/builder/SpockMethodBodyBuilder.groovy | 4 +++- accurest-core/src/main/resources/stubs/wiremocks/sample.json | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 75033ba3ff..80c38ffd36 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -23,7 +23,9 @@ class SpockMethodBodyBuilder { blockBuilder.addLine(".header('$it.key', '$it.value.equalTo')") } if (stubDefinition.request.bodyPatterns) { - blockBuilder.addLine(".body('${JsonOutput.toJson(stubDefinition.request.bodyPatterns[0].matches)}')") + String matches = stubDefinition.request.bodyPatterns[0].matches + matches = matches.replaceAll('\\\\', ''); + blockBuilder.addLine(".body('${JsonOutput.toJson(matches)}')") } blockBuilder.unindent().endBlock().addEmptyLine() diff --git a/accurest-core/src/main/resources/stubs/wiremocks/sample.json b/accurest-core/src/main/resources/stubs/wiremocks/sample.json index 250e54b85a..97eaaa3cdb 100644 --- a/accurest-core/src/main/resources/stubs/wiremocks/sample.json +++ b/accurest-core/src/main/resources/stubs/wiremocks/sample.json @@ -9,7 +9,7 @@ }, "bodyPatterns": [ { - "matches": "{\"client\":{\"pesel\":\"1234567890\"},\"loanApplicationId\":123123123,\"amount\":123.123}" + "matches": "\\{\"clientPesel\":\"1234567890\",\"loanAmount\":123.123\\}" } ] }, From 60ad4d2c1153682b6f69f7bd7464fd9691bdafe9 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 29 Jan 2015 00:36:06 +0100 Subject: [PATCH 031/719] Accurest is now able to override existing file --- .../src/main/groovy/io/coderate/accurest/TestGenerator.groovy | 2 +- .../io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 7dabd60b18..a1a62d27d6 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -50,7 +50,7 @@ class TestGenerator { Files.createDirectories(testBaseDir) def classPath = Paths.get(testBaseDir.toString(), capitalize(it.name) + getTestClassExtension()).toAbsolutePath() def classBytes = buildClass(it, packageName).bytes - Files.write(classPath, classBytes, StandardOpenOption.CREATE) + Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 80c38ffd36..bac810fce6 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -25,7 +25,7 @@ class SpockMethodBodyBuilder { if (stubDefinition.request.bodyPatterns) { String matches = stubDefinition.request.bodyPatterns[0].matches matches = matches.replaceAll('\\\\', ''); - blockBuilder.addLine(".body('${JsonOutput.toJson(matches)}')") + blockBuilder.addLine(".body('$matches')") } blockBuilder.unindent().endBlock().addEmptyLine() From c3a49199877c8b348a2ab42dfbea57c22888ff4d Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 29 Jan 2015 01:01:21 +0100 Subject: [PATCH 032/719] Extended info level logging --- .../main/groovy/io/coderate/accurest/TestGenerator.groovy | 6 +++++- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index a1a62d27d6..7257913ec0 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -10,6 +10,7 @@ import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.nio.file.StandardOpenOption +import java.util.concurrent.atomic.AtomicInteger import static ClassBuilder.createClass import static io.coderate.accurest.builder.MethodBuilder.createTestMethod @@ -24,6 +25,7 @@ class TestGenerator { private final String targetDirectory private final AccurestConfigProperties configProperties private final String stubsBaseDirectory + private AtomicInteger counter = new AtomicInteger() TestGenerator(AccurestConfigProperties accurestConfigProperties) { this.configProperties = accurestConfigProperties @@ -35,8 +37,9 @@ class TestGenerator { this.stubsBaseDirectory = stubsResource.path } - public void generate() { + public int generate() { generateTestClasses(new File(stubsBaseDirectory), configProperties.basePackageForTests) + return counter.get() } protected void generateTestClasses(File baseFile, String packageName) { @@ -51,6 +54,7 @@ class TestGenerator { def classPath = Paths.get(testBaseDir.toString(), capitalize(it.name) + getTestClassExtension()).toAbsolutePath() def classBytes = buildClass(it, packageName).bytes Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) + counter.incrementAndGet() } } } 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 63a5983e3a..c86884d0b8 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 @@ -27,12 +27,14 @@ class AccurestGradlePlugin implements Plugin { extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) project.sourceSets.test.groovy { + project.logger.info("Registering $extension.generatedTestSourcesDir as test source directory") srcDir extension.generatedTestSourcesDir } try { TestGenerator generator = new TestGenerator(extension) - generator.generate() + int generatedClasses = generator.generate() + project.logger.info("Generated {} test classes", generatedClasses) } catch (IllegalStateException e) { project.logger.error("Accurest Plugin: {}", e.getMessage()) } From c314286911cd89c160f8392a578737006ba8ad51 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 29 Jan 2015 01:34:11 +0100 Subject: [PATCH 033/719] Updated documentation --- README.md | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 117 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 34cef3cd65..98d84e56c0 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,7 @@ We would like to use the Wiremock's JSON stub definitions as a point of entry to * __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__ + * __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? @@ -64,11 +63,11 @@ Let's take a look at the following example { "request": { "method": "GET", - "urlPattern": "${/[0-9]{2}}:${/12}" + "urlPattern": "${/[0-9]{2}:/12}" }, "response": { "status": 200, - "body": "${{\"date\":\"2015-01-14\"}:$isCurrentDate($it)}", + "body": "{\"date\":\"${\"2015-01-14\":$anyInt($it)}\"}}", "headers": { "Content-Type": "text/plain" } @@ -113,16 +112,128 @@ called with the corresponding field's (status, body, headers etc.) value as inpu `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: ``` -${123456789:$isPersonalIdValid($it)} +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 { - // TODO: Define how it's going to look like + 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.3.0' + } +} + +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 [] From 9bda30e107be5d9156d3092095eeb3cb7d36a0e3 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 29 Jan 2015 14:14:16 +0100 Subject: [PATCH 034/719] Fixed registering source sets --- .../io/coderate/accurest/AccurestException.groovy | 12 ++++++++++++ .../groovy/io/coderate/accurest/TestGenerator.groovy | 2 +- .../accurest/plugin/AccurestGradlePlugin.groovy | 8 +++++--- 3 files changed, 18 insertions(+), 4 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy new file mode 100644 index 0000000000..d564661933 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy @@ -0,0 +1,12 @@ +package io.coderate.accurest + +/** + * @author Jakub Kubrynski + */ +class AccurestException extends RuntimeException { + + def AccurestException(String message) { + super(message) + } + +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 7257913ec0..2042f25461 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -32,7 +32,7 @@ class TestGenerator { this.targetDirectory = accurestConfigProperties.generatedTestSourcesDir File stubsResource = new File(accurestConfigProperties.stubsBaseDirectory) if (stubsResource == null) { - throw new IllegalStateException("Stubs directory not found under " + accurestConfigProperties.stubsBaseDirectory) + throw new AccurestException("Stubs directory not found under " + accurestConfigProperties.stubsBaseDirectory) } this.stubsBaseDirectory = stubsResource.path } 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 c86884d0b8..b3bd8d6509 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,5 +1,6 @@ package io.codearte.accurest.plugin +import io.coderate.accurest.AccurestException import io.coderate.accurest.TestGenerator import io.coderate.accurest.config.AccurestConfigProperties import org.gradle.api.Plugin @@ -24,19 +25,20 @@ class AccurestGradlePlugin implements Plugin { project.logger.info("Accurest Plugin: Invoking test sources generation") extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory - extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) project.sourceSets.test.groovy { project.logger.info("Registering $extension.generatedTestSourcesDir as test source directory") srcDir extension.generatedTestSourcesDir } + extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) + try { TestGenerator generator = new TestGenerator(extension) int generatedClasses = generator.generate() project.logger.info("Generated {} test classes", generatedClasses) - } catch (IllegalStateException e) { - project.logger.error("Accurest Plugin: {}", e.getMessage()) + } catch (AccurestException e) { + project.logger.error("Accurest Plugin exception: {}", e.getMessage()) } } From f03ef21f66f7cd72aabc3f6301967a4877e614d9 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 29 Jan 2015 14:14:16 +0100 Subject: [PATCH 035/719] [#5] WIP on GroovyDSL to Wiremock conversion --- .../accurest/AccurestException.groovy | 12 + .../io/coderate/accurest/TestGenerator.groovy | 2 +- .../io/coderate/accurest/dsl/GroovyDsl.groovy | 23 ++ .../io/coderate/accurest/dsl/Request.groovy | 172 +++++++++++ .../accurest/dsl/WiremockStubStrategy.groovy | 86 ++++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 270 ++++++++++++++++++ .../plugin/AccurestGradlePlugin.groovy | 8 +- build.gradle | 4 +- 8 files changed, 572 insertions(+), 5 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy new file mode 100644 index 0000000000..d564661933 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy @@ -0,0 +1,12 @@ +package io.coderate.accurest + +/** + * @author Jakub Kubrynski + */ +class AccurestException extends RuntimeException { + + def AccurestException(String message) { + super(message) + } + +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 7257913ec0..2042f25461 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -32,7 +32,7 @@ class TestGenerator { this.targetDirectory = accurestConfigProperties.generatedTestSourcesDir File stubsResource = new File(accurestConfigProperties.stubsBaseDirectory) if (stubsResource == null) { - throw new IllegalStateException("Stubs directory not found under " + accurestConfigProperties.stubsBaseDirectory) + throw new AccurestException("Stubs directory not found under " + accurestConfigProperties.stubsBaseDirectory) } this.stubsBaseDirectory = stubsResource.path } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy new file mode 100644 index 0000000000..35a2acbc7d --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -0,0 +1,23 @@ +package io.coderate.accurest.dsl + +import groovy.transform.TypeChecked + +@TypeChecked +class GroovyDsl { + + Request request + + static GroovyDsl make(Closure closure) { + GroovyDsl dsl = new GroovyDsl() + closure.delegate = dsl + closure() + return dsl + } + + void request(@DelegatesTo(Request) Closure closure) { + Request request = new Request() + this.request = request + closure.delegate = request + closure() + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy new file mode 100644 index 0000000000..d4f40ef6ba --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy @@ -0,0 +1,172 @@ +package io.coderate.accurest.dsl + +import groovy.transform.TypeChecked + +@TypeChecked +class Request { + String method + String url + StringCustomizableProperty urlPattern + String urlPath + Headers headers + + void method(String method) { + this.method = method + } + + void url(String url) { + this.url = url + } + + void urlPattern(@DelegatesTo(StringCustomizableProperty) Closure closure) { + StringCustomizableProperty urlPattern = new StringCustomizableProperty() + this.urlPattern = urlPattern + delegateToClosure(closure, urlPattern) + } + + void headers(@DelegatesTo(Headers) Closure closure) { + Headers headers = new Headers() + this.headers = headers + delegateToClosure(closure, headers) + } + + void urlPath(String urlPath) { + this.urlPath = urlPath + } + + //TODO: Can we have different types for Client/Server (client: pattern(String), server: value(Boolean/Int)) ? + class CustomizableProperty { + private T client + private V server + + void client(T client) { + this.client = client + } + + void server(V server) { + this.server = server + } + + T toClientSide() { + return client + } + + V toServerSide() { + return server + } + } + + private class StringCustomizableProperty extends CustomizableProperty { + @Override + String toClientSide() { + return super.toClientSide() as String + } + + @Override + String toServerSide() { + return super.toServerSide() as String + } + } + + private class NoOpCustomizableProperty extends CustomizableProperty { + NoOpCustomizableProperty(T value) { + client(value) + server(value) + } + + @Override + public String toString() { + return toClientSide() + } + } + + class Headers { + private Map headers = [:] + + WithValuePattern header(String headerName) { + WithValuePattern withValuePattern = new WithValuePattern() + headers[headerName] = withValuePattern + return withValuePattern + } + + Set> entries() { + return headers.entrySet() + } + } + +/** + * + * From Wiremock + private Map queryParamPatterns; + private List bodyPatterns; + + private String equalToJson; + private String equalToXml; + private String matchesXPath; + private JSONCompareMode jsonCompareMode; + private String equalTo; + private String contains; + private String matches; + private String doesNotMatch; + private Boolean absent; + private String matchesJsonPath; + + */ + class WithValuePattern { + NoOpCustomizableProperty equalToJson + NoOpCustomizableProperty equalToXml + StringCustomizableProperty matchesXPath + NoOpCustomizableProperty jsonCompareMode + NoOpCustomizableProperty equalTo + StringCustomizableProperty contains + StringCustomizableProperty matches + StringCustomizableProperty doesNotMatch + CustomizableProperty absent + StringCustomizableProperty matchesJsonPath + +// void equalToJson(String equalToJson) { +// this.equalToJson = equalToJson +// } +// + void equalTo(String equalTo) { + this.equalTo = new NoOpCustomizableProperty(equalTo) + } + +// void equalToXml(String equalToXml) { +// this.equalToXml = equalToXml +// } + + void matches(@DelegatesTo(StringCustomizableProperty) Closure closure) { + StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() + this.matches = placeholderHaving + delegateToClosure(closure, placeholderHaving) + } + + void doesNotMatch(@DelegatesTo(StringCustomizableProperty) Closure closure) { + StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() + this.doesNotMatch = placeholderHaving + delegateToClosure(closure, placeholderHaving) + } + + void contains(@DelegatesTo(StringCustomizableProperty) Closure closure) { + StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() + this.contains = placeholderHaving + delegateToClosure(closure, placeholderHaving) + } + +// void jsonCompareMode(JSONCompareMode jsonCompareMode) { +// this.jsonCompareMode = jsonCompareMode +// } + + } + + enum JSONCompareMode { + STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER; + } + + private static void delegateToClosure(@DelegatesTo(T) Closure closure, T delegate) { + closure.delegate = delegate + closure() + } + +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy new file mode 100644 index 0000000000..ea975a0ca8 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy @@ -0,0 +1,86 @@ +package io.coderate.accurest.dsl + +import groovy.json.JsonOutput +import groovy.transform.CompileStatic + +@CompileStatic +class WiremockStubStrategy { + + private final Request request + + WiremockStubStrategy(GroovyDsl groovyDsl) { + this.request = groovyDsl.request + } + + String toWiremockClientStub() { + return JsonOutput.toJson(buildClientRequest(request)) + + } + + String toWiremockServerStub() { + return JsonOutput.toJson(buildServerRequest(request)) + } + + private Map buildClientRequest(Request request) { + return getRequestSection(request, + { request.urlPattern?.toClientSide() }, + { buildClientHeadersSection(request.headers) }) + } + + private Map buildServerRequest(Request request) { + return getRequestSection(request, + { request.urlPattern?.toServerSide() }, + { buildServerHeadersSection(request.headers) }) + } + + private Map> getRequestSection(Request request, Closure buildUrlPattern, Closure buildHeaders) { + return [request: [method : request.method, + url : request.url, + urlPattern: buildUrlPattern(), + urlPath : request.urlPath, + headers : buildHeaders()].findAll { it.value }] + } + + private Map buildClientHeadersSection(Request.Headers headers) { + return createHeadersSection(headers) { + Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] + } + } + + private Map buildServerHeadersSection(Request.Headers headers) { + return createHeadersSection(headers) { + Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] + } + } + + private Map createHeadersSection(Request.Headers headers, Closure closure) { + return headers?.entries()?.collectEntries(closure) + } + + + private Map buildClientHeaderFromValuePattern(Request.WithValuePattern valuePattern) { + return getValuePatternSection(valuePattern) + .findAll { it.value } + .collectEntries { [(it.key): it.value.toClientSide()] } + } + + private Map buildServerHeaderFromValuePattern(Request.WithValuePattern valuePattern) { + return getValuePatternSection(valuePattern) + .findAll { it.value } + .collectEntries { [(it.key): it.value.toServerSide()] } + } + + private Map getValuePatternSection(Request.WithValuePattern valuePattern) { + return [equalToJson : valuePattern.equalToJson, + equalToXml : valuePattern.equalToXml, + matchesXPath : valuePattern.matchesXPath, + jsonCompareMode: valuePattern.jsonCompareMode, + equalTo : valuePattern.equalTo, + contains : valuePattern.contains, + matches : valuePattern.matches, + doesNotMatch : valuePattern.doesNotMatch, + absent : valuePattern.absent, + matchesJsonPath: valuePattern.matchesJsonPath] + } + +} 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 new file mode 100644 index 0000000000..f6feb8710e --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -0,0 +1,270 @@ +package io.codearte.accurest.dsl + +import groovy.json.JsonSlurper +import io.coderate.accurest.dsl.GroovyDsl +import io.coderate.accurest.dsl.WiremockStubStrategy +import spock.lang.Ignore +import spock.lang.Specification + +class WiremockGroovyDslSpec extends Specification { + + // TODO: add alias instead of placeholder + @Ignore + def 'should convert groovy dsl stub to wiremock stub'() { + given: + GroovyDsl dsl = GroovyDsl.make { + request { + method('GET') + urlPattern { + client('/[0-9]{2}') + server('/12') + } + } + response { + status(200) + body { + withPlaceholder(client: '2015-01-14', server: '$anyInt($it)') + withTemplate(''' + { + "date" : "$placeholder0" + } + ''') + } + headers { + Content-Type('text/plain') + } + } + } + expect: + dsl.toWiremockClientStub() == ''' +{ + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}" + }, + "response": { + "status": 200, + "body": "2015-01-14", + "headers": { + "Content-Type": "text/plain" + } + } +} +''' + } + + def "should generate stub with GET"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method("GET") + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request":{ + "method":"GET" + } + } + ''') + } + + def "should generate request when two elements are provided "() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method("GET") + url("/sth") + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request":{ + "method":"GET", + "url":"/sth" + } + } + ''') + } + + def "should generate request with urlPattern for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + urlPattern { + client('/^[0-9]{2}$') + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request":{ + "urlPattern":"/^[0-9]{2}$" + } + } + ''') + } + + def "should generate stub with urlPattern for server side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + urlPattern { + client('/^[0-9]{2}$') + server('/12') + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request":{ + "urlPattern":"/12" + } + } + ''') + } + + def "should generate stub with urlPath for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + urlPath ('/12') + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request":{ + "urlPath":"/12" + } + } + ''') + } + + def "should generate stub with urlPath for server side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + urlPath ('/12') + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request":{ + "urlPath":"/12" + } + } + ''') + } + + def "should generate stub with some headers section for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + headers { + header('Content-Type').equalTo('text/xml') + header('Accept').matches { + client('text/.*') + server('text/plain') + } + header('etag').doesNotMatch { + client('abcd.*') + server('abcdef') + } + header('X-Custom-Header').contains { + client('2134') + server('121345') + } + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request":{ + "headers": { + "Content-Type": { + "equalTo": "text/xml" + }, + "Accept": { + "matches": "text/.*" + }, + "etag": { + "doesNotMatch": "abcd.*" + }, + "X-Custom-Header": { + "contains": "2134" + } + } + } + } + ''') + } + + def "should generate stub with some headers section for server side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + headers { + header('Content-Type').equalTo('text/xml') + header('Accept').matches { + client('text/.*') + server('text/plain') + } + header('etag').doesNotMatch { + client('abcd.*') + server('abcdef') + } + header('X-Custom-Header').contains { + client('2134') + server('121345') + } + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request":{ + "headers": { + "Content-Type": { + "equalTo": "text/xml" + }, + "Accept": { + "matches": "text/plain" + }, + "etag": { + "doesNotMatch": "abcdef" + }, + "X-Custom-Header": { + "contains": "121345" + } + } + } + } + ''') + } + + +} 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 c86884d0b8..b3bd8d6509 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,5 +1,6 @@ package io.codearte.accurest.plugin +import io.coderate.accurest.AccurestException import io.coderate.accurest.TestGenerator import io.coderate.accurest.config.AccurestConfigProperties import org.gradle.api.Plugin @@ -24,19 +25,20 @@ class AccurestGradlePlugin implements Plugin { project.logger.info("Accurest Plugin: Invoking test sources generation") extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory - extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) project.sourceSets.test.groovy { project.logger.info("Registering $extension.generatedTestSourcesDir as test source directory") srcDir extension.generatedTestSourcesDir } + extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) + try { TestGenerator generator = new TestGenerator(extension) int generatedClasses = generator.generate() project.logger.info("Generated {} test classes", generatedClasses) - } catch (IllegalStateException e) { - project.logger.error("Accurest Plugin: {}", e.getMessage()) + } catch (AccurestException e) { + project.logger.error("Accurest Plugin exception: {}", e.getMessage()) } } diff --git a/build.gradle b/build.gradle index 701ea81137..33ecf9a2db 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,9 @@ subprojects { dependencies { compile localGroovy() - testCompile 'org.spockframework:spock-core:0.7-groovy-2.0' + testCompile('org.spockframework:spock-core:0.7-groovy-2.0') { + exclude(group: 'org.codehaus.groovy') + } } publishing { From e5ee0e437d0c15c9459c8f011d53b129b05b52d9 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Wed, 4 Feb 2015 12:00:03 +0100 Subject: [PATCH 036/719] [#5] Extract common DSL elements --- .../io/coderate/accurest/dsl/GroovyDsl.groovy | 9 ++ .../io/coderate/accurest/dsl/Request.groovy | 143 +----------------- .../accurest/dsl/WiremockStubStrategy.groovy | 21 +-- .../dsl/internal/CustomizableProperty.groovy | 39 +++++ .../dsl/internal/DelegateHelper.groovy | 10 ++ .../accurest/dsl/internal/Headers.groovy | 17 +++ .../dsl/internal/JSONCompareMode.groovy | 5 + .../dsl/internal/WithValuePattern.groovy | 51 +++++++ 8 files changed, 148 insertions(+), 147 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DelegateHelper.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy index 35a2acbc7d..3eb01b9e8c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -1,11 +1,13 @@ package io.coderate.accurest.dsl import groovy.transform.TypeChecked +import io.coderate.accurest.dsl.internal.Response @TypeChecked class GroovyDsl { Request request + Response response static GroovyDsl make(Closure closure) { GroovyDsl dsl = new GroovyDsl() @@ -20,4 +22,11 @@ class GroovyDsl { closure.delegate = request closure() } + + void response(@DelegatesTo(Response) Closure closure) { + Response response = new Response() + this.response = response + closure.delegate = response + closure() + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy index d4f40ef6ba..60fd51b785 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy @@ -1,9 +1,14 @@ package io.coderate.accurest.dsl import groovy.transform.TypeChecked +import io.coderate.accurest.dsl.internal.Headers +import io.coderate.accurest.dsl.internal.StringCustomizableProperty + +import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure @TypeChecked class Request { + String method String url StringCustomizableProperty urlPattern @@ -33,140 +38,4 @@ class Request { void urlPath(String urlPath) { this.urlPath = urlPath } - - //TODO: Can we have different types for Client/Server (client: pattern(String), server: value(Boolean/Int)) ? - class CustomizableProperty { - private T client - private V server - - void client(T client) { - this.client = client - } - - void server(V server) { - this.server = server - } - - T toClientSide() { - return client - } - - V toServerSide() { - return server - } - } - - private class StringCustomizableProperty extends CustomizableProperty { - @Override - String toClientSide() { - return super.toClientSide() as String - } - - @Override - String toServerSide() { - return super.toServerSide() as String - } - } - - private class NoOpCustomizableProperty extends CustomizableProperty { - NoOpCustomizableProperty(T value) { - client(value) - server(value) - } - - @Override - public String toString() { - return toClientSide() - } - } - - class Headers { - private Map headers = [:] - - WithValuePattern header(String headerName) { - WithValuePattern withValuePattern = new WithValuePattern() - headers[headerName] = withValuePattern - return withValuePattern - } - - Set> entries() { - return headers.entrySet() - } - } - -/** - * - * From Wiremock - private Map queryParamPatterns; - private List bodyPatterns; - - private String equalToJson; - private String equalToXml; - private String matchesXPath; - private JSONCompareMode jsonCompareMode; - private String equalTo; - private String contains; - private String matches; - private String doesNotMatch; - private Boolean absent; - private String matchesJsonPath; - - */ - class WithValuePattern { - NoOpCustomizableProperty equalToJson - NoOpCustomizableProperty equalToXml - StringCustomizableProperty matchesXPath - NoOpCustomizableProperty jsonCompareMode - NoOpCustomizableProperty equalTo - StringCustomizableProperty contains - StringCustomizableProperty matches - StringCustomizableProperty doesNotMatch - CustomizableProperty absent - StringCustomizableProperty matchesJsonPath - -// void equalToJson(String equalToJson) { -// this.equalToJson = equalToJson -// } -// - void equalTo(String equalTo) { - this.equalTo = new NoOpCustomizableProperty(equalTo) - } - -// void equalToXml(String equalToXml) { -// this.equalToXml = equalToXml -// } - - void matches(@DelegatesTo(StringCustomizableProperty) Closure closure) { - StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() - this.matches = placeholderHaving - delegateToClosure(closure, placeholderHaving) - } - - void doesNotMatch(@DelegatesTo(StringCustomizableProperty) Closure closure) { - StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() - this.doesNotMatch = placeholderHaving - delegateToClosure(closure, placeholderHaving) - } - - void contains(@DelegatesTo(StringCustomizableProperty) Closure closure) { - StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() - this.contains = placeholderHaving - delegateToClosure(closure, placeholderHaving) - } - -// void jsonCompareMode(JSONCompareMode jsonCompareMode) { -// this.jsonCompareMode = jsonCompareMode -// } - - } - - enum JSONCompareMode { - STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER; - } - - private static void delegateToClosure(@DelegatesTo(T) Closure closure, T delegate) { - closure.delegate = delegate - closure() - } - -} \ No newline at end of file +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy index ea975a0ca8..ee846b1a28 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy @@ -2,6 +2,9 @@ package io.coderate.accurest.dsl import groovy.json.JsonOutput import groovy.transform.CompileStatic +import io.coderate.accurest.dsl.internal.CustomizableProperty +import io.coderate.accurest.dsl.internal.Headers +import io.coderate.accurest.dsl.internal.WithValuePattern @CompileStatic class WiremockStubStrategy { @@ -14,7 +17,6 @@ class WiremockStubStrategy { String toWiremockClientStub() { return JsonOutput.toJson(buildClientRequest(request)) - } String toWiremockServerStub() { @@ -41,36 +43,36 @@ class WiremockStubStrategy { headers : buildHeaders()].findAll { it.value }] } - private Map buildClientHeadersSection(Request.Headers headers) { + private Map buildClientHeadersSection(Headers headers) { return createHeadersSection(headers) { - Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] + Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] } } - private Map buildServerHeadersSection(Request.Headers headers) { + private Map buildServerHeadersSection(Headers headers) { return createHeadersSection(headers) { - Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] + Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] } } - private Map createHeadersSection(Request.Headers headers, Closure closure) { + private Map createHeadersSection(Headers headers, Closure closure) { return headers?.entries()?.collectEntries(closure) } - private Map buildClientHeaderFromValuePattern(Request.WithValuePattern valuePattern) { + private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) { return getValuePatternSection(valuePattern) .findAll { it.value } .collectEntries { [(it.key): it.value.toClientSide()] } } - private Map buildServerHeaderFromValuePattern(Request.WithValuePattern valuePattern) { + private Map buildServerHeaderFromValuePattern(WithValuePattern valuePattern) { return getValuePatternSection(valuePattern) .findAll { it.value } .collectEntries { [(it.key): it.value.toServerSide()] } } - private Map getValuePatternSection(Request.WithValuePattern valuePattern) { + private Map getValuePatternSection(WithValuePattern valuePattern) { return [equalToJson : valuePattern.equalToJson, equalToXml : valuePattern.equalToXml, matchesXPath : valuePattern.matchesXPath, @@ -82,5 +84,4 @@ class WiremockStubStrategy { absent : valuePattern.absent, matchesJsonPath: valuePattern.matchesJsonPath] } - } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy new file mode 100644 index 0000000000..592fff82a0 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy @@ -0,0 +1,39 @@ +package io.coderate.accurest.dsl.internal + +//TODO: Can we have different types for Client/Server (client: pattern(String), server: value(Boolean/Int)) ? +class CustomizableProperty { + + private T client + private V server + + void client(T client) { + this.client = client + } + + void server(V server) { + this.server = server + } + + T toClientSide() { + return client + } + + V toServerSide() { + return server + } +} + +class StringCustomizableProperty extends CustomizableProperty { +} + +class NoOpCustomizableProperty extends CustomizableProperty { + NoOpCustomizableProperty(T value) { + client(value) + server(value) + } + + @Override + public String toString() { + return toClientSide() + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DelegateHelper.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DelegateHelper.groovy new file mode 100644 index 0000000000..baa8240dcf --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DelegateHelper.groovy @@ -0,0 +1,10 @@ +package io.coderate.accurest.dsl.internal + +//TODO: There is problem with a trait usage +class DelegateHelper { + + public static void delegateToClosure(@DelegatesTo(T) Closure closure, T delegate) { + closure.delegate = delegate + closure() + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy new file mode 100644 index 0000000000..3ab38d42ec --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -0,0 +1,17 @@ +package io.coderate.accurest.dsl.internal + +class Headers { + + private Map headers = [:] + + WithValuePattern header(String headerName) { + WithValuePattern withValuePattern = new WithValuePattern() + headers[headerName] = withValuePattern + return withValuePattern + } + + Set> entries() { + //TODO: Make it immutable + return headers.entrySet() + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy new file mode 100644 index 0000000000..591432866e --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy @@ -0,0 +1,5 @@ +package io.coderate.accurest.dsl.internal + +enum JSONCompareMode { + STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER; +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy new file mode 100644 index 0000000000..5f92b4f27f --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy @@ -0,0 +1,51 @@ +package io.coderate.accurest.dsl.internal + +import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure + +class WithValuePattern { + + NoOpCustomizableProperty equalToJson + NoOpCustomizableProperty equalToXml + StringCustomizableProperty matchesXPath + NoOpCustomizableProperty jsonCompareMode + NoOpCustomizableProperty equalTo + StringCustomizableProperty contains + StringCustomizableProperty matches + StringCustomizableProperty doesNotMatch + CustomizableProperty absent + StringCustomizableProperty matchesJsonPath + +// void equalToJson(String equalToJson) { +// this.equalToJson = equalToJson +// } +// + void equalTo(String equalTo) { + this.equalTo = new NoOpCustomizableProperty(equalTo) + } + +// void equalToXml(String equalToXml) { +// this.equalToXml = equalToXml +// } + + void matches(@DelegatesTo(StringCustomizableProperty) Closure closure) { + StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() + this.matches = placeholderHaving + delegateToClosure(closure, placeholderHaving) + } + + void doesNotMatch(@DelegatesTo(StringCustomizableProperty) Closure closure) { + StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() + this.doesNotMatch = placeholderHaving + delegateToClosure(closure, placeholderHaving) + } + + void contains(@DelegatesTo(StringCustomizableProperty) Closure closure) { + StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() + this.contains = placeholderHaving + delegateToClosure(closure, placeholderHaving) + } + +// void jsonCompareMode(JSONCompareMode jsonCompareMode) { +// this.jsonCompareMode = jsonCompareMode +// } +} From daffd14cc3b87016b64574fd93aadb014923a73a Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Wed, 4 Feb 2015 13:36:41 +0100 Subject: [PATCH 037/719] [#5] Add basic response implementation, extract base strategy elements --- .gitignore | 2 + ...groovy => BaseWiremockStubStrategy.groovy} | 43 +-------------- .../io/coderate/accurest/dsl/GroovyDsl.groovy | 1 + .../dsl/WiremockRequestStubStrategy.groovy | 43 +++++++++++++++ .../dsl/WiremockResponseStubStrategy.groovy | 29 ++++++++++ .../dsl/{ => internal}/Request.groovy | 2 +- .../accurest/dsl/internal/Response.groovy | 29 ++++++++++ .../dsl/WiremockGroovyDslResponseSpec.groovy | 55 +++++++++++++++++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 18 +++--- 9 files changed, 172 insertions(+), 50 deletions(-) rename accurest-core/src/main/groovy/io/coderate/accurest/dsl/{WiremockStubStrategy.groovy => BaseWiremockStubStrategy.groovy} (58%) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy rename accurest-core/src/main/groovy/io/coderate/accurest/dsl/{ => internal}/Request.groovy (96%) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy diff --git a/.gitignore b/.gitignore index c1785e61a0..5fd4a2d374 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ *.iml .idea/ +.gradle/ target/ +build/ hs_err_pid* diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy similarity index 58% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index ee846b1a28..8c02509ad8 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -1,55 +1,19 @@ package io.coderate.accurest.dsl -import groovy.json.JsonOutput import groovy.transform.CompileStatic import io.coderate.accurest.dsl.internal.CustomizableProperty import io.coderate.accurest.dsl.internal.Headers import io.coderate.accurest.dsl.internal.WithValuePattern @CompileStatic -class WiremockStubStrategy { - - private final Request request - - WiremockStubStrategy(GroovyDsl groovyDsl) { - this.request = groovyDsl.request - } - - String toWiremockClientStub() { - return JsonOutput.toJson(buildClientRequest(request)) - } - - String toWiremockServerStub() { - return JsonOutput.toJson(buildServerRequest(request)) - } - - private Map buildClientRequest(Request request) { - return getRequestSection(request, - { request.urlPattern?.toClientSide() }, - { buildClientHeadersSection(request.headers) }) - } - - private Map buildServerRequest(Request request) { - return getRequestSection(request, - { request.urlPattern?.toServerSide() }, - { buildServerHeadersSection(request.headers) }) - } - - private Map> getRequestSection(Request request, Closure buildUrlPattern, Closure buildHeaders) { - return [request: [method : request.method, - url : request.url, - urlPattern: buildUrlPattern(), - urlPath : request.urlPath, - headers : buildHeaders()].findAll { it.value }] - } - - private Map buildClientHeadersSection(Headers headers) { +abstract class BaseWiremockStubStrategy { + protected Map buildClientHeadersSection(Headers headers) { return createHeadersSection(headers) { Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] } } - private Map buildServerHeadersSection(Headers headers) { + protected Map buildServerHeadersSection(Headers headers) { return createHeadersSection(headers) { Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] } @@ -59,7 +23,6 @@ class WiremockStubStrategy { return headers?.entries()?.collectEntries(closure) } - private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) { return getValuePatternSection(valuePattern) .findAll { it.value } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy index 3eb01b9e8c..1ae6fe4644 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -1,6 +1,7 @@ package io.coderate.accurest.dsl import groovy.transform.TypeChecked +import io.coderate.accurest.dsl.internal.Request import io.coderate.accurest.dsl.internal.Response @TypeChecked diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy new file mode 100644 index 0000000000..3693d7864e --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -0,0 +1,43 @@ +package io.coderate.accurest.dsl + +import groovy.json.JsonOutput +import groovy.transform.CompileStatic +import io.coderate.accurest.dsl.internal.Request + +@CompileStatic +class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { + + private final Request request + + WiremockRequestStubStrategy(GroovyDsl groovyDsl) { + this.request = groovyDsl.request + } + + String toWiremockClientStub() { + return JsonOutput.toJson(buildClientRequest(request)) + } + + String toWiremockServerStub() { + return JsonOutput.toJson(buildServerRequest(request)) + } + + private Map buildClientRequest(Request request) { + return getRequestSection(request, + { request.urlPattern?.toClientSide() }, + { buildClientHeadersSection(request.headers) }) + } + + private Map buildServerRequest(Request request) { + return getRequestSection(request, + { request.urlPattern?.toServerSide() }, + { buildServerHeadersSection(request.headers) }) + } + + private Map> getRequestSection(Request request, Closure buildUrlPattern, Closure buildHeaders) { + return [request: [method : request.method, + url : request.url, + urlPattern: buildUrlPattern(), + urlPath : request.urlPath, + headers : buildHeaders()].findAll { it.value }] + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy new file mode 100644 index 0000000000..297b001345 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -0,0 +1,29 @@ +package io.coderate.accurest.dsl + +import groovy.json.JsonOutput +import groovy.transform.CompileStatic +import io.coderate.accurest.dsl.internal.Response + +@CompileStatic +class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { + + Response response + + WiremockResponseStubStrategy(GroovyDsl groovyDsl) { //TODO: Or Response? + this.response = groovyDsl.response + } + + String toWiremockClientStub() { + return JsonOutput.toJson(buildClientRequest(response)) + } + + private Map buildClientRequest(Response response) { + return getResponseSection(response, { "TODO" }, { buildClientHeadersSection(response.headers) }) + } + + private Map> getResponseSection(Response response, Closure buildUrlPattern, Closure buildHeaders) { + return [response: [status : response.status, + headers: buildHeaders()] + .findAll { it.value }] + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy similarity index 96% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy rename to accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy index 60fd51b785..d89bd1bd84 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/Request.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy @@ -1,4 +1,4 @@ -package io.coderate.accurest.dsl +package io.coderate.accurest.dsl.internal import groovy.transform.TypeChecked import io.coderate.accurest.dsl.internal.Headers diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy new file mode 100644 index 0000000000..6b0c0d1916 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -0,0 +1,29 @@ +package io.coderate.accurest.dsl.internal + +import groovy.transform.TypeChecked + +import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure + +@TypeChecked +class Response { + + private int status + private Headers headers + + void status(int status) { + this.status = status + } + + void headers(@DelegatesTo(Headers) Closure closure) { + this.headers = new Headers() + delegateToClosure(closure, headers) + } + + int getStatus() { + return status + } + + Headers getHeaders() { + return headers + } +} 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 new file mode 100644 index 0000000000..752cdec417 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy @@ -0,0 +1,55 @@ +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 { + + def 'should generate response without body for client side'() { + given: + GroovyDsl dsl = GroovyDsl.make { + response { + status 200 + } + } + when: + String wiremockStub = new WiremockResponseStubStrategy(dsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "response": { + "status": 200 + } + } + ''') + } + + def 'should generate headers for response for client side'() { + given: + GroovyDsl dsl = GroovyDsl.make { + response { + headers { + header('Content-Type').equalTo('text/xml') + } + status 200 + } + } + when: + String wiremockStub = new WiremockResponseStubStrategy(dsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "response": { + "headers": { + "Content-Type": { + "equalTo": "text/xml" + }, + }, + "status": 200 + } + } + ''') + } +} 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 f6feb8710e..493151c210 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -2,7 +2,7 @@ package io.codearte.accurest.dsl import groovy.json.JsonSlurper import io.coderate.accurest.dsl.GroovyDsl -import io.coderate.accurest.dsl.WiremockStubStrategy +import io.coderate.accurest.dsl.WiremockRequestStubStrategy import spock.lang.Ignore import spock.lang.Specification @@ -61,7 +61,7 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { @@ -81,7 +81,7 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { @@ -103,7 +103,7 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { @@ -125,7 +125,7 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub() then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { @@ -144,7 +144,7 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { @@ -163,7 +163,7 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub() then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { @@ -196,7 +196,7 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { @@ -242,7 +242,7 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub() then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { From c9eb699bc34eecfe6cfd37953bc66f8a3227817d Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Thu, 5 Feb 2015 12:45:38 +0100 Subject: [PATCH 038/719] [#5] Simplify tests for Response --- .../dsl/WiremockResponseStubStrategy.groovy | 12 ++++- .../dsl/WiremockGroovyDslResponseSpec.groovy | 46 +++++++++++++++++-- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 4 ++ 3 files changed, 56 insertions(+), 6 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index 297b001345..1df83b5f58 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -14,13 +14,21 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { } String toWiremockClientStub() { - return JsonOutput.toJson(buildClientRequest(response)) + return JsonOutput.toJson(buildClientResponse(response)) } - private Map buildClientRequest(Response response) { + private Map buildClientResponse(Response response) { return getResponseSection(response, { "TODO" }, { buildClientHeadersSection(response.headers) }) } + String toWiremockServerStub() { + return JsonOutput.toJson(buildServerResponse(response)) + } + + private Map buildServerResponse(Response response) { + return getResponseSection(response, { "TODO" }, { buildServerHeadersSection(response.headers) }) + } + private Map> getResponseSection(Response response, Closure buildUrlPattern, Closure buildHeaders) { return [response: [status : response.status, headers: buildHeaders()] 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 752cdec417..65241c420d 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 @@ -3,11 +3,12 @@ package io.codearte.accurest.dsl import groovy.json.JsonSlurper import io.coderate.accurest.dsl.GroovyDsl import io.coderate.accurest.dsl.WiremockResponseStubStrategy +import spock.lang.Ignore import spock.lang.Specification class WiremockGroovyDslResponseSpec extends Specification { - def 'should generate response without body for client side'() { + def 'should generate response without body for #side side'() { given: GroovyDsl dsl = GroovyDsl.make { response { @@ -15,15 +16,26 @@ class WiremockGroovyDslResponseSpec extends Specification { } } when: - String wiremockStub = new WiremockResponseStubStrategy(dsl).toWiremockClientStub() + String wiremockStub = new WiremockResponseStubStrategy(dsl)."toWiremock${side}Stub"() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(expectedStub) + where: + side << ['Client', 'Server'] + expectedStub << [''' { "response": { "status": 200 } } - ''') + ''', + + ''' + { + "response": { + "status": 200 + } + } + '''] } def 'should generate headers for response for client side'() { @@ -52,4 +64,30 @@ class WiremockGroovyDslResponseSpec extends Specification { } ''') } + + @Ignore("Not implemented yet") + def 'should generate headers for response for server side'() { + given: + GroovyDsl dsl = GroovyDsl.make { + response { + status 200 + headers { + header('Content-Type').equalTo('text/xml') + } + } + } + when: + String wiremockStub = new WiremockResponseStubStrategy(dsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "response": { + "status": 200, + "headers": + "Content-Type": "text/xml" + } + } + } + ''') + } } 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 493151c210..a26983984d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -266,5 +266,9 @@ class WiremockGroovyDslSpec extends Specification { ''') } + @Ignore("Not implemented yet") + def "should generate stub with request body matching for server side"() {} + @Ignore("Not implemented yet") + def "should generate stub with request query parameter matching for server side"() {} } From 759e9a163d707eba4e3ae10410814270cd2b209c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 11 Feb 2015 15:12:10 +0100 Subject: [PATCH 039/719] Minor refactoring - changed class name and added immutability on the headers set --- .../accurest/dsl/internal/CustomizableProperty.groovy | 4 ++-- .../io/coderate/accurest/dsl/internal/Headers.groovy | 3 +-- .../accurest/dsl/internal/WithValuePattern.groovy | 10 +++++----- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy index 592fff82a0..fc6dfcb503 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy @@ -26,8 +26,8 @@ class CustomizableProperty { class StringCustomizableProperty extends CustomizableProperty { } -class NoOpCustomizableProperty extends CustomizableProperty { - NoOpCustomizableProperty(T value) { +class SingleTypeCustomizableProperty extends CustomizableProperty { + SingleTypeCustomizableProperty(T value) { client(value) server(value) } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index 3ab38d42ec..ca7e87e7cb 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -11,7 +11,6 @@ class Headers { } Set> entries() { - //TODO: Make it immutable - return headers.entrySet() + return Collections.unmodifiableSet(headers.entrySet()) } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy index 5f92b4f27f..9e44935cfa 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy @@ -4,11 +4,11 @@ import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure class WithValuePattern { - NoOpCustomizableProperty equalToJson - NoOpCustomizableProperty equalToXml + SingleTypeCustomizableProperty equalToJson + SingleTypeCustomizableProperty equalToXml StringCustomizableProperty matchesXPath - NoOpCustomizableProperty jsonCompareMode - NoOpCustomizableProperty equalTo + SingleTypeCustomizableProperty jsonCompareMode + SingleTypeCustomizableProperty equalTo StringCustomizableProperty contains StringCustomizableProperty matches StringCustomizableProperty doesNotMatch @@ -20,7 +20,7 @@ class WithValuePattern { // } // void equalTo(String equalTo) { - this.equalTo = new NoOpCustomizableProperty(equalTo) + this.equalTo = new SingleTypeCustomizableProperty(equalTo) } // void equalToXml(String equalToXml) { From 4898470613ec39a05ea0f8ea8b82fccd38b894f4 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 12 Feb 2015 00:33:22 +0100 Subject: [PATCH 040/719] [#5] Implemented Request and Response with headers and body (not yet fully though ;) ) --- .../dsl/BaseWiremockStubStrategy.groovy | 18 +- .../dsl/WiremockRequestStubStrategy.groovy | 31 +-- .../dsl/WiremockResponseStubStrategy.groovy | 34 ++- .../accurest/dsl/WiremockStubStrategy.groovy | 26 ++ .../accurest/dsl/internal/Body.groovy | 24 ++ .../accurest/dsl/internal/DslProperty.groovy | 19 ++ .../accurest/dsl/internal/Headers.groovy | 18 +- .../accurest/dsl/internal/Response.groovy | 27 ++ .../dsl/WiremockGroovyDslResponseSpec.groovy | 71 +++--- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 230 ++++++++++-------- 10 files changed, 315 insertions(+), 183 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index 8c02509ad8..d30ace044b 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -8,19 +8,25 @@ import io.coderate.accurest.dsl.internal.WithValuePattern @CompileStatic abstract class BaseWiremockStubStrategy { protected Map buildClientHeadersSection(Headers headers) { - return createHeadersSection(headers) { - Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] + if (!headers) { + return null } + return withAssertionHeaders(headers) { + Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] + } << headers?.valueHeaders() } protected Map buildServerHeadersSection(Headers headers) { - return createHeadersSection(headers) { - Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] + if (!headers) { + return null } + return withAssertionHeaders(headers) { + Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] + } << headers.valueHeaders() } - private Map createHeadersSection(Headers headers, Closure closure) { - return headers?.entries()?.collectEntries(closure) + private Map withAssertionHeaders(Headers headers, Closure closure) { + return headers?.assertionEntries()?.collectEntries(closure) } private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 3693d7864e..c4dfa605d5 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,10 +1,11 @@ package io.coderate.accurest.dsl -import groovy.json.JsonOutput import groovy.transform.CompileStatic +import groovy.transform.PackageScope import io.coderate.accurest.dsl.internal.Request @CompileStatic +@PackageScope class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private final Request request @@ -13,31 +14,23 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { this.request = groovyDsl.request } - String toWiremockClientStub() { - return JsonOutput.toJson(buildClientRequest(request)) - } - - String toWiremockServerStub() { - return JsonOutput.toJson(buildServerRequest(request)) - } - - private Map buildClientRequest(Request request) { - return getRequestSection(request, + @PackageScope Map buildClientRequestContent() { + return buildRequestContent(request, { request.urlPattern?.toClientSide() }, { buildClientHeadersSection(request.headers) }) } - private Map buildServerRequest(Request request) { - return getRequestSection(request, + @PackageScope Map buildServerRequestContent() { + return buildRequestContent(request, { request.urlPattern?.toServerSide() }, { buildServerHeadersSection(request.headers) }) } - private Map> getRequestSection(Request request, Closure buildUrlPattern, Closure buildHeaders) { - return [request: [method : request.method, - url : request.url, - urlPattern: buildUrlPattern(), - urlPath : request.urlPath, - headers : buildHeaders()].findAll { it.value }] + private Map buildRequestContent(Request request, Closure buildUrlPattern, Closure buildHeaders) { + return [method : request.method, + url : request.url, + urlPattern: buildUrlPattern(), + urlPath : request.urlPath, + headers : buildHeaders()].findAll { it.value } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index 1df83b5f58..da013d07f3 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -1,37 +1,35 @@ package io.coderate.accurest.dsl -import groovy.json.JsonOutput import groovy.transform.CompileStatic +import groovy.transform.PackageScope import io.coderate.accurest.dsl.internal.Response @CompileStatic +@PackageScope class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { - Response response + private final Response response - WiremockResponseStubStrategy(GroovyDsl groovyDsl) { //TODO: Or Response? + WiremockResponseStubStrategy(GroovyDsl groovyDsl) { this.response = groovyDsl.response } - String toWiremockClientStub() { - return JsonOutput.toJson(buildClientResponse(response)) + @PackageScope Map buildClientResponseContent() { + return buildResponseContent(response, + { response.getBody().forClientSide() }, + { buildClientHeadersSection(response.headers) }) } - private Map buildClientResponse(Response response) { - return getResponseSection(response, { "TODO" }, { buildClientHeadersSection(response.headers) }) + @PackageScope Map buildServerResponseContent() { + return buildResponseContent(response, + { response.getBody().forServerSide() }, + { buildServerHeadersSection(response.headers) }) } - String toWiremockServerStub() { - return JsonOutput.toJson(buildServerResponse(response)) + private Map buildResponseContent(Response response, Closure> buildBody, Closure buildHeaders) { + return [status : response.status, + body : buildBody(), + headers: buildHeaders()].findAll { it.value } } - private Map buildServerResponse(Response response) { - return getResponseSection(response, { "TODO" }, { buildServerHeadersSection(response.headers) }) - } - - private Map> getResponseSection(Response response, Closure buildUrlPattern, Closure buildHeaders) { - return [response: [status : response.status, - headers: buildHeaders()] - .findAll { it.value }] - } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy new file mode 100644 index 0000000000..c4ced294d6 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy @@ -0,0 +1,26 @@ +package io.coderate.accurest.dsl + +import groovy.json.JsonOutput +import groovy.transform.CompileStatic + +@CompileStatic +class WiremockStubStrategy { + + private final WiremockRequestStubStrategy wiremockRequestStubStrategy + private final WiremockResponseStubStrategy wiremockResponseStubStrategy + + WiremockStubStrategy(GroovyDsl groovyDsl) { + this.wiremockRequestStubStrategy = new WiremockRequestStubStrategy(groovyDsl) + this.wiremockResponseStubStrategy = new WiremockResponseStubStrategy(groovyDsl) + } + + String toWiremockClientStub() { + return JsonOutput.toJson([request: wiremockRequestStubStrategy.buildClientRequestContent(), + response: wiremockResponseStubStrategy.buildClientResponseContent()]) + } + + String toWiremockServerStub() { + return JsonOutput.toJson([request: wiremockRequestStubStrategy.buildServerRequestContent(), + response: wiremockResponseStubStrategy.buildServerResponseContent()]) + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy new file mode 100644 index 0000000000..8d395ee2be --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -0,0 +1,24 @@ +package io.coderate.accurest.dsl.internal +import groovy.transform.CompileStatic + +@CompileStatic +class Body { + + private final Map body + + Body() { + this.body = [:] + } + + Body(Map body) { + this.body = body + } + + Map forClientSide() { + return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.clientValue] } as Map + } + + Map forServerSide() { + return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.serverValue] } as Map + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy new file mode 100644 index 0000000000..f52eabef59 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy @@ -0,0 +1,19 @@ +package io.coderate.accurest.dsl.internal +import groovy.transform.CompileStatic + +@CompileStatic +class DslProperty { + + final Object clientValue + final Object serverValue + + DslProperty(Object clientValue, Object serverValue) { + this.clientValue = clientValue + this.serverValue = serverValue + } + + DslProperty(Object singleValue) { + this.clientValue = singleValue + this.serverValue = singleValue + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index ca7e87e7cb..9ee8dfb242 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -2,15 +2,25 @@ package io.coderate.accurest.dsl.internal class Headers { - private Map headers = [:] + private Map assertionHeaders = [:] + private Map valueHeaders = [:] WithValuePattern header(String headerName) { WithValuePattern withValuePattern = new WithValuePattern() - headers[headerName] = withValuePattern + assertionHeaders[headerName] = withValuePattern return withValuePattern } - Set> entries() { - return Collections.unmodifiableSet(headers.entrySet()) + void header(Map singleHeader) { + Map.Entry first = singleHeader.entrySet().first() + valueHeaders[first?.key] = first?.value + } + + Map valueHeaders() { + return Collections.unmodifiableMap(valueHeaders) + } + + Set> assertionEntries() { + return Collections.unmodifiableSet(assertionHeaders.entrySet()) } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index 6b0c0d1916..e2993fdf5e 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -7,8 +7,12 @@ import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure @TypeChecked class Response { + private static final String CLIENT_PROP_KEY = 'client' + private static final String SERVER_PROP_KEY = 'server' + private int status private Headers headers + private Body body = new Body() void status(int status) { this.status = status @@ -19,6 +23,29 @@ class Response { delegateToClosure(closure, headers) } + void body(Map body) { + this.body = new Body(convertObjectsToDslProperties(body)) + } + + private Map convertObjectsToDslProperties(Map body) { + return body.collectEntries { + Map.Entry entry -> + [(entry.key): entry.value instanceof DslProperty ? entry.value : new DslProperty(entry.value)] + } as Map + } + + DslProperty property(Map properties) { + return new DslProperty(properties[CLIENT_PROP_KEY], properties[SERVER_PROP_KEY]) + } + + DslProperty $(Map properties) { + return property(properties) + } + + Body getBody() { + return body + } + int getStatus() { return status } 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 65241c420d..201d495af6 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 @@ -3,7 +3,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.Ignore import spock.lang.Specification class WiremockGroovyDslResponseSpec extends Specification { @@ -15,25 +14,19 @@ class WiremockGroovyDslResponseSpec extends Specification { status 200 } } - when: - String wiremockStub = new WiremockResponseStubStrategy(dsl)."toWiremock${side}Stub"() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(expectedStub) + expect: + new WiremockResponseStubStrategy(dsl)."build${side}ResponseContent"() == new JsonSlurper().parseText(expectedStub) where: side << ['Client', 'Server'] expectedStub << [''' { - "response": { - "status": 200 - } + "status": 200 } ''', ''' { - "response": { - "status": 200 - } + "status": 200 } '''] } @@ -43,49 +36,69 @@ class WiremockGroovyDslResponseSpec extends Specification { GroovyDsl dsl = GroovyDsl.make { response { headers { - header('Content-Type').equalTo('text/xml') + header('Content-Type').matches { + client('text/xml') + server('text/*') + } } status 200 } } - when: - String wiremockStub = new WiremockResponseStubStrategy(dsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(''' { - "response": { "headers": { "Content-Type": { - "equalTo": "text/xml" + "matches": "text/xml" }, }, "status": 200 - } } ''') } - @Ignore("Not implemented yet") def 'should generate headers for response for server side'() { given: GroovyDsl dsl = GroovyDsl.make { response { status 200 headers { - header('Content-Type').equalTo('text/xml') + header('Content-Type').matches { + client('text/xml') + server('text/*') + } } } } - when: - String wiremockStub = new WiremockResponseStubStrategy(dsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText(''' { - "response": { - "status": 200, - "headers": - "Content-Type": "text/xml" + "status": 200, + "headers": { + "Content-Type": { + "matches": "text/*" + } + } + } + ''') + } + + def 'should generate an exact header for response for both sides '() { + given: + GroovyDsl dsl = GroovyDsl.make { + response { + status 200 + headers { + header 'Content-Type': 'text/xml' + } + } } + expect: + new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText(''' + { + "status": 200, + "headers": { + "Content-Type": "text/xml" } } ''') 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 a26983984d..f5011af153 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -3,40 +3,38 @@ 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.Ignore import spock.lang.Specification class WiremockGroovyDslSpec extends Specification { - // TODO: add alias instead of placeholder - @Ignore - def 'should convert groovy dsl stub to wiremock stub'() { + def 'should convert groovy dsl stub to wiremock stub for the client side'() { given: - GroovyDsl dsl = GroovyDsl.make { - request { - method('GET') - urlPattern { - client('/[0-9]{2}') - server('/12') + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern { + client('/[0-9]{2}') + server('/12') + } + } + response { + status(200) + body ( + id : property(client: '123', server: { regex('[0-9]+') } ), + name: 'Jan', + created : $(client: '2014-02-02 12:23:43', server: { currentDate(it) }) + ) + headers { + header('Content-Type': 'text/plain') + } } } - response { - status(200) - body { - withPlaceholder(client: '2015-01-14', server: '$anyInt($it)') - withTemplate(''' - { - "date" : "$placeholder0" - } - ''') - } - headers { - Content-Type('text/plain') - } - } - } - expect: - dsl.toWiremockClientStub() == ''' + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -44,13 +42,63 @@ class WiremockGroovyDslSpec extends Specification { }, "response": { "status": 200, - "body": "2015-01-14", + "body": { + "id": "123", + "name": "Jan", + "created" : "2014-02-02 12:23:43" + }, "headers": { "Content-Type": "text/plain" } } } -''' +''') + } + + def 'should convert groovy dsl stub to wiremock stub for the server side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern { + client('/[0-9]{2}') + server('/12') + } + } + response { + status(200) + body ( + id : property(client: '123', server: '321' ), + name: 'Jan', + created : $(client: '2014-02-02 12:23:43', server: '1999-01-01 01:23:45') + ) + headers { + header('Content-Type': 'text/plain') + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "GET", + "urlPattern": "/12" + }, + "response": { + "status": 200, + "body": { + "id": "321", + "name": "Jan", + "created" : "1999-01-01 01:23:45" + }, + "headers": { + "Content-Type": "text/plain" + } + } +} +''') } def "should generate stub with GET"() { @@ -60,14 +108,10 @@ class WiremockGroovyDslSpec extends Specification { method("GET") } } - when: - String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { - "request":{ - "method":"GET" - } + "method":"GET" } ''') } @@ -80,15 +124,11 @@ class WiremockGroovyDslSpec extends Specification { url("/sth") } } - when: - String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { - "request":{ - "method":"GET", - "url":"/sth" - } + "method":"GET", + "url":"/sth" } ''') } @@ -102,14 +142,10 @@ class WiremockGroovyDslSpec extends Specification { } } } - when: - String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { - "request":{ - "urlPattern":"/^[0-9]{2}$" - } + "urlPattern":"/^[0-9]{2}$" } ''') } @@ -124,14 +160,10 @@ class WiremockGroovyDslSpec extends Specification { } } } - when: - String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText(''' { - "request":{ - "urlPattern":"/12" - } + "urlPattern":"/12" } ''') } @@ -143,14 +175,10 @@ class WiremockGroovyDslSpec extends Specification { urlPath ('/12') } } - when: - String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { - "request":{ - "urlPath":"/12" - } + "urlPath":"/12" } ''') } @@ -162,14 +190,10 @@ class WiremockGroovyDslSpec extends Specification { urlPath ('/12') } } - when: - String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { - "request":{ - "urlPath":"/12" - } + "urlPath":"/12" } ''') } @@ -195,25 +219,21 @@ class WiremockGroovyDslSpec extends Specification { } } } - when: - String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { - "request":{ - "headers": { - "Content-Type": { - "equalTo": "text/xml" - }, - "Accept": { - "matches": "text/.*" - }, - "etag": { - "doesNotMatch": "abcd.*" - }, - "X-Custom-Header": { - "contains": "2134" - } + "headers": { + "Content-Type": { + "equalTo": "text/xml" + }, + "Accept": { + "matches": "text/.*" + }, + "etag": { + "doesNotMatch": "abcd.*" + }, + "X-Custom-Header": { + "contains": "2134" } } } @@ -241,25 +261,21 @@ class WiremockGroovyDslSpec extends Specification { } } } - when: - String wiremockStub = new WiremockRequestStubStrategy(groovyDsl).toWiremockServerStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + expect: + new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText(''' { - "request":{ - "headers": { - "Content-Type": { - "equalTo": "text/xml" - }, - "Accept": { - "matches": "text/plain" - }, - "etag": { - "doesNotMatch": "abcdef" - }, - "X-Custom-Header": { - "contains": "121345" - } + "headers": { + "Content-Type": { + "equalTo": "text/xml" + }, + "Accept": { + "matches": "text/plain" + }, + "etag": { + "doesNotMatch": "abcdef" + }, + "X-Custom-Header": { + "contains": "121345" } } } From 88537c139ea7135064c42ea6d713ee2b2c210279 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 12 Feb 2015 15:48:55 +0100 Subject: [PATCH 041/719] [#5] Changed the approach to use $(), value() instead of closures with client and server --- .../dsl/BaseWiremockStubStrategy.groovy | 9 +- .../dsl/WiremockRequestStubStrategy.groovy | 30 +++-- .../dsl/WiremockResponseStubStrategy.groovy | 24 ++-- .../dsl/internal/ClientDslProperty.groovy | 13 ++ .../accurest/dsl/internal/Common.groovy | 53 ++++++++ .../dsl/internal/CustomizableProperty.groovy | 39 ------ .../accurest/dsl/internal/DslProperty.groovy | 10 +- .../dsl/internal/JSONCompareMode.groovy | 2 +- .../accurest/dsl/internal/Request.groovy | 67 +++++++--- .../accurest/dsl/internal/Response.groovy | 54 ++++---- .../dsl/internal/ServerDslProperty.groovy | 13 ++ .../dsl/internal/WithValuePattern.groovy | 120 ++++++++++++------ .../dsl/WiremockGroovyDslResponseSpec.groovy | 10 +- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 91 +++++++------ 14 files changed, 342 insertions(+), 193 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy delete mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index d30ace044b..3925ada9f3 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -1,7 +1,6 @@ package io.coderate.accurest.dsl - import groovy.transform.CompileStatic -import io.coderate.accurest.dsl.internal.CustomizableProperty +import io.coderate.accurest.dsl.internal.DslProperty import io.coderate.accurest.dsl.internal.Headers import io.coderate.accurest.dsl.internal.WithValuePattern @@ -32,16 +31,16 @@ abstract class BaseWiremockStubStrategy { private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) { return getValuePatternSection(valuePattern) .findAll { it.value } - .collectEntries { [(it.key): it.value.toClientSide()] } + .collectEntries { [(it.key): it.value.clientValue] } } private Map buildServerHeaderFromValuePattern(WithValuePattern valuePattern) { return getValuePatternSection(valuePattern) .findAll { it.value } - .collectEntries { [(it.key): it.value.toServerSide()] } + .collectEntries { [(it.key): it.value.serverValue] } } - private Map getValuePatternSection(WithValuePattern valuePattern) { + private Map getValuePatternSection(WithValuePattern valuePattern) { return [equalToJson : valuePattern.equalToJson, equalToXml : valuePattern.equalToXml, matchesXPath : valuePattern.matchesXPath, diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index c4dfa605d5..369b082cf8 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -2,7 +2,9 @@ package io.coderate.accurest.dsl import groovy.transform.CompileStatic import groovy.transform.PackageScope +import io.coderate.accurest.dsl.internal.ClientRequest import io.coderate.accurest.dsl.internal.Request +import io.coderate.accurest.dsl.internal.ServerRequest @CompileStatic @PackageScope @@ -15,22 +17,26 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { } @PackageScope Map buildClientRequestContent() { - return buildRequestContent(request, - { request.urlPattern?.toClientSide() }, - { buildClientHeadersSection(request.headers) }) + return buildRequestContent(new ClientRequest(request)) } @PackageScope Map buildServerRequestContent() { - return buildRequestContent(request, - { request.urlPattern?.toServerSide() }, - { buildServerHeadersSection(request.headers) }) + return buildRequestContent(new ServerRequest(request)) } - private Map buildRequestContent(Request request, Closure buildUrlPattern, Closure buildHeaders) { - return [method : request.method, - url : request.url, - urlPattern: buildUrlPattern(), - urlPath : request.urlPath, - headers : buildHeaders()].findAll { it.value } + private Map buildRequestContent(ClientRequest request) { + return [method : request?.method?.clientValue, + url : request?.url?.clientValue, + urlPattern: request?.urlPattern?.clientValue, + urlPath : request?.urlPath?.clientValue, + headers : buildClientHeadersSection(request.headers)].findAll { it.value } + } + + private Map buildRequestContent(ServerRequest request) { + return [method : request?.method?.serverValue, + url : request?.url?.serverValue, + urlPattern: request?.urlPattern?.serverValue, + urlPath : request?.urlPath?.serverValue, + headers : buildServerHeadersSection(request.headers)].findAll { it.value } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index da013d07f3..76f7f38a3b 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -2,7 +2,9 @@ package io.coderate.accurest.dsl import groovy.transform.CompileStatic import groovy.transform.PackageScope +import io.coderate.accurest.dsl.internal.ClientResponse import io.coderate.accurest.dsl.internal.Response +import io.coderate.accurest.dsl.internal.ServerResponse @CompileStatic @PackageScope @@ -15,21 +17,23 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { } @PackageScope Map buildClientResponseContent() { - return buildResponseContent(response, - { response.getBody().forClientSide() }, - { buildClientHeadersSection(response.headers) }) + return buildResponseContent(new ClientResponse(response)) } @PackageScope Map buildServerResponseContent() { - return buildResponseContent(response, - { response.getBody().forServerSide() }, - { buildServerHeadersSection(response.headers) }) + return buildResponseContent(new ServerResponse(response)) } - private Map buildResponseContent(Response response, Closure> buildBody, Closure buildHeaders) { - return [status : response.status, - body : buildBody(), - headers: buildHeaders()].findAll { it.value } + private Map buildResponseContent(ClientResponse response) { + return [status : response?.status?.clientValue, + body : response?.getBody()?.forClientSide(), + headers: buildClientHeadersSection(response.headers)].findAll { it.value } + } + + private Map buildResponseContent(ServerResponse response) { + return [status : response?.status?.serverValue, + body : response?.getBody()?.forServerSide(), + headers: buildServerHeadersSection(response.headers)].findAll { it.value } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy new file mode 100644 index 0000000000..005d52bc7b --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy @@ -0,0 +1,13 @@ +package io.coderate.accurest.dsl.internal +import groovy.transform.CompileStatic + +@CompileStatic +class ClientDslProperty extends DslProperty { + + ClientDslProperty(Object clientValue, Object serverValue) { + super(clientValue, serverValue) } + + ClientDslProperty(Object singleValue) { + super(singleValue) + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy new file mode 100644 index 0000000000..7fbd42caea --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy @@ -0,0 +1,53 @@ +package io.coderate.accurest.dsl.internal + +import groovy.transform.PackageScope +import groovy.transform.TypeChecked + +/** + * @TypeChecked instead of @CompileStatic due to usage of double dispatch. + * Double dispatch doesn't work if you're using @CompileStatic + */ +@TypeChecked +@PackageScope +class Common { + + Map convertObjectsToDslProperties(Map body) { + return body.collectEntries { + Map.Entry entry -> + [(entry.key): toDslProperty(entry.value)] + } as Map + } + + DslProperty toDslProperty(Object property) { + return new DslProperty(property) + } + + DslProperty toDslProperty(DslProperty property) { + return property + } + + DslProperty value(ClientDslProperty client, ServerDslProperty server) { + return new DslProperty(client.clientValue, server.serverValue) + } + + DslProperty value(ServerDslProperty server, ClientDslProperty client) { + return new DslProperty(client.clientValue, server.serverValue) + } + + DslProperty $(ClientDslProperty client, ServerDslProperty server) { + return value(client, server) + } + + DslProperty $(ServerDslProperty server, ClientDslProperty client) { + return value(client, server) + } + + ClientDslProperty client(Object clientValue) { + return new ClientDslProperty(clientValue) + } + + ServerDslProperty server(Object serverValue) { + return new ServerDslProperty(serverValue) + } + +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy deleted file mode 100644 index fc6dfcb503..0000000000 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/CustomizableProperty.groovy +++ /dev/null @@ -1,39 +0,0 @@ -package io.coderate.accurest.dsl.internal - -//TODO: Can we have different types for Client/Server (client: pattern(String), server: value(Boolean/Int)) ? -class CustomizableProperty { - - private T client - private V server - - void client(T client) { - this.client = client - } - - void server(V server) { - this.server = server - } - - T toClientSide() { - return client - } - - V toServerSide() { - return server - } -} - -class StringCustomizableProperty extends CustomizableProperty { -} - -class SingleTypeCustomizableProperty extends CustomizableProperty { - SingleTypeCustomizableProperty(T value) { - client(value) - server(value) - } - - @Override - public String toString() { - return toClientSide() - } -} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy index f52eabef59..11ede5a82e 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy @@ -2,17 +2,17 @@ package io.coderate.accurest.dsl.internal import groovy.transform.CompileStatic @CompileStatic -class DslProperty { +class DslProperty { - final Object clientValue - final Object serverValue + final T clientValue + final T serverValue - DslProperty(Object clientValue, Object serverValue) { + DslProperty(T clientValue, T serverValue) { this.clientValue = clientValue this.serverValue = serverValue } - DslProperty(Object singleValue) { + DslProperty(T singleValue) { this.clientValue = singleValue this.serverValue = singleValue } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy index 591432866e..7f07abb723 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy @@ -1,5 +1,5 @@ package io.coderate.accurest.dsl.internal enum JSONCompareMode { - STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER; + STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy index d89bd1bd84..d28bc159c0 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy @@ -1,32 +1,51 @@ package io.coderate.accurest.dsl.internal - +import groovy.transform.CompileStatic import groovy.transform.TypeChecked -import io.coderate.accurest.dsl.internal.Headers -import io.coderate.accurest.dsl.internal.StringCustomizableProperty import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure @TypeChecked -class Request { +class Request extends Common { - String method - String url - StringCustomizableProperty urlPattern - String urlPath + DslProperty method + DslProperty url + DslProperty urlPattern + DslProperty urlPath Headers headers + Request() { + } + + Request(Request request) { + this.method = request.method + this.url = request.url + this.urlPattern = request.urlPattern + this.urlPath = request.urlPath + this.headers = request.headers + } + void method(String method) { - this.method = method + this.method = toDslProperty(method) + } + + void method(DslProperty method) { + this.method = toDslProperty(method) } void url(String url) { - this.url = url + this.url = toDslProperty(url) } - void urlPattern(@DelegatesTo(StringCustomizableProperty) Closure closure) { - StringCustomizableProperty urlPattern = new StringCustomizableProperty() - this.urlPattern = urlPattern - delegateToClosure(closure, urlPattern) + void url(DslProperty url) { + this.url = toDslProperty(url) + } + + void urlPattern(String urlPattern) { + this.urlPattern = toDslProperty(urlPattern) + } + + void urlPattern(DslProperty urlPattern) { + this.urlPattern = toDslProperty(urlPattern) } void headers(@DelegatesTo(Headers) Closure closure) { @@ -36,6 +55,24 @@ class Request { } void urlPath(String urlPath) { - this.urlPath = urlPath + this.urlPath = toDslProperty(urlPath) + } + + void urlPath(DslProperty urlPath) { + this.urlPath = toDslProperty(urlPath) + } +} + +@CompileStatic +class ServerRequest extends Request { + ServerRequest(Request request) { + super(request) + } +} + +@CompileStatic +class ClientRequest extends Request { + ClientRequest(Request request) { + super(request) } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index e2993fdf5e..fe15280bde 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -1,21 +1,32 @@ package io.coderate.accurest.dsl.internal +import groovy.transform.CompileStatic import groovy.transform.TypeChecked import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure @TypeChecked -class Response { +class Response extends Common { - private static final String CLIENT_PROP_KEY = 'client' - private static final String SERVER_PROP_KEY = 'server' - - private int status + private DslProperty status private Headers headers private Body body = new Body() + Response() { + } + + Response(Response response) { + this.status = response.status + this.headers = response.headers + this.body = response.body + } + void status(int status) { - this.status = status + this.status = toDslProperty(status) + } + + void status(DslProperty status) { + this.status = toDslProperty(status) } void headers(@DelegatesTo(Headers) Closure closure) { @@ -27,26 +38,11 @@ class Response { this.body = new Body(convertObjectsToDslProperties(body)) } - private Map convertObjectsToDslProperties(Map body) { - return body.collectEntries { - Map.Entry entry -> - [(entry.key): entry.value instanceof DslProperty ? entry.value : new DslProperty(entry.value)] - } as Map - } - - DslProperty property(Map properties) { - return new DslProperty(properties[CLIENT_PROP_KEY], properties[SERVER_PROP_KEY]) - } - - DslProperty $(Map properties) { - return property(properties) - } - Body getBody() { return body } - int getStatus() { + DslProperty getStatus() { return status } @@ -54,3 +50,17 @@ class Response { return headers } } + +@CompileStatic +class ServerResponse extends Response { + ServerResponse(Response request) { + super(request) + } +} + +@CompileStatic +class ClientResponse extends Response { + ClientResponse(Response request) { + super(request) + } +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy new file mode 100644 index 0000000000..a23cc80c23 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy @@ -0,0 +1,13 @@ +package io.coderate.accurest.dsl.internal +import groovy.transform.CompileStatic + +@CompileStatic +class ServerDslProperty extends DslProperty { + + ServerDslProperty(Object clientValue, Object serverValue) { + super(clientValue, serverValue) } + + ServerDslProperty(Object singleValue) { + super(singleValue) + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy index 9e44935cfa..32dfddf741 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy @@ -1,51 +1,99 @@ package io.coderate.accurest.dsl.internal +import groovy.transform.TypeChecked -import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure - +@TypeChecked class WithValuePattern { - SingleTypeCustomizableProperty equalToJson - SingleTypeCustomizableProperty equalToXml - StringCustomizableProperty matchesXPath - SingleTypeCustomizableProperty jsonCompareMode - SingleTypeCustomizableProperty equalTo - StringCustomizableProperty contains - StringCustomizableProperty matches - StringCustomizableProperty doesNotMatch - CustomizableProperty absent - StringCustomizableProperty matchesJsonPath + DslProperty equalTo + DslProperty equalToJson + DslProperty equalToXml + DslProperty matchesXPath + DslProperty jsonCompareMode + DslProperty contains + DslProperty matches + DslProperty doesNotMatch + DslProperty absent + DslProperty matchesJsonPath -// void equalToJson(String equalToJson) { -// this.equalToJson = equalToJson -// } -// void equalTo(String equalTo) { - this.equalTo = new SingleTypeCustomizableProperty(equalTo) + this.equalTo = new DslProperty(equalTo) } -// void equalToXml(String equalToXml) { -// this.equalToXml = equalToXml -// } - - void matches(@DelegatesTo(StringCustomizableProperty) Closure closure) { - StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() - this.matches = placeholderHaving - delegateToClosure(closure, placeholderHaving) + void equalTo(DslProperty equalTo) { + this.equalTo = equalTo } - void doesNotMatch(@DelegatesTo(StringCustomizableProperty) Closure closure) { - StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() - this.doesNotMatch = placeholderHaving - delegateToClosure(closure, placeholderHaving) + void equalToJson(String equalToJson) { + this.equalToJson = new DslProperty(equalToJson) } - void contains(@DelegatesTo(StringCustomizableProperty) Closure closure) { - StringCustomizableProperty placeholderHaving = new StringCustomizableProperty() - this.contains = placeholderHaving - delegateToClosure(closure, placeholderHaving) + void equalToJson(DslProperty equalToJson) { + this.equalToJson = equalToJson } -// void jsonCompareMode(JSONCompareMode jsonCompareMode) { -// this.jsonCompareMode = jsonCompareMode -// } + void equalToXml(String equalToXml) { + this.equalToXml = new DslProperty(equalToXml) + } + + void equalToXml(DslProperty equalToXml) { + this.equalToXml = equalToXml + } + + void matchesXPath(String matchesXPath) { + this.matchesXPath = new DslProperty(matchesXPath) + } + + void matchesXPath(DslProperty matchesXPath) { + this.matchesXPath = matchesXPath + } + + void jsonCompareMode(JSONCompareMode jsonCompareMode) { + this.jsonCompareMode = new DslProperty(jsonCompareMode) + } + + void jsonCompareMode(DslProperty jsonCompareMode) { + this.jsonCompareMode = jsonCompareMode + } + + void contains(String contains) { + this.contains = new DslProperty(contains) + } + + void contains(DslProperty contains) { + this.contains = contains + } + + void matches(String matches) { + this.matches = new DslProperty(matches) + } + + void matches(DslProperty matches) { + this.matches = matches + } + + void doesNotMatch(String doesNotMatch) { + this.doesNotMatch = new DslProperty(doesNotMatch) + } + + void doesNotMatch(DslProperty doesNotMatch) { + this.doesNotMatch = doesNotMatch + } + + void absent(String absent) { + this.absent = new DslProperty(absent) + } + + void absent(DslProperty absent) { + this.absent = absent + } + + void matchesJsonPath(String matchesJsonPath) { + this.matchesJsonPath = new DslProperty(matchesJsonPath) + } + + void matchesJsonPath(DslProperty matchesJsonPath) { + this.matchesJsonPath = matchesJsonPath + } + + } 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 201d495af6..f8aa6a6890 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 @@ -36,10 +36,7 @@ class WiremockGroovyDslResponseSpec extends Specification { GroovyDsl dsl = GroovyDsl.make { response { headers { - header('Content-Type').matches { - client('text/xml') - server('text/*') - } + header('Content-Type').matches $(client('text/xml'), server('text/*')) } status 200 } @@ -63,10 +60,7 @@ class WiremockGroovyDslResponseSpec extends Specification { response { status 200 headers { - header('Content-Type').matches { - client('text/xml') - server('text/*') - } + header('Content-Type').matches $(client('text/xml'), server('text/*')) } } } 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 f5011af153..3ee9cd7f11 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -14,20 +14,24 @@ class WiremockGroovyDslSpec extends Specification { GroovyDsl groovyDsl = GroovyDsl.make { request { method('GET') - urlPattern { - client('/[0-9]{2}') - server('/12') - } + urlPattern $(client('/[0-9]{2}'), server('/12')) } response { - status(200) + status 200 body ( - id : property(client: '123', server: { regex('[0-9]+') } ), + id : value( + client('123'), + server({ regex('[0-9]+') }) + ), + surname : $( + client('Kowalsky'), + server('Lewandowski') + ), name: 'Jan', - created : $(client: '2014-02-02 12:23:43', server: { currentDate(it) }) + created : $(client('2014-02-02 12:23:43'), server({ currentDate(it) })) ) headers { - header('Content-Type': 'text/plain') + header 'Content-Type': 'text/plain' } } } @@ -44,6 +48,7 @@ class WiremockGroovyDslSpec extends Specification { "status": 200, "body": { "id": "123", + "surname": "Kowalsky", "name": "Jan", "created" : "2014-02-02 12:23:43" }, @@ -60,17 +65,21 @@ class WiremockGroovyDslSpec extends Specification { GroovyDsl groovyDsl = GroovyDsl.make { request { method('GET') - urlPattern { - client('/[0-9]{2}') - server('/12') - } + urlPattern $(client('/[0-9]{2}'), server('/12')) } response { status(200) body ( - id : property(client: '123', server: '321' ), - name: 'Jan', - created : $(client: '2014-02-02 12:23:43', server: '1999-01-01 01:23:45') + id : value( + client('123'), + server('321') + ), + surname : $( + client('Kowalsky'), + server('Lewandowski') + ), + name: 'Jan', + created : $(client('2014-02-02 12:23:43'), server('1999-01-01 01:23:45')) ) headers { header('Content-Type': 'text/plain') @@ -90,6 +99,7 @@ class WiremockGroovyDslSpec extends Specification { "status": 200, "body": { "id": "321", + "surname": "Lewandowski", "name": "Jan", "created" : "1999-01-01 01:23:45" }, @@ -137,9 +147,10 @@ class WiremockGroovyDslSpec extends Specification { given: GroovyDsl groovyDsl = GroovyDsl.make { request { - urlPattern { - client('/^[0-9]{2}$') - } + urlPattern $( + client('/^[0-9]{2}$'), + server('/12') + ) } } expect: @@ -154,10 +165,10 @@ class WiremockGroovyDslSpec extends Specification { given: GroovyDsl groovyDsl = GroovyDsl.make { request { - urlPattern { - client('/^[0-9]{2}$') - server('/12') - } + urlPattern $( + client('/[0-9]{2}'), + server('/12') + ) } } expect: @@ -204,18 +215,18 @@ class WiremockGroovyDslSpec extends Specification { request { headers { header('Content-Type').equalTo('text/xml') - header('Accept').matches { - client('text/.*') + header('Accept').matches $( + client('text/.*'), server('text/plain') - } - header('etag').doesNotMatch { - client('abcd.*') + ) + header('etag').doesNotMatch $( + client('abcd.*'), server('abcdef') - } - header('X-Custom-Header').contains { - client('2134') + ) + header('X-Custom-Header').contains $( + client('2134'), server('121345') - } + ) } } } @@ -246,18 +257,18 @@ class WiremockGroovyDslSpec extends Specification { request { headers { header('Content-Type').equalTo('text/xml') - header('Accept').matches { - client('text/.*') + header('Accept').matches $( + client('text/.*'), server('text/plain') - } - header('etag').doesNotMatch { - client('abcd.*') + ) + header('etag').doesNotMatch $( + client('abcd.*'), server('abcdef') - } - header('X-Custom-Header').contains { - client('2134') + ) + header('X-Custom-Header').contains $( + client('2134'), server('121345') - } + ) } } } From e5d218a2d2167964eccf25c6ef2c510aab4dd5c5 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 12 Feb 2015 16:01:22 +0100 Subject: [PATCH 042/719] [#5] Minor refactoring --- .../accurest/dsl/WiremockResponseStubStrategy.groovy | 4 ++-- .../groovy/io/coderate/accurest/dsl/internal/Body.groovy | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index 76f7f38a3b..ab62663b51 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -26,13 +26,13 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { private Map buildResponseContent(ClientResponse response) { return [status : response?.status?.clientValue, - body : response?.getBody()?.forClientSide(), + body : response?.body?.forClientSide(), headers: buildClientHeadersSection(response.headers)].findAll { it.value } } private Map buildResponseContent(ServerResponse response) { return [status : response?.status?.serverValue, - body : response?.getBody()?.forServerSide(), + body : response?.body?.forServerSide(), headers: buildServerHeadersSection(response.headers)].findAll { it.value } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index 8d395ee2be..90ae62d726 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -15,10 +15,14 @@ class Body { } Map forClientSide() { - return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.clientValue] } as Map + return body.collectEntries { + Map.Entry entry -> [(entry.key) : entry.value.clientValue] + } as Map } Map forServerSide() { - return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.serverValue] } as Map + return body.collectEntries { + Map.Entry entry -> [(entry.key) : entry.value.serverValue] + } as Map } } From 4e0296252521fffa51bc1e7ef303bbc242f1230c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 12 Feb 2015 17:21:45 +0100 Subject: [PATCH 043/719] [#10] Added initial version of Wiremock -> GroovyDsl --- .../wiremock/WiremockToDslConverter.groovy | 37 +++++++++++++ .../WiremockToDslConverterSpec.groovy | 54 +++++++++++++++++++ .../io/coderate/accurest/dsl/GroovyDsl.groovy | 4 ++ .../accurest/dsl/internal/Body.groovy | 4 ++ .../accurest/dsl/internal/DslProperty.groovy | 4 ++ .../accurest/dsl/internal/Headers.groovy | 5 ++ .../accurest/dsl/internal/Request.groovy | 8 +++ .../accurest/dsl/internal/Response.groovy | 8 +++ .../dsl/internal/ServerDslProperty.groovy | 4 ++ .../dsl/internal/WithValuePattern.groovy | 5 ++ build.gradle | 6 +++ settings.gradle | 5 +- 12 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy create mode 100644 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy 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 new file mode 100644 index 0000000000..cdd09eee72 --- /dev/null +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -0,0 +1,37 @@ +package io.codearte.accurest.wiremock +import groovy.json.JsonSlurper +import io.coderate.accurest.dsl.GroovyDsl + +class WiremockToDslConverter { + static GroovyDsl fromWiremockStub(String wiremockStringStub) { + Object wiremockStub = new JsonSlurper().parseText(wiremockStringStub) + def wiremockRequest = wiremockStub.request + def wiremockResponse = wiremockStub.response + return GroovyDsl.make { + request { + wiremockRequest.method ? method(wiremockRequest.method as String) : null + wiremockRequest.url ? url(wiremockRequest.url as String) : null + wiremockRequest.urlPattern ? urlPattern(wiremockRequest.urlPattern as String) : null + wiremockRequest.urlPath ? urlPath(wiremockRequest.urlPath as String) : null + wiremockRequest.headers ? headers { + wiremockRequest.headers.each { + def assertion = it.value + String headerName = it.key as String + header(headerName)."$assertion.key"(assertion.value) + } + } : null + } + response { + status wiremockResponse.status ? wiremockResponse.status as Integer : null + wiremockResponse.body ? body ( + wiremockResponse.body as Map + ) : null + wiremockResponse.headers ? headers { + wiremockResponse.headers.each { + header([(it.key) : it.value]) + } + } : null + } + } + } +} 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 new file mode 100644 index 0000000000..6a4534a20b --- /dev/null +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -0,0 +1,54 @@ +package io.codearte.accurest.wiremock + +import io.coderate.accurest.dsl.GroovyDsl +import spock.lang.Specification + +class WiremockToDslConverterSpec extends Specification { + + def 'should produce a Groovy DSL from Wiremock stub'() { + given: + String wiremockStub = ''' +{ + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}" + }, + "response": { + "status": 200, + "body": { + "id": "123", + "surname": "Kowalsky", + "name": "Jan", + "created" : "2014-02-02 12:23:43" + }, + "headers": { + "Content-Type": "text/plain" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPattern '/[0-9]{2}' + } + response { + status 200 + body ( + id : '123', + surname : 'Kowalsky', + name: 'Jan', + created : '2014-02-02 12:23:43' + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + GroovyDsl groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + groovyDsl == expectedGroovyDsl + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy index 1ae6fe4644..47a0e8e72f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -1,10 +1,14 @@ package io.coderate.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 @TypeChecked +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class GroovyDsl { Request request diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index 90ae62d726..e3b75c9eb4 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -1,7 +1,11 @@ package io.coderate.accurest.dsl.internal import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString @CompileStatic +@ToString(includePackage = false, includeFields = true) +@EqualsAndHashCode(includeFields = true) class Body { private final Map body diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy index 11ede5a82e..f1de600e8a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy @@ -1,7 +1,11 @@ package io.coderate.accurest.dsl.internal import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString @CompileStatic +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class DslProperty { final T clientValue diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index 9ee8dfb242..5487b10b53 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -1,5 +1,10 @@ package io.coderate.accurest.dsl.internal +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class Headers { private Map assertionHeaders = [:] diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy index d28bc159c0..3d0f7fec66 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy @@ -1,10 +1,14 @@ package io.coderate.accurest.dsl.internal import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString import groovy.transform.TypeChecked import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure @TypeChecked +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class Request extends Common { DslProperty method @@ -64,6 +68,8 @@ class Request extends Common { } @CompileStatic +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class ServerRequest extends Request { ServerRequest(Request request) { super(request) @@ -71,6 +77,8 @@ class ServerRequest extends Request { } @CompileStatic +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class ClientRequest extends Request { ClientRequest(Request request) { super(request) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index fe15280bde..190ad7b3d9 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -1,11 +1,15 @@ package io.coderate.accurest.dsl.internal import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString import groovy.transform.TypeChecked import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure @TypeChecked +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeFields = true) class Response extends Common { private DslProperty status @@ -52,6 +56,8 @@ class Response extends Common { } @CompileStatic +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class ServerResponse extends Response { ServerResponse(Response request) { super(request) @@ -59,6 +65,8 @@ class ServerResponse extends Response { } @CompileStatic +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class ClientResponse extends Response { ClientResponse(Response request) { super(request) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy index a23cc80c23..71827545dd 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy @@ -1,7 +1,11 @@ package io.coderate.accurest.dsl.internal import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString @CompileStatic +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class ServerDslProperty extends DslProperty { ServerDslProperty(Object clientValue, Object serverValue) { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy index 32dfddf741..8a3b1d1f20 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy @@ -1,7 +1,12 @@ package io.coderate.accurest.dsl.internal + +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString import groovy.transform.TypeChecked @TypeChecked +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) class WithValuePattern { DslProperty equalTo diff --git a/build.gradle b/build.gradle index 33ecf9a2db..a74ec2a59f 100644 --- a/build.gradle +++ b/build.gradle @@ -44,6 +44,12 @@ subprojects { project(':accurest-core') { } +project(':accurest-converters') { + dependencies { + compile project(':accurest-core') + } +} + project(':accurest-gradle-plugin') { dependencies { compile project(':accurest-core') diff --git a/settings.gradle b/settings.gradle index dff32d91dd..148580177b 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,3 @@ -include "accurest-core", "accurest-gradle-plugin" -rootProject.name = "accurest" \ No newline at end of file +include "accurest-core", "accurest-gradle-plugin", 'accurest-converters' +rootProject.name = "accurest" + From 71757e1ec8aa31cd285b86f620dd111e05af0e39 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Fri, 13 Feb 2015 00:11:00 +0100 Subject: [PATCH 044/719] [#5] Minor enhancements --- .../groovy/io/coderate/accurest/dsl/GroovyDsl.groovy | 6 ++---- .../accurest/dsl/internal/ClientDslProperty.groovy | 3 --- .../io/coderate/accurest/dsl/internal/Common.groovy | 3 +-- .../accurest/dsl/internal/DelegateHelper.groovy | 10 ---------- .../coderate/accurest/dsl/internal/DslProperty.groovy | 1 + .../io/coderate/accurest/dsl/internal/Request.groovy | 8 +++----- .../io/coderate/accurest/dsl/internal/Response.groovy | 5 ++--- .../accurest/dsl/internal/ServerDslProperty.groovy | 4 +--- .../accurest/dsl/internal/WithValuePattern.groovy | 2 -- 9 files changed, 10 insertions(+), 32 deletions(-) delete mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DelegateHelper.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy index 1ae6fe4644..4c7ef95839 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -18,15 +18,13 @@ class GroovyDsl { } void request(@DelegatesTo(Request) Closure closure) { - Request request = new Request() - this.request = request + this.request = new Request() closure.delegate = request closure() } void response(@DelegatesTo(Response) Closure closure) { - Response response = new Response() - this.response = response + this.response = new Response() closure.delegate = response closure() } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy index 005d52bc7b..5551688e02 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy @@ -4,9 +4,6 @@ import groovy.transform.CompileStatic @CompileStatic class ClientDslProperty extends DslProperty { - ClientDslProperty(Object clientValue, Object serverValue) { - super(clientValue, serverValue) } - ClientDslProperty(Object singleValue) { super(singleValue) } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy index 7fbd42caea..fc5135af33 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy @@ -39,7 +39,7 @@ class Common { } DslProperty $(ServerDslProperty server, ClientDslProperty client) { - return value(client, server) + return value(server, client) } ClientDslProperty client(Object clientValue) { @@ -49,5 +49,4 @@ class Common { ServerDslProperty server(Object serverValue) { return new ServerDslProperty(serverValue) } - } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DelegateHelper.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DelegateHelper.groovy deleted file mode 100644 index baa8240dcf..0000000000 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DelegateHelper.groovy +++ /dev/null @@ -1,10 +0,0 @@ -package io.coderate.accurest.dsl.internal - -//TODO: There is problem with a trait usage -class DelegateHelper { - - public static void delegateToClosure(@DelegatesTo(T) Closure closure, T delegate) { - closure.delegate = delegate - closure() - } -} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy index 11ede5a82e..485ff61a79 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy @@ -1,4 +1,5 @@ package io.coderate.accurest.dsl.internal + import groovy.transform.CompileStatic @CompileStatic diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy index d28bc159c0..7f41fe41fd 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy @@ -2,8 +2,6 @@ package io.coderate.accurest.dsl.internal import groovy.transform.CompileStatic import groovy.transform.TypeChecked -import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure - @TypeChecked class Request extends Common { @@ -49,9 +47,9 @@ class Request extends Common { } void headers(@DelegatesTo(Headers) Closure closure) { - Headers headers = new Headers() - this.headers = headers - delegateToClosure(closure, headers) + this.headers = new Headers() + closure.delegate = headers + closure() } void urlPath(String urlPath) { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index fe15280bde..928d441dc5 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -3,8 +3,6 @@ package io.coderate.accurest.dsl.internal import groovy.transform.CompileStatic import groovy.transform.TypeChecked -import static io.coderate.accurest.dsl.internal.DelegateHelper.delegateToClosure - @TypeChecked class Response extends Common { @@ -31,7 +29,8 @@ class Response extends Common { void headers(@DelegatesTo(Headers) Closure closure) { this.headers = new Headers() - delegateToClosure(closure, headers) + closure.delegate = headers + closure() } void body(Map body) { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy index a23cc80c23..1e468f10e5 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy @@ -1,12 +1,10 @@ package io.coderate.accurest.dsl.internal + import groovy.transform.CompileStatic @CompileStatic class ServerDslProperty extends DslProperty { - ServerDslProperty(Object clientValue, Object serverValue) { - super(clientValue, serverValue) } - ServerDslProperty(Object singleValue) { super(singleValue) } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy index 32dfddf741..d9fb4cc588 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy @@ -94,6 +94,4 @@ class WithValuePattern { void matchesJsonPath(DslProperty matchesJsonPath) { this.matchesJsonPath = matchesJsonPath } - - } From 6c60e0dc82798e84f21818ea0f1c20256f829b80 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Feb 2015 12:31:14 +0100 Subject: [PATCH 045/719] [#10] Fixed header creation for requests --- .../wiremock/WiremockToDslConverter.groovy | 21 ++++++++++++++++--- .../WiremockToDslConverterSpec.groovy | 21 +++++++++++++++++-- 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index cdd09eee72..4e08b51d5f 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.wiremock + import groovy.json.JsonSlurper import io.coderate.accurest.dsl.GroovyDsl @@ -17,21 +18,35 @@ class WiremockToDslConverter { wiremockRequest.headers.each { def assertion = it.value String headerName = it.key as String - header(headerName)."$assertion.key"(assertion.value) + def entry = assertion.entrySet().first() + header(headerName)."$entry.key"(entry.value) } } : null } response { status wiremockResponse.status ? wiremockResponse.status as Integer : null - wiremockResponse.body ? body ( + wiremockResponse.body ? body( wiremockResponse.body as Map ) : null wiremockResponse.headers ? headers { wiremockResponse.headers.each { - header([(it.key) : it.value]) + header([(it.key): it.value]) } } : null } } } + + static int main(String[] args) { + String rootOfFolderWithStubs = args[0] + new File(rootOfFolderWithStubs).eachFileRecurse { + try { + GroovyDsl stub = fromWiremockStub(it.text) + new File(it.parent, it.name.replaceAll('json', 'groovy')).text + } catch (Exception e) { + System.err.println(e) + } + + } + } } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 6a4534a20b..444c4a3d4f 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -11,7 +11,18 @@ class WiremockToDslConverterSpec extends Specification { { "request": { "method": "GET", - "urlPattern": "/[0-9]{2}" + "urlPattern": "/[0-9]{2}", + "headers" : { + "Accept": { + "matches": "text/.*" + }, + "etag": { + "doesNotMatch": "abcd.*" + }, + "X-Custom-Header": { + "contains": "2134" + } + } }, "response": { "status": 200, @@ -22,7 +33,7 @@ class WiremockToDslConverterSpec extends Specification { "created" : "2014-02-02 12:23:43" }, "headers": { - "Content-Type": "text/plain" + "Content-Type": "text/plain", } } } @@ -32,6 +43,11 @@ class WiremockToDslConverterSpec extends Specification { request { method 'GET' urlPattern '/[0-9]{2}' + headers { + header('Accept').matches('text/.*') + header('etag').doesNotMatch('abcd.*') + header('X-Custom-Header').contains('2134') + } } response { status 200 @@ -43,6 +59,7 @@ class WiremockToDslConverterSpec extends Specification { ) headers { header 'Content-Type': 'text/plain' + } } } From a6b1cef2e88b28f4e987fe96da877fc9f5f18426 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Feb 2015 15:18:28 +0100 Subject: [PATCH 046/719] [#10] Working Wiremock To Dsl Converter --- .../wiremock/WiremockToDslConverter.groovy | 77 +++++++++++++------ .../WiremockToDslConverterSpec.groovy | 57 +++++++------- .../dsl/BaseWiremockStubStrategy.groovy | 2 +- .../io/coderate/accurest/dsl/GroovyDsl.groovy | 3 +- .../accurest/dsl/internal/Headers.groovy | 3 +- 5 files changed, 88 insertions(+), 54 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index 4e08b51d5f..f7d2311d75 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -4,37 +4,64 @@ import groovy.json.JsonSlurper import io.coderate.accurest.dsl.GroovyDsl class WiremockToDslConverter { - static GroovyDsl fromWiremockStub(String wiremockStringStub) { + static String fromWiremockStub(String wiremockStringStub) { + return new WiremockToDslConverter().convertFromWiremockStub(wiremockStringStub) + } + + private String convertFromWiremockStub(String wiremockStringStub) { Object wiremockStub = new JsonSlurper().parseText(wiremockStringStub) - def wiremockRequest = wiremockStub.request - def wiremockResponse = wiremockStub.response - return GroovyDsl.make { + def request = wiremockStub.request + def response = wiremockStub.response + return """\ request { - wiremockRequest.method ? method(wiremockRequest.method as String) : null - wiremockRequest.url ? url(wiremockRequest.url as String) : null - wiremockRequest.urlPattern ? urlPattern(wiremockRequest.urlPattern as String) : null - wiremockRequest.urlPath ? urlPath(wiremockRequest.urlPath as String) : null - wiremockRequest.headers ? headers { - wiremockRequest.headers.each { - def assertion = it.value - String headerName = it.key as String - def entry = assertion.entrySet().first() - header(headerName)."$entry.key"(entry.value) - } - } : null + ${request.method ? "method '$request.method'" : ""} + ${request.url ? "url '$request.url'" : ""} + ${request.urlPattern ? "urlPattern '$request.urlPattern'" : ""} + ${request.urlPath ? "urlPath '$request.urlPath'" : ""} + ${request.headers ? """headers { + ${request.headers.collect { + def assertion = it.value + String headerName = it.key as String + def entry = assertion.entrySet().first() + """header('$headerName').$entry.key('$entry.value')\n""" + }.join('') + } + } + """ : ""} } response { - status wiremockResponse.status ? wiremockResponse.status as Integer : null - wiremockResponse.body ? body( - wiremockResponse.body as Map - ) : null - wiremockResponse.headers ? headers { - wiremockResponse.headers.each { - header([(it.key): it.value]) + ${response.status ? "status $response.status" : ""} + ${response.body ? "body( ${response.body.entrySet().collectAll(withQuotedStringElements()).inject([:], appendToMap())})" : ""} + ${response.headers ? """headers { + ${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')} } - } : null + """ : ""} } - } + """ + } + + private Closure withQuotedStringElements() { + return { [(it.key): convert(it.value)] } + } + + private Closure appendToMap() { + return { acc, el -> acc << el } + } + + private Object convert(Object element) { + return element + } + + private Object convert(String element) { + return """ "$element" """ + } + + private Object convert(List element) { + return element.collect { convert(it) } + } + + private Object convert(Map element) { + return element.collectEntries { [(it.key) : convert(it.value)] } } static int main(String[] args) { diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 444c4a3d4f..099d0fb621 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -7,7 +7,7 @@ class WiremockToDslConverterSpec extends Specification { def 'should produce a Groovy DSL from Wiremock stub'() { given: - String wiremockStub = ''' + String wiremockStub = '''\ { "request": { "method": "GET", @@ -27,7 +27,9 @@ class WiremockToDslConverterSpec extends Specification { "response": { "status": 200, "body": { - "id": "123", + "id": { + "value": "132" + }, "surname": "Kowalsky", "name": "Jan", "created" : "2014-02-02 12:23:43" @@ -40,32 +42,35 @@ class WiremockToDslConverterSpec extends Specification { ''' and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { - request { - method 'GET' - urlPattern '/[0-9]{2}' - headers { - header('Accept').matches('text/.*') - header('etag').doesNotMatch('abcd.*') - header('X-Custom-Header').contains('2134') - } - } - response { - status 200 - body ( - id : '123', - surname : 'Kowalsky', - name: 'Jan', - created : '2014-02-02 12:23:43' - ) - headers { - header 'Content-Type': 'text/plain' + request { + method 'GET' + urlPattern '/[0-9]{2}' + headers { + header('Accept').matches('text/.*') + header('etag').doesNotMatch('abcd.*') + header('X-Custom-Header').contains('2134') + } + } + response { + status 200 + body ( + id : [value: '132'], + surname : 'Kowalsky', + name: 'Jan', + created : '2014-02-02 12:23:43' + ) + headers { + header 'Content-Type': 'text/plain' - } - } - } + } + } + } when: - GroovyDsl groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) then: - groovyDsl == expectedGroovyDsl + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index 3925ada9f3..e02c2a62ce 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -12,7 +12,7 @@ abstract class BaseWiremockStubStrategy { } return withAssertionHeaders(headers) { Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] - } << headers?.valueHeaders() + } << headers.valueHeaders() } protected Map buildServerHeadersSection(Headers headers) { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy index 9ea3348dbd..225d5dce52 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -8,7 +8,7 @@ import io.coderate.accurest.dsl.internal.Response @TypeChecked @EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) +@ToString(includeFields = true, includePackage = false) class GroovyDsl { Request request @@ -32,4 +32,5 @@ class GroovyDsl { closure.delegate = response closure() } + } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index 5487b10b53..f2b5a5649b 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -4,7 +4,7 @@ import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true) class Headers { private Map assertionHeaders = [:] @@ -28,4 +28,5 @@ class Headers { Set> assertionEntries() { return Collections.unmodifiableSet(assertionHeaders.entrySet()) } + } From e0f72ab6ab5c413d5294e5a2ab9fd7cd32d059e1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Feb 2015 17:34:13 +0100 Subject: [PATCH 047/719] [#10] Working Wiremock To Dsl Converter - fixed character escaping and other minor bugs Still we have to know how to escape special characters that JSON doesn't recognize --- .../wiremock/WiremockToDslConverter.groovy | 90 ++++++-- .../WiremockToDslConverterSpec.groovy | 215 ++++++++++++++++++ .../accurest/dsl/internal/Body.groovy | 33 ++- .../accurest/dsl/internal/Common.groovy | 18 ++ .../accurest/dsl/internal/Response.groovy | 8 + 5 files changed, 337 insertions(+), 27 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index f7d2311d75..36cde449f6 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,7 +1,7 @@ package io.codearte.accurest.wiremock +import groovy.io.FileType import groovy.json.JsonSlurper -import io.coderate.accurest.dsl.GroovyDsl class WiremockToDslConverter { static String fromWiremockStub(String wiremockStringStub) { @@ -14,24 +14,24 @@ class WiremockToDslConverter { def response = wiremockStub.response return """\ request { - ${request.method ? "method '$request.method'" : ""} - ${request.url ? "url '$request.url'" : ""} - ${request.urlPattern ? "urlPattern '$request.urlPattern'" : ""} - ${request.urlPath ? "urlPath '$request.urlPath'" : ""} + ${request.method ? "method '''$request.method'''" : ""} + ${request.url ? "url '''$request.url'''" : ""} + ${request.urlPattern ? "urlPattern '''$request.urlPattern'''" : ""} + ${request.urlPath ? "urlPath '''$request.urlPath'''" : ""} ${request.headers ? """headers { ${request.headers.collect { - def assertion = it.value - String headerName = it.key as String - def entry = assertion.entrySet().first() - """header('$headerName').$entry.key('$entry.value')\n""" - }.join('') + def assertion = it.value + String headerName = it.key as String + def entry = assertion.entrySet().first() + """header('''$headerName''').$entry.key('''$entry.value''')\n""" + }.join('') } } """ : ""} } response { ${response.status ? "status $response.status" : ""} - ${response.body ? "body( ${response.body.entrySet().collectAll(withQuotedStringElements()).inject([:], appendToMap())})" : ""} + ${response.body ? "body( ${buildBody(response.body)})" : ""} ${response.headers ? """headers { ${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')} } @@ -40,12 +40,42 @@ class WiremockToDslConverter { """ } - private Closure withQuotedStringElements() { - return { [(it.key): convert(it.value)] } + private Object buildBody(Map responseBody) { + return responseBody.entrySet().collectAll(withQuotedMapStringElements()).inject([:], appendToIterable()) } - private Closure appendToMap() { - return { acc, el -> acc << el } + private Object buildBody(List responseBody) { + return responseBody.collectAll(withQuotedStringElements()).inject([], appendToIterable()) + } + + private Object buildBody(Integer responseBody) { + return responseBody + } + + private Object buildBody(String responseBody) { + try { + return buildBody(new JsonSlurper().parseText(responseBody)) + } catch (Exception e) { + return """'''$responseBody'''""" + } + } + + private Closure withQuotedMapStringElements() { + return { + [(it.key): convert(it.value)] + } + } + + private Closure withQuotedStringElements() { + return { + convert(it) + } + } + + private Closure appendToIterable() { + return { + acc, el -> acc << el + } } private Object convert(Object element) { @@ -53,23 +83,39 @@ class WiremockToDslConverter { } private Object convert(String element) { - return """ "$element" """ + return quoteString(element) + } + + private String quoteString(String element) { + if (element =~ /^".*"$/) { + return element + } + return """'''$element'''""" } private Object convert(List element) { - return element.collect { convert(it) } + return element.collect { + convert(it) + } } private Object convert(Map element) { - return element.collectEntries { [(it.key) : convert(it.value)] } + return element.collectEntries { + [(it.key) : convert(it.value)] + } } - static int main(String[] args) { + static void main(String[] args) { String rootOfFolderWithStubs = args[0] - new File(rootOfFolderWithStubs).eachFileRecurse { + new File(rootOfFolderWithStubs).eachFileRecurse(FileType.FILES) { try { - GroovyDsl stub = fromWiremockStub(it.text) - new File(it.parent, it.name.replaceAll('json', 'groovy')).text + if(!it.name.endsWith('json')) { + return + } + String wiremockStub = fromWiremockStub(it.text) + File newGroovyFile = new File(it.parent, it.name.replaceAll('json', 'groovy')) + println("Creating new groovy file [$newGroovyFile.path]") + newGroovyFile.text = wiremockStub } catch (Exception e) { System.err.println(e) } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 099d0fb621..8128727d49 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -73,4 +73,219 @@ class WiremockToDslConverterSpec extends Specification { $groovyDsl }""") == expectedGroovyDsl } + + + def 'should convert Wiremock stub with body containing simple JSON'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "DELETE", + "urlPattern": "/credit-card-verification-data/[0-9]+", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8" + } + } + }, + "response": { + "status": 200, + "body": "{\"status\": \"OK\"}", + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'DELETE' + urlPattern '/credit-card-verification-data/[0-9]+' + headers { + header('Content-Type').equalTo('application/vnd.mymoid-adapter.v2+json; charset=UTF-8') + } + } + response { + status 200 + body ( + status : "OK" + ) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + def 'should convert Wiremock stub with body containing integer'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/count", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body": 200, + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/count' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ( 200 ) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + def 'should convert Wiremock stub with body as a list'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/count", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body": [ + {"a":1, "c":"3"}, + "b", + "a" + ], + "headers": { + "Content-Type": "application/json" + } + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/count' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ([ + [a: 1, c: '3'], + 'b', + 'c' + ]) + headers { + header 'Content-Type': 'application/json' + + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + + + def 'should convert Wiremock stub with body containing a nested list'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/charge/search?pageNumber=0&size=2147483647", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } + }, + "response": { + "status": 200, + "body":"[{\\"amount\\":1.01,\\"name\\":\\"Name\\",\\"info\\":{\\"title\\":\\"title1\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null},{\\"amount\\":2.01,\\"name\\":\\"Name2\\",\\"info\\":{\\"title\\":\\"title2\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null}]" + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/search?pageNumber=0&size=2147483647' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body ([ + [amount:1.01, + name: "Name" , + info: [title:"title1", + payload:null], + booleanvalue:true, + user:null], + [amount:2.01, + name: "Name2" , + info: [title:"title2", + payload:null], + booleanvalue:true, + user:null] + ]) + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") == expectedGroovyDsl + } + } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index e3b75c9eb4..1a3b331bb3 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -1,14 +1,15 @@ package io.coderate.accurest.dsl.internal -import groovy.transform.CompileStatic + import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -@CompileStatic @ToString(includePackage = false, includeFields = true) @EqualsAndHashCode(includeFields = true) class Body { - private final Map body + private Map body + private DslProperty bodyAsValue + private List bodyAsList Body() { this.body = [:] @@ -18,13 +19,35 @@ class Body { this.body = body } - Map forClientSide() { + Body(List bodyAsList) { + this.bodyAsList = bodyAsList + } + + Body(Object bodyAsValue) { + this.bodyAsValue = new DslProperty(bodyAsValue) + } + + Body(DslProperty bodyAsValue) { + this.bodyAsValue = bodyAsValue + } + + Object forClientSide() { + if(bodyAsValue) { + return bodyAsValue.clientValue + } else if(bodyAsList) { + bodyAsList.collect { it.clientValue } + } return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.clientValue] } as Map } - Map forServerSide() { + Object forServerSide() { + if(bodyAsValue) { + return bodyAsValue.serverValue + } else if(bodyAsList) { + bodyAsList.collect { it.serverValue } + } return body.collectEntries { Map.Entry entry -> [(entry.key) : entry.value.serverValue] } as Map diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy index fc5135af33..9afb7e115c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy @@ -18,10 +18,28 @@ class Common { } as Map } + List convertObjectsToDslProperties(List body) { + return body.collect { + Object element -> toDslProperty(element) + } as List + } + DslProperty toDslProperty(Object property) { return new DslProperty(property) } + DslProperty toDslProperty(Map property) { + return new DslProperty(property.collectEntries { + [(it.key) : toDslProperty(it.value)] + }) + } + + DslProperty toDslProperty(List property) { + return new DslProperty(property.collect { + toDslProperty(it) + }) + } + DslProperty toDslProperty(DslProperty property) { return property } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index 660863c1b0..46827b9875 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -41,6 +41,14 @@ class Response extends Common { this.body = new Body(convertObjectsToDslProperties(body)) } + void body(List body) { + this.body = new Body(convertObjectsToDslProperties(body)) + } + + void body(Object bodyAsValue) { + this.body = new Body(bodyAsValue) + } + Body getBody() { return body } From 103c2d5cbfb0f2ecaa418ae8d16bcea68c3ac8ac Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Sun, 15 Feb 2015 22:41:48 +0100 Subject: [PATCH 048/719] Add test class suffix generation No tests due to broken windows theory... --- .../main/groovy/io/coderate/accurest/TestGenerator.groovy | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 2042f25461..e13a2ea523 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -51,7 +51,8 @@ class TestGenerator { if (containsStubs(it)) { def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(packageName)) Files.createDirectories(testBaseDir) - def classPath = Paths.get(testBaseDir.toString(), capitalize(it.name) + getTestClassExtension()).toAbsolutePath() + def classPath = Paths.get(testBaseDir.toString(), capitalize(it.name) + getTestClassSuffix() + getTestClassExtension()) + .toAbsolutePath() def classBytes = buildClass(it, packageName).bytes Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) counter.incrementAndGet() @@ -60,6 +61,10 @@ class TestGenerator { } } + private String getTestClassSuffix() { + return configProperties.targetFramework == TestFramework.SPOCK ? 'Spec' : 'Test' + } + private String getTestClassExtension() { return configProperties.targetFramework == TestFramework.SPOCK ? '.groovy' : '.java' } From ca4cceaa5b4b877eda6684605e61fb4b14f7fe06 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 16 Feb 2015 10:24:06 +0100 Subject: [PATCH 049/719] [#5] Added possibility of providing a GString as Body with Client / Server values --- .../accurest/dsl/internal/Body.groovy | 18 ++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 96 +++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index 1a3b331bb3..502e18a2ca 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -1,7 +1,9 @@ package io.coderate.accurest.dsl.internal +import groovy.json.JsonSlurper import groovy.transform.EqualsAndHashCode import groovy.transform.ToString +import org.codehaus.groovy.runtime.GStringImpl @ToString(includePackage = false, includeFields = true) @EqualsAndHashCode(includeFields = true) @@ -27,6 +29,22 @@ class Body { this.bodyAsValue = new DslProperty(bodyAsValue) } + Body(GString bodyAsValue) { + this.bodyAsValue = new DslProperty(getClientValue(bodyAsValue), getServerValue(bodyAsValue)) + } + + private Map getClientValue(GString bodyAsValue) { + GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) + Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } as Object[] + return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString()) + } + + private Map getServerValue(GString bodyAsValue) { + GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) + Object[] serverValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.serverValue: it } as Object[] + return new JsonSlurper().parseText(new GStringImpl(serverValues, clientGString.strings).toString()) + } + Body(DslProperty bodyAsValue) { this.bodyAsValue = bodyAsValue } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy index 3ee9cd7f11..9740c6f40e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -60,6 +60,102 @@ class WiremockGroovyDslSpec extends Specification { ''') } + def 'should convert groovy dsl stub with Body as String to wiremock stub for the client side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body ("""\ + { + "id": "${value(client('123'),server('321'))}", + "surname": "${value(client('Kowalsky'),server('Lewandowski'))}", + "name": "Jan", + "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}" + }, + "response": { + "status": 200, + "body": { + "id": "123", + "surname": "Kowalsky", + "name": "Jan", + "created" : "2014-02-02 12:23:43" + }, + "headers": { + "Content-Type": "text/plain" + } + } +} +''') + } + + def 'should convert groovy dsl stub with Body as String to wiremock stub for the server side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body ("""\ + { + "id": "${value(client('123'),server('321'))}", + "surname": "${value(client('Kowalsky'),server('Lewandowski'))}", + "name": "Jan", + "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "GET", + "urlPattern": "/12" + }, + "response": { + "status": 200, + "body": { + "id": "321", + "surname": "Lewandowski", + "name": "Jan", + "created" : "2999-09-09 01:23:45" + }, + "headers": { + "Content-Type": "text/plain" + } + } +} +''') + } + def 'should convert groovy dsl stub to wiremock stub for the server side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From 36280bab7d301a3d87b60dda9fa343780c94c86b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 16 Feb 2015 11:32:05 +0100 Subject: [PATCH 050/719] [#10] Added conversion from Wiremock Stub to Groovy DSL --- .../wiremock/WiremockToDslConverter.groovy | 33 +++++++++---- .../WiremockToDslConverterSpec.groovy | 46 +++++++++++-------- build.gradle | 1 + 3 files changed, 51 insertions(+), 29 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index 36cde449f6..101260ac3a 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,7 +1,10 @@ package io.codearte.accurest.wiremock - import groovy.io.FileType +import groovy.json.JsonOutput import groovy.json.JsonSlurper +import groovy.xml.XmlUtil + +import static org.apache.commons.lang3.StringEscapeUtils.escapeJava class WiremockToDslConverter { static String fromWiremockStub(String wiremockStringStub) { @@ -14,16 +17,16 @@ class WiremockToDslConverter { def response = wiremockStub.response return """\ request { - ${request.method ? "method '''$request.method'''" : ""} - ${request.url ? "url '''$request.url'''" : ""} - ${request.urlPattern ? "urlPattern '''$request.urlPattern'''" : ""} - ${request.urlPath ? "urlPath '''$request.urlPath'''" : ""} + ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} + ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} + ${request.urlPattern ? "urlPattern \"\"\"${escapeJava(request.urlPattern)}\"\"\"" : ""} + ${request.urlPath ? "urlPath \"\"\"$request.urlPath\"\"\"" : ""} ${request.headers ? """headers { ${request.headers.collect { def assertion = it.value String headerName = it.key as String def entry = assertion.entrySet().first() - """header('''$headerName''').$entry.key('''$entry.value''')\n""" + """header(\"\"\"$headerName\"\"\").$entry.key(\"\"\"${escapeJava(entry.value)}\"\"\")\n""" }.join('') } } @@ -54,12 +57,22 @@ class WiremockToDslConverter { private Object buildBody(String responseBody) { try { - return buildBody(new JsonSlurper().parseText(responseBody)) - } catch (Exception e) { - return """'''$responseBody'''""" + def json = new JsonSlurper().parseText(responseBody) + return wrapWithMultilineGString(JsonOutput.prettyPrint(responseBody)) + } catch (Exception jsonException) { + try { + def xml = new XmlSlurper().parseText(responseBody) + return wrapWithMultilineGString(XmlUtil.serialize(responseBody)) + } catch (Exception xmlException) { + return wrapWithMultilineGString(responseBody) + } } } + private String wrapWithMultilineGString(String string) { + return """\"\"\"$string\"\"\"""" + } + private Closure withQuotedMapStringElements() { return { [(it.key): convert(it.value)] @@ -90,7 +103,7 @@ class WiremockToDslConverter { if (element =~ /^".*"$/) { return element } - return """'''$element'''""" + return """\"\"\"${escapeJava(element)}\"\"\"""" } private Object convert(List element) { diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 8128727d49..aac2bbb12f 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -90,7 +90,7 @@ class WiremockToDslConverterSpec extends Specification { }, "response": { "status": 200, - "body": "{\"status\": \"OK\"}", + "body": "{\\"status\\": \\"OK\\"}", "headers": { "Content-Type": "application/json" } @@ -108,9 +108,9 @@ class WiremockToDslConverterSpec extends Specification { } response { status 200 - body ( - status : "OK" - ) + body ("""{ + "status": "OK" +}""") headers { header 'Content-Type': 'application/json' @@ -215,7 +215,7 @@ class WiremockToDslConverterSpec extends Specification { body ([ [a: 1, c: '3'], 'b', - 'c' + 'a' ]) headers { header 'Content-Type': 'application/json' @@ -263,20 +263,28 @@ class WiremockToDslConverterSpec extends Specification { } response { status 200 - body ([ - [amount:1.01, - name: "Name" , - info: [title:"title1", - payload:null], - booleanvalue:true, - user:null], - [amount:2.01, - name: "Name2" , - info: [title:"title2", - payload:null], - booleanvalue:true, - user:null] - ]) + body ("""[ + { + "amount": 1.01, + "name": "Name", + "info": { + "title": "title1", + "payload": null + }, + "booleanvalue": true, + "user": null + }, + { + "amount": 2.01, + "name": "Name2", + "info": { + "title": "title2", + "payload": null + }, + "booleanvalue": true, + "user": null + } +]""") } } when: diff --git a/build.gradle b/build.gradle index a74ec2a59f..8a123cd670 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,7 @@ project(':accurest-core') { project(':accurest-converters') { dependencies { compile project(':accurest-core') + compile 'org.apache.commons:commons-lang3:3.3.2' } } From be79983892f8e271ffac2649f091f6d78d81798c Mon Sep 17 00:00:00 2001 From: "konrad.dobrzynski" Date: Thu, 19 Feb 2015 11:58:46 +0100 Subject: [PATCH 051/719] TravisCI added --- .travis.yml | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..7a0dff7140 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: java + +jdk: + - oraclejdk7 + - openjdk7 + - oraclejdk8 + +install: ./gradlew assemble +script: ./gradlew check --stacktrace --info --continue \ No newline at end of file From 88dc228a4100ad68b4ec2959cd2eb4df8e0fc869 Mon Sep 17 00:00:00 2001 From: "konrad.dobrzynski" Date: Mon, 16 Feb 2015 11:46:36 +0100 Subject: [PATCH 052/719] [#15] Added exclusion for folders and files --- .../io/coderate/accurest/FileSaver.groovy | 41 +++++ .../accurest/SingleTestGenerator.groovy | 60 +++++++ .../io/coderate/accurest/TestGenerator.groovy | 156 ++++++------------ .../config/AccurestConfigProperties.groovy | 1 + .../io/codearte/accurest/MainTest.groovy | 15 ++ .../accurest/TestGeneratorSpec.groovy | 51 ++++++ .../directory/with/stubs/different/diff.json} | 0 .../with/stubs/other/different/diff.json | 0 .../directory/with/stubs/other/other.json | 0 .../directory/with/stubs/other/sample.json | 0 .../with/stubs/stubsRepositoryIndicator | 0 accurest-core/src/test/resources/main.json | 0 build.gradle | 10 ++ 13 files changed, 232 insertions(+), 102 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy rename accurest-core/src/{main/resources/stubs/some.json => test/resources/directory/with/stubs/different/diff.json} (100%) create mode 100644 accurest-core/src/test/resources/directory/with/stubs/other/different/diff.json create mode 100644 accurest-core/src/test/resources/directory/with/stubs/other/other.json create mode 100644 accurest-core/src/test/resources/directory/with/stubs/other/sample.json create mode 100644 accurest-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator create mode 100644 accurest-core/src/test/resources/main.json diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy new file mode 100644 index 0000000000..8d76595c4a --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy @@ -0,0 +1,41 @@ +package io.coderate.accurest + +import groovy.transform.CompileStatic +import io.coderate.accurest.config.TestFramework +import io.coderate.accurest.util.NamesUtil + +import java.nio.file.Files +import java.nio.file.Paths +import java.nio.file.StandardOpenOption + +import static io.coderate.accurest.util.NamesUtil.capitalize + +@CompileStatic +class FileSaver { + + + String targetDirectory + TestFramework framework + + FileSaver(String targetDirectory, TestFramework framework) { + this.targetDirectory = targetDirectory + this.framework = framework + } + + void saveClassFile(String fileName, String packageName, byte[] classBytes) { + + def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(packageName)) + Files.createDirectories(testBaseDir) + def classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + getTestClassSuffix() + getTestClassExtension()) + .toAbsolutePath() + Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) + } + + private String getTestClassSuffix() { + return framework == TestFramework.SPOCK ? 'Spec' : 'Test' + } + + private String getTestClassExtension() { + return framework == TestFramework.SPOCK ? '.groovy' : '.java' + } +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy new file mode 100644 index 0000000000..42b35134cd --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy @@ -0,0 +1,60 @@ +package io.coderate.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 static io.coderate.accurest.builder.ClassBuilder.createClass +import static io.coderate.accurest.builder.MethodBuilder.createTestMethod +import static io.coderate.accurest.util.NamesUtil.capitalize + +class SingleTestGenerator { + private final AccurestConfigProperties configProperties + + SingleTestGenerator(AccurestConfigProperties configProperties) { + this.configProperties = configProperties + } + + @PackageScope + String buildClass(List listOfFiles, String className, String classPackage) { + ClassBuilder clazz = createClass(capitalize(className), classPackage, + configProperties) + + if (configProperties.imports) { + configProperties.imports.each { + clazz.addImport(it) + } + } + + if (configProperties.staticImports) { + configProperties.staticImports.each { + clazz.addStaticImport(it) + } + } + + 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) { + clazz.addImport('org.junit.Test') + } else { + clazz.addImport('groovy.json.JsonSlurper') + } + + if (configProperties.ruleClassForTests) { + clazz.addImport('org.junit.Rule') + .addRule(configProperties.ruleClassForTests) + } + + listOfFiles.each { + clazz.addMethod(createTestMethod(it, configProperties.targetFramework)) + } + return clazz.build() + } + +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index e13a2ea523..2358df8362 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -1,124 +1,76 @@ package io.coderate.accurest -import io.coderate.accurest.builder.ClassBuilder +import groovy.transform.PackageScope import io.coderate.accurest.config.AccurestConfigProperties -import io.coderate.accurest.config.TestFramework -import io.coderate.accurest.config.TestMode -import io.coderate.accurest.util.NamesUtil +import org.codehaus.plexus.util.DirectoryScanner -import java.nio.file.Files -import java.nio.file.Path -import java.nio.file.Paths -import java.nio.file.StandardOpenOption import java.util.concurrent.atomic.AtomicInteger -import static ClassBuilder.createClass -import static io.coderate.accurest.builder.MethodBuilder.createTestMethod import static io.coderate.accurest.util.NamesUtil.afterLast -import static io.coderate.accurest.util.NamesUtil.capitalize /** * @author Jakub Kubrynski */ class TestGenerator { - private final String targetDirectory - private final AccurestConfigProperties configProperties - private final String stubsBaseDirectory - private AtomicInteger counter = new AtomicInteger() + private final AccurestConfigProperties configProperties + private final String stubsBaseDirectory + private AtomicInteger counter = new AtomicInteger() + private SingleTestGenerator generator + private FileSaver saver + private DirectoryScanner directoryScanner - TestGenerator(AccurestConfigProperties accurestConfigProperties) { - this.configProperties = accurestConfigProperties - this.targetDirectory = accurestConfigProperties.generatedTestSourcesDir - File stubsResource = new File(accurestConfigProperties.stubsBaseDirectory) - if (stubsResource == null) { - throw new AccurestException("Stubs directory not found under " + accurestConfigProperties.stubsBaseDirectory) - } - this.stubsBaseDirectory = stubsResource.path - } + TestGenerator(AccurestConfigProperties accurestConfigProperties) { + this(accurestConfigProperties, new SingleTestGenerator(accurestConfigProperties), new FileSaver(accurestConfigProperties.generatedTestSourcesDir, accurestConfigProperties.targetFramework)) + } - public int generate() { - generateTestClasses(new File(stubsBaseDirectory), configProperties.basePackageForTests) - return counter.get() - } + TestGenerator(AccurestConfigProperties configProperties, SingleTestGenerator generator, FileSaver saver) { + this.configProperties = configProperties + File stubsResource = new File(configProperties.stubsBaseDirectory) + if (stubsResource == null) { + throw new AccurestException("Stubs directory not found under " + configProperties.stubsBaseDirectory) + } + this.stubsBaseDirectory = stubsResource.path + this.generator = generator + this.saver = saver + this.directoryScanner = new DirectoryScanner() + directoryScanner.setExcludes(configProperties.getIgnoredFiles() as String[]) + directoryScanner.setBasedir(configProperties.stubsBaseDirectory) + } - protected void generateTestClasses(File baseFile, String packageName) { - List files = baseFile.listFiles() + int generate() { + generateTestClasses(configProperties.basePackageForTests) + return counter.get() + } - files.each { - if (it.isDirectory()) { - generateTestClasses(it, "$packageName.$it.name") - if (containsStubs(it)) { - def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(packageName)) - Files.createDirectories(testBaseDir) - def classPath = Paths.get(testBaseDir.toString(), capitalize(it.name) + getTestClassSuffix() + getTestClassExtension()) - .toAbsolutePath() - def classBytes = buildClass(it, packageName).bytes - Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) - counter.incrementAndGet() - } - } - } - } + @PackageScope + void generateTestClasses(final String packageName) { + directoryScanner.scan() + directoryScanner.getIncludedDirectories() + .each { String includedDirectoryRelativePath -> + processIncludedDirectory(includedDirectoryRelativePath, packageName) - private String getTestClassSuffix() { - return configProperties.targetFramework == TestFramework.SPOCK ? 'Spec' : 'Test' - } + } + } - private String getTestClassExtension() { - return configProperties.targetFramework == TestFramework.SPOCK ? '.groovy' : '.java' - } + private void processIncludedDirectory( + final String includedDirectoryRelativePath, final String packageNameForClass) { + if (!includedDirectoryRelativePath.isEmpty()) { + List filesToClass = directoryScanner.includedFiles. + grep { String includedFile -> + return includedFile.matches(includedDirectoryRelativePath + File.separator + "[A-Za-z0-9]*\\.json") + } + .collect { + return new File(stubsBaseDirectory + File.separator + it) + } + if (filesToClass.size()) { + def className = afterLast(includedDirectoryRelativePath, File.separator) + def classBytes = generator.buildClass(filesToClass, className, packageNameForClass).bytes + saver.saveClassFile(className, packageNameForClass, classBytes) + counter.incrementAndGet() + } + } + } - boolean containsStubs(File file) { - return file.list(new FilenameFilter() { - @Override - boolean accept(File dir, String name) { - return "json".equalsIgnoreCase(NamesUtil.afterLastDot(name)) - } - }).size() > 0 - } - private String buildClass(File directory, String classPackage) { - ClassBuilder clazz = createClass(capitalize(afterLast(directory.path, '/')), classPackage, configProperties) - - if (configProperties.imports) { - configProperties.imports.each { - clazz.addImport(it) - } - } - - if (configProperties.staticImports) { - configProperties.staticImports.each { - clazz.addStaticImport(it) - } - } - - 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) { - clazz.addImport('org.junit.Test') - } else { - clazz.addImport('groovy.json.JsonSlurper') - } - - if (configProperties.ruleClassForTests) { - clazz.addImport('org.junit.Rule') - .addRule(configProperties.ruleClassForTests) - } - - directory.listFiles().grep({ File file -> !file.isDirectory()}).each { - clazz.addMethod(createTestMethod(it, configProperties.targetFramework)) - } - return clazz.build() - } - - public static void main(String[] args) { - AccurestConfigProperties properties = new AccurestConfigProperties(stubsBaseDirectory: '/home/devel/projects/codearte/accurest/accurest-core/src/main/resources/stubs', - targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test']) - new TestGenerator(properties).generate() - } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy index e77d4bb9a0..794c6f9635 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy @@ -10,6 +10,7 @@ class AccurestConfigProperties { String basePackageForTests = 'io.codearte.accurest.tests' String baseClassForTests String ruleClassForTests + List ignoredFiles = [] String generatedTestSourcesDir = 'build/generated-sources/accurest' String[] imports = [] String[] staticImports = [] diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy new file mode 100644 index 0000000000..76c4256cb5 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy @@ -0,0 +1,15 @@ +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 + +class MainTest { + public static void main(String[] args) { + AccurestConfigProperties properties = new AccurestConfigProperties(stubsBaseDirectory: '/home/devel/workspace/accurest/accurest-core/src/main/resources/stubs', + targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', + staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], ignoredFiles: ["**/different/some.json", "**/other"]) + println new TestGenerator(properties).generate() + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy new file mode 100644 index 0000000000..279af858de --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy @@ -0,0 +1,51 @@ +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 spock.lang.Specification + +class TestGeneratorSpec extends Specification { + + private SingleTestGenerator classGenerator = Mock(SingleTestGenerator) + + def "should find all .json files and generate 3 classes for them"() { + given: + File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) + AccurestConfigProperties properties = new AccurestConfigProperties() + properties.stubsBaseDirectory = resource.parentFile.path + TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) + when: + testGenerator.generateTestClasses("com.ofg") + then: + 3 * classGenerator.buildClass(_, _, _) >> "qwerty" + } + + def "should filter other directory"() { + given: + File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) + AccurestConfigProperties properties = new AccurestConfigProperties() + properties.ignoredFiles << "**/other/**" + properties.stubsBaseDirectory = resource.parentFile.path + TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) + when: + testGenerator.generateTestClasses("com.ofg") + then: + 1 * classGenerator.buildClass(_, 'different', _) >> "qwerty" + } + + def "should ignore file"() { + given: + File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) + AccurestConfigProperties properties = new AccurestConfigProperties() + properties.ignoredFiles << "**/other.json" + properties.stubsBaseDirectory = resource.parentFile.path + TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) + classGenerator.buildClass(_, _, _) >> "sample" + when: + testGenerator.generateTestClasses("com.ofg") + then: + 1 * classGenerator.buildClass({ it.size() == 1 }, 'other', _) >> "sample.json" + } +} diff --git a/accurest-core/src/main/resources/stubs/some.json b/accurest-core/src/test/resources/directory/with/stubs/different/diff.json similarity index 100% rename from accurest-core/src/main/resources/stubs/some.json rename to accurest-core/src/test/resources/directory/with/stubs/different/diff.json diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/different/diff.json b/accurest-core/src/test/resources/directory/with/stubs/other/different/diff.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/other.json b/accurest-core/src/test/resources/directory/with/stubs/other/other.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/sample.json b/accurest-core/src/test/resources/directory/with/stubs/other/sample.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator b/accurest-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-core/src/test/resources/main.json b/accurest-core/src/test/resources/main.json new file mode 100644 index 0000000000..e69de29bb2 diff --git a/build.gradle b/build.gradle index 8a123cd670..29b11d04f5 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,10 @@ subprojects { mavenCentral() } + //Dependencies in all subprojects - http://solidsoft.wordpress.com/2014/11/13/gradle-tricks-display-dependencies-for-all-subprojects-in-multi-project-build/ + task allDeps(type: DependencyReportTask) {} + task allInsight(type: DependencyInsightReportTask) {} + dependencies { compile localGroovy() testCompile('org.spockframework:spock-core:0.7-groovy-2.0') { @@ -42,6 +46,12 @@ subprojects { } project(':accurest-core') { + dependencies { + compile 'org.codehaus.plexus:plexus-utils:3.0.21' + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + + } } project(':accurest-converters') { From 468547c561104f941d91b9d569b725a06a101ec8 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Thu, 19 Feb 2015 10:10:01 +0100 Subject: [PATCH 053/719] [#22] Dsl to Wiremock converters --- .../DslToWiremockClientConverter.groovy | 11 +++++ .../wiremock/DslToWiremockConverter.groovy | 20 ++++++++ .../DslToWiremockServerConverter.groovy | 11 +++++ .../wiremock/RecursiveFilesConverter.groovy | 40 ++++++++++++++++ .../wiremock/SingleFileConverter.groovy | 10 ++++ .../wiremock/WiremockToDslConverter.groovy | 1 + .../DslToWiremockClientConverterSpec.groovy | 29 +++++++++++ .../DslToWiremockServerConverterSpec.groovy | 29 +++++++++++ .../RecursiveFilesConverterSpec.groovy | 48 +++++++++++++++++++ .../converter/source/dir1/dsl1.groovy | 12 +++++ .../converter/source/dir1/dsl1b.groovy | 12 +++++ .../converter/source/dir2/dsl2.groovy | 12 +++++ .../resources/converter/source/dslRoot.groovy | 12 +++++ build.gradle | 3 +- 14 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverter.groovy create mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockConverter.groovy create mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy create mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy create mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy create mode 100644 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy create mode 100644 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy create mode 100644 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy create mode 100644 accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy create mode 100644 accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy create mode 100644 accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy create mode 100644 accurest-converters/src/test/resources/converter/source/dslRoot.groovy 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 new file mode 100644 index 0000000000..bfd46e5d3d --- /dev/null +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverter.groovy @@ -0,0 +1,11 @@ +package io.codearte.accurest.wiremock + +import io.coderate.accurest.dsl.WiremockStubStrategy + +class DslToWiremockClientConverter extends DslToWiremockConverter { + + @Override + String convertContent(String dslBody) { + return new WiremockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWiremockClientStub() + } +} 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 new file mode 100644 index 0000000000..82d81a924f --- /dev/null +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockConverter.groovy @@ -0,0 +1,20 @@ +package io.codearte.accurest.wiremock + +import io.coderate.accurest.dsl.GroovyDsl + +abstract class DslToWiremockConverter implements SingleFileConverter { + + @Override + boolean canHandleFileName(String fileName) { + return fileName.endsWith('.groovy') + } + + @Override + String getOutputFileNameForInputFileName(String inputFileName) { + return inputFileName.replaceAll('.groovy', '.json') + } + + protected GroovyDsl createGroovyDSLfromStringContent(String groovyDslAsString) { + return (GroovyDsl)new GroovyShell(this.class.classLoader).evaluate("$groovyDslAsString") + } +} diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy new file mode 100644 index 0000000000..d0e13e7526 --- /dev/null +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy @@ -0,0 +1,11 @@ +package io.codearte.accurest.wiremock + +import io.coderate.accurest.dsl.WiremockStubStrategy + +class DslToWiremockServerConverter extends DslToWiremockConverter { + + @Override + String convertContent(String dslBody) { + return new WiremockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWiremockServerStub() + } +} diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy new file mode 100644 index 0000000000..6273b54849 --- /dev/null +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy @@ -0,0 +1,40 @@ +package io.codearte.accurest.wiremock + +import groovy.io.FileType +import groovy.util.logging.Slf4j + +import java.nio.file.Files +import java.nio.file.Path +import java.nio.file.Paths + +@Slf4j +class RecursiveFilesConverter { + + private final SingleFileConverter singleFileConverter + + RecursiveFilesConverter(SingleFileConverter singleFileConverter) { + this.singleFileConverter = singleFileConverter + } + + void processDirectory(File sourceRootDirectory, File targetRootDirectory) { + sourceRootDirectory.eachFileRecurse(FileType.FILES) { File sourceFile -> + try { + if (!singleFileConverter.canHandleFileName(sourceFile.name)) { + return + } + + String convertedContent = singleFileConverter.convertContent(sourceFile.text) + + Path relativePath = Paths.get(sourceRootDirectory.toURI()).relativize(sourceFile.parentFile.toPath()) + Path absoluteTargetPath = targetRootDirectory.toPath().resolve(relativePath) + Files.createDirectories(absoluteTargetPath) + + File newGroovyFile = new File(absoluteTargetPath.toFile(), singleFileConverter.getOutputFileNameForInputFileName(sourceFile.name)) + log.info("Creating new json [$newGroovyFile.path]") + newGroovyFile.text = convertedContent + } catch (Exception e) { + throw e + } + } + } +} diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy new file mode 100644 index 0000000000..216b573be0 --- /dev/null +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy @@ -0,0 +1,10 @@ +package io.codearte.accurest.wiremock + +interface SingleFileConverter { + + boolean canHandleFileName(String fileName) + + String convertContent(String content) + + String getOutputFileNameForInputFileName(String inputFileName) +} \ No newline at end of file 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 101260ac3a..7b249f0d33 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.wiremock + import groovy.io.FileType import groovy.json.JsonOutput import groovy.json.JsonSlurper 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 new file mode 100644 index 0000000000..1c447be017 --- /dev/null +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy @@ -0,0 +1,29 @@ +package io.codearte.accurest.wiremock + +import groovy.json.JsonSlurper +import spock.lang.Specification + +class DslToWiremockClientConverterSpec extends Specification { + + def "should convert DSL file to Wiremock JSON"() { + given: + def converter = new DslToWiremockClientConverter() + and: + String dslBody = """ + io.coderate.accurest.dsl.GroovyDsl.make { + request { + method('PUT') + urlPattern \$(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } + } +""" + when: + String json = converter.convertContent(dslBody) + then: + new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" +{"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}}""") + } +} diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy new file mode 100644 index 0000000000..063cbab6a3 --- /dev/null +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy @@ -0,0 +1,29 @@ +package io.codearte.accurest.wiremock + +import groovy.json.JsonSlurper +import spock.lang.Specification + +class DslToWiremockServerConverterSpec extends Specification { + + def "should convert DSL file to Wiremock JSON"() { + given: + def converter = new DslToWiremockServerConverter() + and: + String dslBody = """ + io.coderate.accurest.dsl.GroovyDsl.make { + request { + method('PUT') + urlPattern \$(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } + } +""" + when: + String json = converter.convertContent(dslBody) + then: + new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" +{"request":{"method":"PUT","urlPattern":"/12"},"response":{"status":200}}""") + } +} diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy new file mode 100644 index 0000000000..ca3dd46ce0 --- /dev/null +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy @@ -0,0 +1,48 @@ +package io.codearte.accurest.wiremock + +import org.apache.commons.io.FileUtils +import org.apache.commons.io.filefilter.TrueFileFilter +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +import java.nio.file.Path +import java.nio.file.Paths + +class RecursiveFilesConverterSpec extends Specification { + + private static final Set EXPECTED_TARGET_FILES = ["dslRoot.json", "dir1/dsl1.json", "dir1/dsl1b.json", "dir2/dsl2.json"] + + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); + + def "should recursively convert all matching files"() { + given: + def singleFileConverterStub = Stub(SingleFileConverter) + singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") } + singleFileConverterStub.convertContent(_) >> { "converted" } + singleFileConverterStub.getOutputFileNameForInputFileName(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') } + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub) + and: + File originalSourceRootDirectory = new File(this.getClass().getResource("/converter/source").toURI()) + File sourceRootDirectory = tmpFolder.newFolder("source") + File targetRootDirectory = tmpFolder.newFolder("target") + FileUtils.copyDirectory(originalSourceRootDirectory, sourceRootDirectory) + when: + recursiveFilesConverter.processDirectory(sourceRootDirectory, targetRootDirectory) + then: + Collection createdFiles = FileUtils.listFiles(targetRootDirectory, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) + Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, targetRootDirectory) + EXPECTED_TARGET_FILES == relativizedCreatedFiles + and: + createdFiles.each { it.text == "converted" } + } + + private static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { + Path rootSourcePath = Paths.get(targetRootDirectory.toURI()) + Set relativizedCreatedFiles = createdFiles.collect { File file -> + rootSourcePath.relativize(Paths.get(file.toURI())).toString() + } + relativizedCreatedFiles + } +} diff --git a/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy b/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy new file mode 100644 index 0000000000..69afddb8bd --- /dev/null +++ b/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy @@ -0,0 +1,12 @@ +io.coderate.accurest.dsl.GroovyDsl.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } +} diff --git a/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy b/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy new file mode 100644 index 0000000000..69afddb8bd --- /dev/null +++ b/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy @@ -0,0 +1,12 @@ +io.coderate.accurest.dsl.GroovyDsl.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } +} diff --git a/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy b/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy new file mode 100644 index 0000000000..69afddb8bd --- /dev/null +++ b/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy @@ -0,0 +1,12 @@ +io.coderate.accurest.dsl.GroovyDsl.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } +} diff --git a/accurest-converters/src/test/resources/converter/source/dslRoot.groovy b/accurest-converters/src/test/resources/converter/source/dslRoot.groovy new file mode 100644 index 0000000000..69afddb8bd --- /dev/null +++ b/accurest-converters/src/test/resources/converter/source/dslRoot.groovy @@ -0,0 +1,12 @@ +io.coderate.accurest.dsl.GroovyDsl.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } +} diff --git a/build.gradle b/build.gradle index 29b11d04f5..571cfb3c35 100644 --- a/build.gradle +++ b/build.gradle @@ -47,10 +47,10 @@ subprojects { project(':accurest-core') { dependencies { + compile 'org.slf4j:slf4j-api:[1.6.0,)' compile 'org.codehaus.plexus:plexus-utils:3.0.21' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - } } @@ -58,6 +58,7 @@ project(':accurest-converters') { dependencies { compile project(':accurest-core') compile 'org.apache.commons:commons-lang3:3.3.2' + compile 'commons-io:commons-io:[2.4,)' } } From 442c3abe40c2e6e4fca955bfb2dddf2c52df3d95 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Thu, 19 Feb 2015 16:32:59 +0100 Subject: [PATCH 054/719] [#22] Dsl to Wiremock converters - clean up --- .../ConversionAccurestException.groovy | 11 ++++++ .../DslToWiremockClientConverter.groovy | 2 ++ .../wiremock/DslToWiremockConverter.groovy | 4 ++- .../DslToWiremockServerConverter.groovy | 2 ++ .../wiremock/RecursiveFilesConverter.groovy | 35 +++++++++++++------ .../wiremock/SingleFileConverter.groovy | 5 ++- .../RecursiveFilesConverterSpec.groovy | 31 ++++++++++++---- 7 files changed, 70 insertions(+), 20 deletions(-) create mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/ConversionAccurestException.groovy 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 new file mode 100644 index 0000000000..1d111eea7b --- /dev/null +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/ConversionAccurestException.groovy @@ -0,0 +1,11 @@ +package io.codearte.accurest.wiremock + +import groovy.transform.CompileStatic + +@CompileStatic +class ConversionAccurestException extends RuntimeException { + + ConversionAccurestException(String message, Throwable cause) { + super(message, cause) + } +} 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 bfd46e5d3d..1d28f2b9ee 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,9 @@ package io.codearte.accurest.wiremock +import groovy.transform.CompileStatic import io.coderate.accurest.dsl.WiremockStubStrategy +@CompileStatic class DslToWiremockClientConverter extends DslToWiremockConverter { @Override 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 82d81a924f..3f2b81c14b 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,9 @@ package io.codearte.accurest.wiremock +import groovy.transform.CompileStatic import io.coderate.accurest.dsl.GroovyDsl +@CompileStatic abstract class DslToWiremockConverter implements SingleFileConverter { @Override @@ -10,7 +12,7 @@ abstract class DslToWiremockConverter implements SingleFileConverter { } @Override - String getOutputFileNameForInputFileName(String inputFileName) { + String generateOutputFileNameForInput(String inputFileName) { return inputFileName.replaceAll('.groovy', '.json') } diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy index d0e13e7526..caf3b3a199 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy @@ -1,7 +1,9 @@ package io.codearte.accurest.wiremock +import groovy.transform.CompileStatic import io.coderate.accurest.dsl.WiremockStubStrategy +@CompileStatic class DslToWiremockServerConverter extends DslToWiremockConverter { @Override diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy index 6273b54849..ca79645cc8 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest.wiremock import groovy.io.FileType +import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import java.nio.file.Files @@ -8,33 +9,45 @@ import java.nio.file.Path import java.nio.file.Paths @Slf4j +@CompileStatic class RecursiveFilesConverter { private final SingleFileConverter singleFileConverter + private final File sourceRootDirectory + private final File targetRootDirectory - RecursiveFilesConverter(SingleFileConverter singleFileConverter) { + RecursiveFilesConverter(SingleFileConverter singleFileConverter, File sourceRootDirectory, File targetRootDirectory) { this.singleFileConverter = singleFileConverter + this.sourceRootDirectory = sourceRootDirectory + this.targetRootDirectory = targetRootDirectory } - void processDirectory(File sourceRootDirectory, File targetRootDirectory) { + void processFiles() { sourceRootDirectory.eachFileRecurse(FileType.FILES) { File sourceFile -> try { if (!singleFileConverter.canHandleFileName(sourceFile.name)) { return } - String convertedContent = singleFileConverter.convertContent(sourceFile.text) - - Path relativePath = Paths.get(sourceRootDirectory.toURI()).relativize(sourceFile.parentFile.toPath()) - Path absoluteTargetPath = targetRootDirectory.toPath().resolve(relativePath) - Files.createDirectories(absoluteTargetPath) - - File newGroovyFile = new File(absoluteTargetPath.toFile(), singleFileConverter.getOutputFileNameForInputFileName(sourceFile.name)) - log.info("Creating new json [$newGroovyFile.path]") + Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile) + File newGroovyFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) newGroovyFile.text = convertedContent } catch (Exception e) { - throw e + throw new ConversionAccurestException("Unable to convertion of ${sourceFile.name}", e) } } } + + private Path createAndReturnTargetDirectory(File sourceFile) { + Path relativePath = Paths.get(sourceRootDirectory.toURI()).relativize(sourceFile.parentFile.toPath()) + Path absoluteTargetPath = targetRootDirectory.toPath().resolve(relativePath) + Files.createDirectories(absoluteTargetPath) + 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 + } } diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy index 216b573be0..4b76be8357 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy @@ -1,10 +1,13 @@ package io.codearte.accurest.wiremock +import groovy.transform.CompileStatic + +@CompileStatic interface SingleFileConverter { boolean canHandleFileName(String fileName) String convertContent(String content) - String getOutputFileNameForInputFileName(String inputFileName) + String generateOutputFileNameForInput(String inputFileName) } \ No newline at end of file diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy index ca3dd46ce0..5972e00122 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy @@ -18,18 +18,18 @@ class RecursiveFilesConverterSpec extends Specification { def "should recursively convert all matching files"() { given: - def singleFileConverterStub = Stub(SingleFileConverter) - singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") } - singleFileConverterStub.convertContent(_) >> { "converted" } - singleFileConverterStub.getOutputFileNameForInputFileName(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') } - RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub) - and: File originalSourceRootDirectory = new File(this.getClass().getResource("/converter/source").toURI()) File sourceRootDirectory = tmpFolder.newFolder("source") File targetRootDirectory = tmpFolder.newFolder("target") FileUtils.copyDirectory(originalSourceRootDirectory, sourceRootDirectory) + and: + def singleFileConverterStub = Stub(SingleFileConverter) + singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") } + singleFileConverterStub.convertContent(_) >> { "converted" } + singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') } + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, sourceRootDirectory, targetRootDirectory) when: - recursiveFilesConverter.processDirectory(sourceRootDirectory, targetRootDirectory) + recursiveFilesConverter.processFiles() then: Collection createdFiles = FileUtils.listFiles(targetRootDirectory, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, targetRootDirectory) @@ -38,6 +38,23 @@ class RecursiveFilesConverterSpec extends Specification { createdFiles.each { it.text == "converted" } } + def "on failure should break processing and throw meaningful exception"() { + given: + def sourceFile = tmpFolder.newFile() + and: + def singleFileConverterStub = Stub(SingleFileConverter) + singleFileConverterStub.canHandleFileName(_) >> { true } + singleFileConverterStub.convertContent(_) >> { throw new NullPointerException("Test conversion error") } + singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> "${inputFileName}2" } + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, tmpFolder.root, tmpFolder.root) + when: + recursiveFilesConverter.processFiles() + then: + def e = thrown(ConversionAccurestException) + e.message?.contains(sourceFile.name) + e.cause?.message == "Test conversion error" + } + private static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { Path rootSourcePath = Paths.get(targetRootDirectory.toURI()) Set relativizedCreatedFiles = createdFiles.collect { File file -> From 4dc4f1d37cd13f5e125636bfe1d36866dadd29ba Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Fri, 20 Feb 2015 15:52:29 +0100 Subject: [PATCH 055/719] [#22] Add generateWiremockClientStubs task --- .../ConversionAccurestException.groovy | 3 +- .../accurest/AccurestException.groovy | 5 ++- .../config/AccurestConfigProperties.groovy | 2 + .../accurest/dsl/WiremockStubStrategy.groovy | 8 ++-- .../accurest/dsl/internal/Body.groovy | 8 ++-- .../plugin/AccurestGradlePlugin.groovy | 45 ++++++++++++------- ...erateWiremockClientStubsFromDslTask.groovy | 24 ++++++++++ build.gradle | 3 +- 8 files changed, 72 insertions(+), 26 deletions(-) create mode 100644 accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy 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 1d111eea7b..b12d46917f 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,9 +1,10 @@ package io.codearte.accurest.wiremock import groovy.transform.CompileStatic +import io.coderate.accurest.AccurestException @CompileStatic -class ConversionAccurestException extends RuntimeException { +class ConversionAccurestException extends AccurestException { ConversionAccurestException(String message, Throwable cause) { super(message, cause) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy index d564661933..740e13e620 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/AccurestException.groovy @@ -5,8 +5,11 @@ package io.coderate.accurest */ class AccurestException extends RuntimeException { - def AccurestException(String message) { + AccurestException(String message) { super(message) } + AccurestException(String message, Throwable cause) { + super(message, cause) + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy index 794c6f9635..3cf1edb274 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy @@ -14,4 +14,6 @@ class AccurestConfigProperties { String generatedTestSourcesDir = 'build/generated-sources/accurest' String[] imports = [] String[] staticImports = [] + File groovyDslDir + File generatedWiremockClientStubsDir } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy index c4ced294d6..a3d3924fc0 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy @@ -15,12 +15,12 @@ class WiremockStubStrategy { } String toWiremockClientStub() { - return JsonOutput.toJson([request: wiremockRequestStubStrategy.buildClientRequestContent(), - response: wiremockResponseStubStrategy.buildClientResponseContent()]) + return JsonOutput.prettyPrint(JsonOutput.toJson([request: wiremockRequestStubStrategy.buildClientRequestContent(), + response: wiremockResponseStubStrategy.buildClientResponseContent()])) } String toWiremockServerStub() { - return JsonOutput.toJson([request: wiremockRequestStubStrategy.buildServerRequestContent(), - response: wiremockResponseStubStrategy.buildServerResponseContent()]) + return JsonOutput.prettyPrint(JsonOutput.toJson([request: wiremockRequestStubStrategy.buildServerRequestContent(), + response: wiremockResponseStubStrategy.buildServerResponseContent()])) } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index 502e18a2ca..dcf033be1d 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -55,8 +55,8 @@ class Body { } else if(bodyAsList) { bodyAsList.collect { it.clientValue } } - return body.collectEntries { - Map.Entry entry -> [(entry.key) : entry.value.clientValue] + return body.collectEntries { Map.Entry entry -> + [(entry.key) : entry.value.clientValue] } as Map } @@ -66,8 +66,8 @@ class Body { } else if(bodyAsList) { bodyAsList.collect { it.serverValue } } - return body.collectEntries { - Map.Entry entry -> [(entry.key) : entry.value.serverValue] + return body.collectEntries { Map.Entry entry -> + [(entry.key) : entry.value.serverValue] } as Map } } 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 b3bd8d6509..b7561ea393 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 @@ -3,15 +3,18 @@ package io.codearte.accurest.plugin import io.coderate.accurest.AccurestException import io.coderate.accurest.TestGenerator import io.coderate.accurest.config.AccurestConfigProperties +import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.Task /** * @author Jakub Kubrynski */ class AccurestGradlePlugin implements Plugin { - private static final String TASK_NAME = 'generateAccurest' + private static final String GENERATE_SERVER_TESTS_TASK_NAME = 'generateAccurest' + private static final String DSL_TO_WIREMOCK_CLIENT_TASK_NAME = 'generateWiremockClientStubs' private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin @@ -19,9 +22,25 @@ class AccurestGradlePlugin implements Plugin { void apply(Project project) { AccurestConfigProperties extension = project.extensions.create('accurest', AccurestConfigProperties) - project.compileTestGroovy.dependsOn(TASK_NAME) + project.compileTestGroovy.dependsOn(GENERATE_SERVER_TESTS_TASK_NAME) - project.task(TASK_NAME) << { + createGenerateTestsTask(project, extension) + createAndConfigureGenerateWiremockClientStubsFromDslTask(project, extension) + + project.afterEvaluate { + def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) + if (hasIdea) { + project.idea { + module { + testSourceDirs += project.file(buildGeneratedSourcesDir(project, extension)) + } + } + } + } + } + + private Task createGenerateTestsTask(Project project, AccurestConfigProperties extension) { + project.task(GENERATE_SERVER_TESTS_TASK_NAME) << { project.logger.info("Accurest Plugin: Invoking test sources generation") extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory @@ -38,21 +57,18 @@ class AccurestGradlePlugin implements Plugin { int generatedClasses = generator.generate() project.logger.info("Generated {} test classes", generatedClasses) } catch (AccurestException e) { - project.logger.error("Accurest Plugin exception: {}", e.getMessage()) + throw new GradleException("Accurest Plugin exception: ${e.message}", e) } } + } - project.afterEvaluate { - def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) - if (hasIdea) { - project.idea { - module { - testSourceDirs += new File(buildGeneratedSourcesDir(project, extension)) - } - } - } + private void createAndConfigureGenerateWiremockClientStubsFromDslTask(Project project, AccurestConfigProperties extension) { + Task task = project.tasks.create(DSL_TO_WIREMOCK_CLIENT_TASK_NAME, GenerateWiremockClientStubsFromDslTask) + task.description = "Generate" + task.conventionMapping.with { + groovyDslDir = { extension.groovyDslDir } + generatedWiremockClientStubsDir = { extension.generatedWiremockClientStubsDir } } - } private String buildGeneratedSourcesDir(Project project, def extension) { @@ -64,5 +80,4 @@ class AccurestGradlePlugin implements Plugin { } moduleDir } - } diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy new file mode 100644 index 0000000000..46111dc736 --- /dev/null +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy @@ -0,0 +1,24 @@ +package io.codearte.accurest.plugin + +import io.codearte.accurest.wiremock.DslToWiremockClientConverter +import io.codearte.accurest.wiremock.RecursiveFilesConverter +import org.gradle.api.DefaultTask +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.TaskAction + +//TODO: Implement as an incremental task: https://gradle.org/docs/current/userguide/custom_tasks.html#incremental_tasks ? +class GenerateWiremockClientStubsFromDslTask extends DefaultTask { + + @InputDirectory File groovyDslDir + @InputDirectory File generatedWiremockClientStubsDir + + @TaskAction + void generate() { + project.logger.info("Accurest Plugin: Invoking GroovyDSL to Wiremock client stubs conversion") + project.logger.debug("From '${getGroovyDslDir()}' to '${getGeneratedWiremockClientStubsDir()}'") + + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWiremockClientConverter(), getGroovyDslDir(), + getGeneratedWiremockClientStubsDir()) + converter.processFiles() + } +} diff --git a/build.gradle b/build.gradle index 571cfb3c35..e0130574b9 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.3.0-SNAPSHOT' + projectVersion = '0.3.1-SNAPSHOT' projectGroup = 'io.codearte.accurest' } @@ -65,6 +65,7 @@ project(':accurest-converters') { project(':accurest-gradle-plugin') { dependencies { compile project(':accurest-core') + compile project(':accurest-converters') compile gradleApi() } } From 10fb15190b1dd37b7a8f51d9fb698d592ac6cd98 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Sat, 21 Feb 2015 12:15:13 +0100 Subject: [PATCH 056/719] [#22] Rework generate server tests task --- .../io/coderate/accurest/FileSaver.groovy | 7 +-- .../io/coderate/accurest/TestGenerator.groovy | 12 ++-- .../config/AccurestConfigProperties.groovy | 6 +- .../accurest/TestGeneratorSpec.groovy | 6 +- .../plugin/AccurestGradlePlugin.groovy | 61 +++++++------------ .../plugin/GenerateServerTestsTask.groovy | 36 +++++++++++ 6 files changed, 72 insertions(+), 56 deletions(-) create mode 100644 accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateServerTestsTask.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy index 8d76595c4a..74d54d188a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy @@ -13,18 +13,17 @@ import static io.coderate.accurest.util.NamesUtil.capitalize @CompileStatic class FileSaver { - - String targetDirectory + File targetDirectory TestFramework framework - FileSaver(String targetDirectory, TestFramework framework) { + FileSaver(File targetDirectory, TestFramework framework) { this.targetDirectory = targetDirectory this.framework = framework } void saveClassFile(String fileName, String packageName, byte[] classBytes) { - def testBaseDir = Paths.get(targetDirectory, NamesUtil.packageToDirectory(packageName)) + def testBaseDir = Paths.get(targetDirectory.absolutePath, NamesUtil.packageToDirectory(packageName)) Files.createDirectories(testBaseDir) def classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + getTestClassSuffix() + getTestClassExtension()) .toAbsolutePath() diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 2358df8362..f01b5398eb 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -14,23 +14,21 @@ import static io.coderate.accurest.util.NamesUtil.afterLast class TestGenerator { private final AccurestConfigProperties configProperties - private final String stubsBaseDirectory private AtomicInteger counter = new AtomicInteger() private SingleTestGenerator generator private FileSaver saver private DirectoryScanner directoryScanner TestGenerator(AccurestConfigProperties accurestConfigProperties) { - this(accurestConfigProperties, new SingleTestGenerator(accurestConfigProperties), new FileSaver(accurestConfigProperties.generatedTestSourcesDir, accurestConfigProperties.targetFramework)) + this(accurestConfigProperties, new SingleTestGenerator(accurestConfigProperties), + new FileSaver(accurestConfigProperties.generatedTestSourcesDir, accurestConfigProperties.targetFramework)) } TestGenerator(AccurestConfigProperties configProperties, SingleTestGenerator generator, FileSaver saver) { this.configProperties = configProperties - File stubsResource = new File(configProperties.stubsBaseDirectory) - if (stubsResource == null) { + if (configProperties.stubsBaseDirectory == null) { throw new AccurestException("Stubs directory not found under " + configProperties.stubsBaseDirectory) } - this.stubsBaseDirectory = stubsResource.path this.generator = generator this.saver = saver this.directoryScanner = new DirectoryScanner() @@ -61,7 +59,7 @@ class TestGenerator { return includedFile.matches(includedDirectoryRelativePath + File.separator + "[A-Za-z0-9]*\\.json") } .collect { - return new File(stubsBaseDirectory + File.separator + it) + return new File(configProperties.stubsBaseDirectory, it) } if (filesToClass.size()) { def className = afterLast(includedDirectoryRelativePath, File.separator) @@ -71,6 +69,4 @@ class TestGenerator { } } } - - } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy index 3cf1edb274..3f6e50c889 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy @@ -6,12 +6,12 @@ package io.coderate.accurest.config class AccurestConfigProperties { TestFramework targetFramework = TestFramework.SPOCK TestMode testMode = TestMode.MOCKMVC - String stubsBaseDirectory = 'src/test/resources/stubs' - String basePackageForTests = 'io.codearte.accurest.tests' + File stubsBaseDirectory + String basePackageForTests String baseClassForTests String ruleClassForTests List ignoredFiles = [] - String generatedTestSourcesDir = 'build/generated-sources/accurest' + File generatedTestSourcesDir String[] imports = [] String[] staticImports = [] File groovyDslDir diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy index 279af858de..f639dfe1cd 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy @@ -14,7 +14,7 @@ class TestGeneratorSpec extends Specification { given: File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() - properties.stubsBaseDirectory = resource.parentFile.path + properties.stubsBaseDirectory = resource.parentFile TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) when: testGenerator.generateTestClasses("com.ofg") @@ -27,7 +27,7 @@ class TestGeneratorSpec extends Specification { File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() properties.ignoredFiles << "**/other/**" - properties.stubsBaseDirectory = resource.parentFile.path + properties.stubsBaseDirectory = resource.parentFile TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) when: testGenerator.generateTestClasses("com.ofg") @@ -40,7 +40,7 @@ class TestGeneratorSpec extends Specification { File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() properties.ignoredFiles << "**/other.json" - properties.stubsBaseDirectory = resource.parentFile.path + properties.stubsBaseDirectory = resource.parentFile TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) classGenerator.buildClass(_, _, _) >> "sample" when: 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 b7561ea393..11c9d75ba8 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,9 +1,6 @@ package io.codearte.accurest.plugin -import io.coderate.accurest.AccurestException -import io.coderate.accurest.TestGenerator import io.coderate.accurest.config.AccurestConfigProperties -import org.gradle.api.GradleException import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task @@ -18,66 +15,54 @@ class AccurestGradlePlugin implements Plugin { private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin + private Project project + @Override void apply(Project project) { + this.project = project AccurestConfigProperties extension = project.extensions.create('accurest', AccurestConfigProperties) project.compileTestGroovy.dependsOn(GENERATE_SERVER_TESTS_TASK_NAME) - createGenerateTestsTask(project, extension) - createAndConfigureGenerateWiremockClientStubsFromDslTask(project, extension) + setConfigurationDefaults(extension) + createGenerateTestsTask(extension) + createAndConfigureGenerateWiremockClientStubsFromDslTask(extension) project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) if (hasIdea) { project.idea { module { - testSourceDirs += project.file(buildGeneratedSourcesDir(project, extension)) + testSourceDirs += extension.generatedTestSourcesDir } } } } } - private Task createGenerateTestsTask(Project project, AccurestConfigProperties extension) { - project.task(GENERATE_SERVER_TESTS_TASK_NAME) << { - project.logger.info("Accurest Plugin: Invoking test sources generation") - - extension.stubsBaseDirectory = project.projectDir.path + File.separator + extension.stubsBaseDirectory - - project.sourceSets.test.groovy { - project.logger.info("Registering $extension.generatedTestSourcesDir as test source directory") - srcDir extension.generatedTestSourcesDir - } - - extension.generatedTestSourcesDir = buildGeneratedSourcesDir(project, extension) - - try { - TestGenerator generator = new TestGenerator(extension) - int generatedClasses = generator.generate() - project.logger.info("Generated {} test classes", generatedClasses) - } catch (AccurestException e) { - throw new GradleException("Accurest Plugin exception: ${e.message}", e) - } + void setConfigurationDefaults(AccurestConfigProperties extension) { + extension.with { + generatedTestSourcesDir = project.file("${project.buildDir}/generated-sources/accurest") + stubsBaseDirectory = project.file("${project.rootDir}/src/test/resources/stubs") //TODO: Use sourceset + basePackageForTests = 'io.codearte.accurest.tests' } } - private void createAndConfigureGenerateWiremockClientStubsFromDslTask(Project project, AccurestConfigProperties extension) { + private void createGenerateTestsTask(AccurestConfigProperties extension) { + Task task = project.tasks.create(GENERATE_SERVER_TESTS_TASK_NAME, GenerateServerTestsTask) + task.description = "Generate server tests from GroovyDSL" + task.conventionMapping.with { + generatedTestSourcesDir = { extension.generatedTestSourcesDir } + configProperties = { extension } + } + } + + private void createAndConfigureGenerateWiremockClientStubsFromDslTask(AccurestConfigProperties extension) { Task task = project.tasks.create(DSL_TO_WIREMOCK_CLIENT_TASK_NAME, GenerateWiremockClientStubsFromDslTask) - task.description = "Generate" + task.description = "Generate Wiremock client stubs from GroovyDSL" task.conventionMapping.with { groovyDslDir = { extension.groovyDslDir } generatedWiremockClientStubsDir = { extension.generatedWiremockClientStubsDir } } } - - private String buildGeneratedSourcesDir(Project project, def extension) { - String moduleDir - if (project.getParent()) { - moduleDir = project.name + File.separator + extension.generatedTestSourcesDir - } else { - moduleDir = extension.generatedTestSourcesDir - } - moduleDir - } } 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 new file mode 100644 index 0000000000..124c226fe4 --- /dev/null +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateServerTestsTask.groovy @@ -0,0 +1,36 @@ +package io.codearte.accurest.plugin + +import io.coderate.accurest.AccurestException +import io.coderate.accurest.TestGenerator +import io.coderate.accurest.config.AccurestConfigProperties +import org.gradle.api.DefaultTask +import org.gradle.api.GradleException +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction + +class GenerateServerTestsTask extends DefaultTask { + + @OutputDirectory File generatedTestSourcesDir + + //TODO: How to deal with @Input*, @Output* and that domain object? + AccurestConfigProperties configProperties + + @TaskAction + void generate() { + project.logger.info("Accurest Plugin: Invoking test sources generation") + + project.sourceSets.test.groovy { + project.logger.info("Registering ${getConfigProperties().generatedTestSourcesDir} as test source directory") + srcDir getConfigProperties().generatedTestSourcesDir + } + + try { + //TODO: What with that? How to pass? + TestGenerator generator = new TestGenerator(getConfigProperties()) + int generatedClasses = generator.generate() + project.logger.info("Generated {} test classes", generatedClasses) + } catch (AccurestException e) { + throw new GradleException("Accurest Plugin exception: ${e.message}", e) + } + } +} From e521511e00f69c01968a973fc3b617ca5275b4a8 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 12:48:31 +0100 Subject: [PATCH 057/719] Extracted framework configuration to enum --- .../accurest/builder/ClassBuilder.groovy | 23 ++++++------------ .../accurest/builder/MethodBuilder.groovy | 6 +---- .../accurest/config/TestFramework.groovy | 24 ++++++++++++++++++- .../io/codearte/accurest/MainTest.groovy | 6 +++-- .../plugin/GenerateServerTestsTask.groovy | 2 ++ 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy index 7bf11cc9ee..912740b83f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/ClassBuilder.groovy @@ -16,25 +16,16 @@ class ClassBuilder { private final List staticImports = [] private final List rules = [] private final List methods = [] - private final String modifier - private final String suffix + private final TestFramework lang private ClassBuilder(String className, String packageName, String baseClass, TestFramework lang) { + this.lang = lang if (baseClass) { imports << baseClass } this.baseClass = NamesUtil.afterLastDot(baseClass) this.packageName = packageName this.className = className - switch (lang) { - case TestFramework.JUNIT: - modifier = "public " - suffix = ";" - break - case TestFramework.SPOCK: - modifier = "" - suffix = "" - } } static ClassBuilder createClass(String className, String classPackage, AccurestConfigProperties properties) { @@ -70,24 +61,24 @@ class ClassBuilder { String build() { BlockBuilder clazz = new BlockBuilder("\t") - .addLine("package $packageName$suffix") + .addLine("package $packageName$lang.lineSuffix") .addEmptyLine() imports.sort().each { - clazz.addLine("import $it$suffix") + clazz.addLine("import $it$lang.lineSuffix") } if (!imports.empty) { clazz.addEmptyLine() } staticImports.sort().each { - clazz.addLine("import static $it$suffix") + clazz.addLine("import static $it$lang.lineSuffix") } if (!staticImports.empty) { clazz.addEmptyLine() } - def classLine = "${modifier}class $className" + def classLine = "${lang.classModifier}class $className" if (baseClass) { classLine += " extends $baseClass" } @@ -97,7 +88,7 @@ class ClassBuilder { clazz.startBlock() rules.sort().each { clazz.addLine("@Rule") - clazz.addLine("public $it ${NamesUtil.camelCase(it)} = new $it()$suffix") + clazz.addLine("public $it ${NamesUtil.camelCase(it)} = new $it()$lang.lineSuffix") } clazz.endBlock() if (!rules.empty) { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy index 60cd6a074b..951d1ebd5d 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy @@ -26,14 +26,10 @@ class MethodBuilder { } void appendTo(BlockBuilder blockBuilder) { - String modifier if (lang == TestFramework.JUNIT) { blockBuilder.addLine('@Test') - modifier = "public void " - } else { - modifier = "def " } - blockBuilder.addLine(modifier + "$methodName() {") + blockBuilder.addLine(lang.methodModifier + "$methodName() {") new SpockMethodBodyBuilder(stubContent).appendTo(blockBuilder) blockBuilder.addLine('}') } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy index 1a468b1fcb..82e3b3ac90 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy @@ -4,5 +4,27 @@ package io.coderate.accurest.config * @author Jakub Kubrynski */ enum TestFramework { - JUNIT, SPOCK + JUNIT("public ", "public void ", ";"), SPOCK("", "def ", "") + + private final String classModifier + private final String methodModifier + private final String lineSuffix + + TestFramework(String classModifier, String methodModifier, String lineSuffix) { + this.classModifier = classModifier + this.lineSuffix = lineSuffix + this.methodModifier = methodModifier + } + + String getClassModifier() { + return classModifier + } + + String getMethodModifier() { + return methodModifier + } + + String getLineSuffix() { + return lineSuffix + } } \ No newline at end of file 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 76c4256cb5..19e1914a8a 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy @@ -7,9 +7,11 @@ import io.coderate.accurest.config.TestMode class MainTest { public static void main(String[] args) { - AccurestConfigProperties properties = new AccurestConfigProperties(stubsBaseDirectory: '/home/devel/workspace/accurest/accurest-core/src/main/resources/stubs', + AccurestConfigProperties properties = new AccurestConfigProperties( + stubsBaseDirectory: '/home/devel/projects/codearte/accurest/accurest-core/src/main/resources/stubs', + generatedTestSourcesDir: '/tmp/accurest', targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', - staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], ignoredFiles: ["**/different/some.json", "**/other"]) + staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], ignoredFiles: ["**/other"]) println new TestGenerator(properties).generate() } } 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 124c226fe4..cc0c2b288e 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 @@ -5,11 +5,13 @@ import io.coderate.accurest.TestGenerator import io.coderate.accurest.config.AccurestConfigProperties import org.gradle.api.DefaultTask import org.gradle.api.GradleException +import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction class GenerateServerTestsTask extends DefaultTask { + @InputDirectory File groovyDslDir @OutputDirectory File generatedTestSourcesDir //TODO: How to deal with @Input*, @Output* and that domain object? From 4a5efff48cd29e7f27a4fa50c27bd26afb6b78f8 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 12:49:49 +0100 Subject: [PATCH 058/719] Code formatting --- .../ConversionAccurestException.groovy | 6 +- .../DslToWiremockClientConverter.groovy | 8 +- .../wiremock/DslToWiremockConverter.groovy | 22 +- .../DslToWiremockServerConverter.groovy | 8 +- .../wiremock/RecursiveFilesConverter.groovy | 68 +-- .../wiremock/SingleFileConverter.groovy | 6 +- .../wiremock/WiremockToDslConverter.groovy | 201 ++++---- .../DslToWiremockClientConverterSpec.groovy | 20 +- .../DslToWiremockServerConverterSpec.groovy | 20 +- .../RecursiveFilesConverterSpec.groovy | 96 ++-- .../WiremockToDslConverterSpec.groovy | 276 +++++------ .../converter/source/dir1/dsl1.groovy | 20 +- .../converter/source/dir1/dsl1b.groovy | 20 +- .../converter/source/dir2/dsl2.groovy | 20 +- .../resources/converter/source/dslRoot.groovy | 20 +- .../io/coderate/accurest/FileSaver.groovy | 38 +- .../accurest/SingleTestGenerator.groovy | 72 +-- .../io/coderate/accurest/TestGenerator.groovy | 100 ++-- .../builder/SpockMethodBodyBuilder.groovy | 1 - .../dsl/BaseWiremockStubStrategy.groovy | 83 ++-- .../io/coderate/accurest/dsl/GroovyDsl.groovy | 36 +- .../dsl/WiremockRequestStubStrategy.groovy | 50 +- .../dsl/WiremockResponseStubStrategy.groovy | 42 +- .../accurest/dsl/WiremockStubStrategy.groovy | 28 +- .../accurest/dsl/internal/Body.groovy | 102 ++-- .../dsl/internal/ClientDslProperty.groovy | 7 +- .../accurest/dsl/internal/Common.groovy | 90 ++-- .../accurest/dsl/internal/DslProperty.groovy | 20 +- .../accurest/dsl/internal/Headers.groovy | 34 +- .../dsl/internal/JSONCompareMode.groovy | 2 +- .../accurest/dsl/internal/Request.groovy | 99 ++-- .../accurest/dsl/internal/Response.groovy | 90 ++-- .../dsl/internal/ServerDslProperty.groovy | 6 +- .../dsl/internal/WithValuePattern.groovy | 140 +++--- .../resources/stubs/wiremocks/sample.json | 2 +- .../io/codearte/accurest/MainTest.groovy | 2 +- .../accurest/TestGeneratorSpec.groovy | 6 +- .../dsl/WiremockGroovyDslResponseSpec.groovy | 106 ++-- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 454 +++++++++--------- .../plugin/GenerateServerTestsTask.groovy | 6 +- ...erateWiremockClientStubsFromDslTask.groovy | 6 +- 41 files changed, 1225 insertions(+), 1208 deletions(-) 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 b12d46917f..050853b02d 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 @@ -6,7 +6,7 @@ import io.coderate.accurest.AccurestException @CompileStatic class ConversionAccurestException extends AccurestException { - ConversionAccurestException(String message, Throwable cause) { - super(message, cause) - } + ConversionAccurestException(String message, Throwable cause) { + super(message, cause) + } } 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 1d28f2b9ee..7b2b3054e7 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 @@ -6,8 +6,8 @@ import io.coderate.accurest.dsl.WiremockStubStrategy @CompileStatic class DslToWiremockClientConverter extends DslToWiremockConverter { - @Override - String convertContent(String dslBody) { - return new WiremockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWiremockClientStub() - } + @Override + String convertContent(String dslBody) { + return new WiremockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWiremockClientStub() + } } 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 3f2b81c14b..c44d8b40f1 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 @@ -6,17 +6,17 @@ import io.coderate.accurest.dsl.GroovyDsl @CompileStatic abstract class DslToWiremockConverter implements SingleFileConverter { - @Override - boolean canHandleFileName(String fileName) { - return fileName.endsWith('.groovy') - } + @Override + boolean canHandleFileName(String fileName) { + return fileName.endsWith('.groovy') + } - @Override - String generateOutputFileNameForInput(String inputFileName) { - return inputFileName.replaceAll('.groovy', '.json') - } + @Override + String generateOutputFileNameForInput(String inputFileName) { + return inputFileName.replaceAll('.groovy', '.json') + } - protected GroovyDsl createGroovyDSLfromStringContent(String groovyDslAsString) { - return (GroovyDsl)new GroovyShell(this.class.classLoader).evaluate("$groovyDslAsString") - } + protected GroovyDsl createGroovyDSLfromStringContent(String groovyDslAsString) { + return (GroovyDsl) new GroovyShell(this.class.classLoader).evaluate("$groovyDslAsString") + } } diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy index caf3b3a199..ad62c8cc74 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy @@ -6,8 +6,8 @@ import io.coderate.accurest.dsl.WiremockStubStrategy @CompileStatic class DslToWiremockServerConverter extends DslToWiremockConverter { - @Override - String convertContent(String dslBody) { - return new WiremockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWiremockServerStub() - } + @Override + String convertContent(String dslBody) { + return new WiremockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWiremockServerStub() + } } diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy index ca79645cc8..5eb8f81d45 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy @@ -12,42 +12,42 @@ import java.nio.file.Paths @CompileStatic class RecursiveFilesConverter { - private final SingleFileConverter singleFileConverter - private final File sourceRootDirectory - private final File targetRootDirectory + private final SingleFileConverter singleFileConverter + private final File sourceRootDirectory + private final File targetRootDirectory - RecursiveFilesConverter(SingleFileConverter singleFileConverter, File sourceRootDirectory, File targetRootDirectory) { - this.singleFileConverter = singleFileConverter - this.sourceRootDirectory = sourceRootDirectory - this.targetRootDirectory = targetRootDirectory - } + RecursiveFilesConverter(SingleFileConverter singleFileConverter, File sourceRootDirectory, File targetRootDirectory) { + this.singleFileConverter = singleFileConverter + this.sourceRootDirectory = sourceRootDirectory + this.targetRootDirectory = targetRootDirectory + } - void processFiles() { - sourceRootDirectory.eachFileRecurse(FileType.FILES) { File sourceFile -> - try { - if (!singleFileConverter.canHandleFileName(sourceFile.name)) { - return - } - String convertedContent = singleFileConverter.convertContent(sourceFile.text) - Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile) - File newGroovyFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) - newGroovyFile.text = convertedContent - } catch (Exception e) { - throw new ConversionAccurestException("Unable to convertion of ${sourceFile.name}", e) - } - } - } + void processFiles() { + sourceRootDirectory.eachFileRecurse(FileType.FILES) { File sourceFile -> + try { + if (!singleFileConverter.canHandleFileName(sourceFile.name)) { + return + } + String convertedContent = singleFileConverter.convertContent(sourceFile.text) + Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile) + File newGroovyFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) + newGroovyFile.text = convertedContent + } catch (Exception e) { + throw new ConversionAccurestException("Unable to convertion of ${sourceFile.name}", e) + } + } + } - private Path createAndReturnTargetDirectory(File sourceFile) { - Path relativePath = Paths.get(sourceRootDirectory.toURI()).relativize(sourceFile.parentFile.toPath()) - Path absoluteTargetPath = targetRootDirectory.toPath().resolve(relativePath) - Files.createDirectories(absoluteTargetPath) - absoluteTargetPath - } + private Path createAndReturnTargetDirectory(File sourceFile) { + Path relativePath = Paths.get(sourceRootDirectory.toURI()).relativize(sourceFile.parentFile.toPath()) + Path absoluteTargetPath = targetRootDirectory.toPath().resolve(relativePath) + Files.createDirectories(absoluteTargetPath) + 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 - } + 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 + } } diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy index 4b76be8357..27d10c25c8 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy @@ -5,9 +5,9 @@ import groovy.transform.CompileStatic @CompileStatic interface SingleFileConverter { - boolean canHandleFileName(String fileName) + boolean canHandleFileName(String fileName) - String convertContent(String content) + String convertContent(String content) - String generateOutputFileNameForInput(String inputFileName) + String generateOutputFileNameForInput(String inputFileName) } \ No newline at end of file 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 7b249f0d33..6a1ca4fbde 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 @@ -8,132 +8,137 @@ import groovy.xml.XmlUtil import static org.apache.commons.lang3.StringEscapeUtils.escapeJava class WiremockToDslConverter { - static String fromWiremockStub(String wiremockStringStub) { - return new WiremockToDslConverter().convertFromWiremockStub(wiremockStringStub) - } + static String fromWiremockStub(String wiremockStringStub) { + return new WiremockToDslConverter().convertFromWiremockStub(wiremockStringStub) + } - private String convertFromWiremockStub(String wiremockStringStub) { - Object wiremockStub = new JsonSlurper().parseText(wiremockStringStub) - def request = wiremockStub.request - def response = wiremockStub.response - return """\ + private String convertFromWiremockStub(String wiremockStringStub) { + Object wiremockStub = new JsonSlurper().parseText(wiremockStringStub) + def request = wiremockStub.request + def response = wiremockStub.response + return """\ request { ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} ${request.urlPattern ? "urlPattern \"\"\"${escapeJava(request.urlPattern)}\"\"\"" : ""} ${request.urlPath ? "urlPath \"\"\"$request.urlPath\"\"\"" : ""} - ${request.headers ? """headers { - ${request.headers.collect { - def assertion = it.value - String headerName = it.key as String - def entry = assertion.entrySet().first() - """header(\"\"\"$headerName\"\"\").$entry.key(\"\"\"${escapeJava(entry.value)}\"\"\")\n""" - }.join('') - } + ${ + request.headers ? """headers { + ${ + request.headers.collect { + def assertion = it.value + String headerName = it.key as String + def entry = assertion.entrySet().first() + """header(\"\"\"$headerName\"\"\").$entry.key(\"\"\"${escapeJava(entry.value)}\"\"\")\n""" + }.join('') + } } - """ : ""} + """ : "" + } } response { ${response.status ? "status $response.status" : ""} ${response.body ? "body( ${buildBody(response.body)})" : ""} - ${response.headers ? """headers { + ${ + response.headers ? """headers { ${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')} } - """ : ""} + """ : "" + } } """ - } + } - private Object buildBody(Map responseBody) { - return responseBody.entrySet().collectAll(withQuotedMapStringElements()).inject([:], appendToIterable()) - } + private Object buildBody(Map responseBody) { + return responseBody.entrySet().collectAll(withQuotedMapStringElements()).inject([:], appendToIterable()) + } - private Object buildBody(List responseBody) { - return responseBody.collectAll(withQuotedStringElements()).inject([], appendToIterable()) - } + private Object buildBody(List responseBody) { + return responseBody.collectAll(withQuotedStringElements()).inject([], appendToIterable()) + } - private Object buildBody(Integer responseBody) { - return responseBody - } + private Object buildBody(Integer responseBody) { + return responseBody + } - private Object buildBody(String responseBody) { - try { - def json = new JsonSlurper().parseText(responseBody) - return wrapWithMultilineGString(JsonOutput.prettyPrint(responseBody)) - } catch (Exception jsonException) { - try { - def xml = new XmlSlurper().parseText(responseBody) - return wrapWithMultilineGString(XmlUtil.serialize(responseBody)) - } catch (Exception xmlException) { - return wrapWithMultilineGString(responseBody) - } - } - } + private Object buildBody(String responseBody) { + try { + def json = new JsonSlurper().parseText(responseBody) + return wrapWithMultilineGString(JsonOutput.prettyPrint(responseBody)) + } catch (Exception jsonException) { + try { + def xml = new XmlSlurper().parseText(responseBody) + return wrapWithMultilineGString(XmlUtil.serialize(responseBody)) + } catch (Exception xmlException) { + return wrapWithMultilineGString(responseBody) + } + } + } - private String wrapWithMultilineGString(String string) { - return """\"\"\"$string\"\"\"""" - } + private String wrapWithMultilineGString(String string) { + return """\"\"\"$string\"\"\"""" + } - private Closure withQuotedMapStringElements() { - return { - [(it.key): convert(it.value)] - } - } + private Closure withQuotedMapStringElements() { + return { + [(it.key): convert(it.value)] + } + } - private Closure withQuotedStringElements() { - return { - convert(it) - } - } + private Closure withQuotedStringElements() { + return { + convert(it) + } + } - private Closure appendToIterable() { - return { - acc, el -> acc << el - } - } + private Closure appendToIterable() { + return { + acc, el -> acc << el + } + } - private Object convert(Object element) { - return element - } + private Object convert(Object element) { + return element + } - private Object convert(String element) { - return quoteString(element) - } + private Object convert(String element) { + return quoteString(element) + } - private String quoteString(String element) { - if (element =~ /^".*"$/) { - return element - } - return """\"\"\"${escapeJava(element)}\"\"\"""" - } + private String quoteString(String element) { + if (element =~ /^".*"$/) { + return element + } + return """\"\"\"${escapeJava(element)}\"\"\"""" + } - private Object convert(List element) { - return element.collect { - convert(it) - } - } + private Object convert(List element) { + return element.collect { + convert(it) + } + } - private Object convert(Map element) { - return element.collectEntries { - [(it.key) : convert(it.value)] - } - } + private Object convert(Map element) { + return element.collectEntries { + [(it.key): convert(it.value)] + } + } - static void main(String[] args) { - String rootOfFolderWithStubs = args[0] - new File(rootOfFolderWithStubs).eachFileRecurse(FileType.FILES) { - try { - if(!it.name.endsWith('json')) { - return - } - String wiremockStub = fromWiremockStub(it.text) - File newGroovyFile = new File(it.parent, it.name.replaceAll('json', 'groovy')) - println("Creating new groovy file [$newGroovyFile.path]") - newGroovyFile.text = wiremockStub - } catch (Exception e) { - System.err.println(e) - } + static void main(String[] args) { + String rootOfFolderWithStubs = args[0] + new File(rootOfFolderWithStubs).eachFileRecurse(FileType.FILES) { + try { + if (!it.name.endsWith('json')) { + return + } + String wiremockStub = fromWiremockStub(it.text) + File newGroovyFile = new File(it.parent, it.name.replaceAll('json', 'groovy')) + println("Creating new groovy file [$newGroovyFile.path]") + newGroovyFile.text = wiremockStub + } catch (Exception e) { + System.err.println(e) + } - } - } + } + } } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy index 1c447be017..4f2d5e060e 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy @@ -5,11 +5,11 @@ import spock.lang.Specification class DslToWiremockClientConverterSpec extends Specification { - def "should convert DSL file to Wiremock JSON"() { - given: - def converter = new DslToWiremockClientConverter() - and: - String dslBody = """ + def "should convert DSL file to Wiremock JSON"() { + given: + def converter = new DslToWiremockClientConverter() + and: + String dslBody = """ io.coderate.accurest.dsl.GroovyDsl.make { request { method('PUT') @@ -20,10 +20,10 @@ class DslToWiremockClientConverterSpec extends Specification { } } """ - when: - String json = converter.convertContent(dslBody) - then: - new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" + when: + String json = converter.convertContent(dslBody) + then: + new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" {"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}}""") - } + } } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy index 063cbab6a3..b11f4460b3 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy @@ -5,11 +5,11 @@ import spock.lang.Specification class DslToWiremockServerConverterSpec extends Specification { - def "should convert DSL file to Wiremock JSON"() { - given: - def converter = new DslToWiremockServerConverter() - and: - String dslBody = """ + def "should convert DSL file to Wiremock JSON"() { + given: + def converter = new DslToWiremockServerConverter() + and: + String dslBody = """ io.coderate.accurest.dsl.GroovyDsl.make { request { method('PUT') @@ -20,10 +20,10 @@ class DslToWiremockServerConverterSpec extends Specification { } } """ - when: - String json = converter.convertContent(dslBody) - then: - new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" + when: + String json = converter.convertContent(dslBody) + then: + new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" {"request":{"method":"PUT","urlPattern":"/12"},"response":{"status":200}}""") - } + } } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy index 5972e00122..f450449046 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy @@ -11,55 +11,57 @@ import java.nio.file.Paths class RecursiveFilesConverterSpec extends Specification { - private static final Set EXPECTED_TARGET_FILES = ["dslRoot.json", "dir1/dsl1.json", "dir1/dsl1b.json", "dir2/dsl2.json"] + private static + final Set EXPECTED_TARGET_FILES = ["dslRoot.json", "dir1/dsl1.json", "dir1/dsl1b.json", "dir2/dsl2.json"] - @Rule - public TemporaryFolder tmpFolder = new TemporaryFolder(); + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); - def "should recursively convert all matching files"() { - given: - File originalSourceRootDirectory = new File(this.getClass().getResource("/converter/source").toURI()) - File sourceRootDirectory = tmpFolder.newFolder("source") - File targetRootDirectory = tmpFolder.newFolder("target") - FileUtils.copyDirectory(originalSourceRootDirectory, sourceRootDirectory) - and: - def singleFileConverterStub = Stub(SingleFileConverter) - singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") } - singleFileConverterStub.convertContent(_) >> { "converted" } - singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') } - RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, sourceRootDirectory, targetRootDirectory) - when: - recursiveFilesConverter.processFiles() - then: - Collection createdFiles = FileUtils.listFiles(targetRootDirectory, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) - Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, targetRootDirectory) - EXPECTED_TARGET_FILES == relativizedCreatedFiles - and: - createdFiles.each { it.text == "converted" } - } + def "should recursively convert all matching files"() { + given: + File originalSourceRootDirectory = new File(this.getClass().getResource("/converter/source").toURI()) + File sourceRootDirectory = tmpFolder.newFolder("source") + File targetRootDirectory = tmpFolder.newFolder("target") + FileUtils.copyDirectory(originalSourceRootDirectory, sourceRootDirectory) + and: + def singleFileConverterStub = Stub(SingleFileConverter) + singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") } + singleFileConverterStub.convertContent(_) >> { "converted" } + singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') } + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, sourceRootDirectory, targetRootDirectory) + when: + recursiveFilesConverter.processFiles() + then: + Collection createdFiles = FileUtils.listFiles(targetRootDirectory, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) + Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, targetRootDirectory) + EXPECTED_TARGET_FILES == relativizedCreatedFiles + and: + createdFiles.each { it.text == "converted" } + } - def "on failure should break processing and throw meaningful exception"() { - given: - def sourceFile = tmpFolder.newFile() - and: - def singleFileConverterStub = Stub(SingleFileConverter) - singleFileConverterStub.canHandleFileName(_) >> { true } - singleFileConverterStub.convertContent(_) >> { throw new NullPointerException("Test conversion error") } - singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> "${inputFileName}2" } - RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, tmpFolder.root, tmpFolder.root) - when: - recursiveFilesConverter.processFiles() - then: - def e = thrown(ConversionAccurestException) - e.message?.contains(sourceFile.name) - e.cause?.message == "Test conversion error" - } + def "on failure should break processing and throw meaningful exception"() { + given: + def sourceFile = tmpFolder.newFile() + and: + def singleFileConverterStub = Stub(SingleFileConverter) + singleFileConverterStub.canHandleFileName(_) >> { true } + singleFileConverterStub.convertContent(_) >> { throw new NullPointerException("Test conversion error") } + singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> "${inputFileName}2" } + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, tmpFolder.root, tmpFolder.root) + when: + recursiveFilesConverter.processFiles() + then: + def e = thrown(ConversionAccurestException) + e.message?.contains(sourceFile.name) + e.cause?.message == "Test conversion error" + } - private static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { - Path rootSourcePath = Paths.get(targetRootDirectory.toURI()) - Set relativizedCreatedFiles = createdFiles.collect { File file -> - rootSourcePath.relativize(Paths.get(file.toURI())).toString() - } - relativizedCreatedFiles - } + private + static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { + Path rootSourcePath = Paths.get(targetRootDirectory.toURI()) + Set relativizedCreatedFiles = createdFiles.collect { File file -> + rootSourcePath.relativize(Paths.get(file.toURI())).toString() + } + relativizedCreatedFiles + } } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index aac2bbb12f..ad551f3272 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -5,9 +5,9 @@ import spock.lang.Specification class WiremockToDslConverterSpec extends Specification { - def 'should produce a Groovy DSL from Wiremock stub'() { - given: - String wiremockStub = '''\ + def 'should produce a Groovy DSL from Wiremock stub'() { + given: + String wiremockStub = '''\ { "request": { "method": "GET", @@ -40,44 +40,44 @@ class WiremockToDslConverterSpec extends Specification { } } ''' - and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { - request { - method 'GET' - urlPattern '/[0-9]{2}' - headers { - header('Accept').matches('text/.*') - header('etag').doesNotMatch('abcd.*') - header('X-Custom-Header').contains('2134') - } - } - response { - status 200 - body ( - id : [value: '132'], - surname : 'Kowalsky', - name: 'Jan', - created : '2014-02-02 12:23:43' - ) - headers { - header 'Content-Type': 'text/plain' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPattern '/[0-9]{2}' + headers { + header('Accept').matches('text/.*') + header('etag').doesNotMatch('abcd.*') + header('X-Custom-Header').contains('2134') + } + } + response { + status 200 + body( + id: [value: '132'], + surname: 'Kowalsky', + name: 'Jan', + created: '2014-02-02 12:23:43' + ) + headers { + header 'Content-Type': 'text/plain' - } - } - } - when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) - then: - new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl - } + } - def 'should convert Wiremock stub with body containing simple JSON'() { - given: - String wiremockStub = '''\ + def 'should convert Wiremock stub with body containing simple JSON'() { + given: + String wiremockStub = '''\ { "request": { "method": "DELETE", @@ -97,38 +97,38 @@ class WiremockToDslConverterSpec extends Specification { } } ''' - and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { - request { - method 'DELETE' - urlPattern '/credit-card-verification-data/[0-9]+' - headers { - header('Content-Type').equalTo('application/vnd.mymoid-adapter.v2+json; charset=UTF-8') - } - } - response { - status 200 - body ("""{ + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'DELETE' + urlPattern '/credit-card-verification-data/[0-9]+' + headers { + header('Content-Type').equalTo('application/vnd.mymoid-adapter.v2+json; charset=UTF-8') + } + } + response { + status 200 + body("""{ "status": "OK" }""") - headers { - header 'Content-Type': 'application/json' + headers { + header 'Content-Type': 'application/json' - } - } - } - when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) - then: - new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl - } + } - def 'should convert Wiremock stub with body containing integer'() { - given: - String wiremockStub = '''\ + def 'should convert Wiremock stub with body containing integer'() { + given: + String wiremockStub = '''\ { "request": { "method": "POST", @@ -148,36 +148,36 @@ class WiremockToDslConverterSpec extends Specification { } } ''' - and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { - request { - method 'POST' - url '/charge/count' - headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') - } - } - response { - status 200 - body ( 200 ) - headers { - header 'Content-Type': 'application/json' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/count' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body(200) + headers { + header 'Content-Type': 'application/json' - } - } - } - when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) - then: - new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl - } + } - def 'should convert Wiremock stub with body as a list'() { - given: - String wiremockStub = '''\ + def 'should convert Wiremock stub with body as a list'() { + given: + String wiremockStub = '''\ { "request": { "method": "POST", @@ -201,41 +201,41 @@ class WiremockToDslConverterSpec extends Specification { } } ''' - and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { - request { - method 'POST' - url '/charge/count' - headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') - } - } - response { - status 200 - body ([ - [a: 1, c: '3'], - 'b', - 'a' - ]) - headers { - header 'Content-Type': 'application/json' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/count' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body([ + [a: 1, c: '3'], + 'b', + 'a' + ]) + headers { + header 'Content-Type': 'application/json' - } - } - } - when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) - then: - new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + } + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl - } + } - def 'should convert Wiremock stub with body containing a nested list'() { - given: - String wiremockStub = '''\ + def 'should convert Wiremock stub with body containing a nested list'() { + given: + String wiremockStub = '''\ { "request": { "method": "POST", @@ -252,18 +252,18 @@ class WiremockToDslConverterSpec extends Specification { } } ''' - and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { - request { - method 'POST' - url '/charge/search?pageNumber=0&size=2147483647' - headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') - } - } - response { - status 200 - body ("""[ + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/charge/search?pageNumber=0&size=2147483647' + headers { + header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + } + } + response { + status 200 + body("""[ { "amount": 1.01, "name": "Name", @@ -285,15 +285,15 @@ class WiremockToDslConverterSpec extends Specification { "user": null } ]""") - } - } - when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) - then: - new GroovyShell(this.class.classLoader).evaluate( - """ io.coderate.accurest.dsl.GroovyDsl.make { + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + new GroovyShell(this.class.classLoader).evaluate( + """ io.coderate.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl - } + } } diff --git a/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy b/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy index 69afddb8bd..be45f92092 100644 --- a/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy +++ b/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy @@ -1,12 +1,12 @@ io.coderate.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } } 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 69afddb8bd..be45f92092 100644 --- a/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy +++ b/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy @@ -1,12 +1,12 @@ io.coderate.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } } 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 69afddb8bd..be45f92092 100644 --- a/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy +++ b/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy @@ -1,12 +1,12 @@ io.coderate.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } } diff --git a/accurest-converters/src/test/resources/converter/source/dslRoot.groovy b/accurest-converters/src/test/resources/converter/source/dslRoot.groovy index 69afddb8bd..be45f92092 100644 --- a/accurest-converters/src/test/resources/converter/source/dslRoot.groovy +++ b/accurest-converters/src/test/resources/converter/source/dslRoot.groovy @@ -1,12 +1,12 @@ io.coderate.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy index 74d54d188a..dd393993a6 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy @@ -13,28 +13,28 @@ import static io.coderate.accurest.util.NamesUtil.capitalize @CompileStatic class FileSaver { - File targetDirectory - TestFramework framework + File targetDirectory + TestFramework framework - FileSaver(File targetDirectory, TestFramework framework) { - this.targetDirectory = targetDirectory - this.framework = framework - } + FileSaver(File targetDirectory, TestFramework framework) { + this.targetDirectory = targetDirectory + this.framework = framework + } - void saveClassFile(String fileName, String packageName, byte[] classBytes) { + void saveClassFile(String fileName, String packageName, byte[] classBytes) { - def testBaseDir = Paths.get(targetDirectory.absolutePath, NamesUtil.packageToDirectory(packageName)) - Files.createDirectories(testBaseDir) - def classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + getTestClassSuffix() + getTestClassExtension()) - .toAbsolutePath() - Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) - } + def testBaseDir = Paths.get(targetDirectory.absolutePath, NamesUtil.packageToDirectory(packageName)) + Files.createDirectories(testBaseDir) + def classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + getTestClassSuffix() + getTestClassExtension()) + .toAbsolutePath() + Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) + } - private String getTestClassSuffix() { - return framework == TestFramework.SPOCK ? 'Spec' : 'Test' - } + private String getTestClassSuffix() { + return framework == TestFramework.SPOCK ? 'Spec' : 'Test' + } - private String getTestClassExtension() { - return framework == TestFramework.SPOCK ? '.groovy' : '.java' - } + private String getTestClassExtension() { + return framework == TestFramework.SPOCK ? '.groovy' : '.java' + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy index 42b35134cd..80f7276a68 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/SingleTestGenerator.groovy @@ -11,50 +11,50 @@ import static io.coderate.accurest.builder.MethodBuilder.createTestMethod import static io.coderate.accurest.util.NamesUtil.capitalize class SingleTestGenerator { - private final AccurestConfigProperties configProperties + private final AccurestConfigProperties configProperties SingleTestGenerator(AccurestConfigProperties configProperties) { - this.configProperties = configProperties - } + this.configProperties = configProperties + } - @PackageScope - String buildClass(List listOfFiles, String className, String classPackage) { - ClassBuilder clazz = createClass(capitalize(className), classPackage, - configProperties) + @PackageScope + String buildClass(List listOfFiles, String className, String classPackage) { + ClassBuilder clazz = createClass(capitalize(className), classPackage, + configProperties) - if (configProperties.imports) { - configProperties.imports.each { - clazz.addImport(it) - } - } + if (configProperties.imports) { + configProperties.imports.each { + clazz.addImport(it) + } + } - if (configProperties.staticImports) { - configProperties.staticImports.each { - clazz.addStaticImport(it) - } - } + if (configProperties.staticImports) { + configProperties.staticImports.each { + clazz.addStaticImport(it) + } + } - if (configProperties.testMode == TestMode.MOCKMVC) { - clazz.addStaticImport('com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*') - } else { - clazz.addStaticImport('com.jayway.restassured.RestAssured.*') - } + 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) { - clazz.addImport('org.junit.Test') - } else { - clazz.addImport('groovy.json.JsonSlurper') - } + if (configProperties.targetFramework == TestFramework.JUNIT) { + clazz.addImport('org.junit.Test') + } else { + clazz.addImport('groovy.json.JsonSlurper') + } - if (configProperties.ruleClassForTests) { - clazz.addImport('org.junit.Rule') - .addRule(configProperties.ruleClassForTests) - } + if (configProperties.ruleClassForTests) { + clazz.addImport('org.junit.Rule') + .addRule(configProperties.ruleClassForTests) + } - listOfFiles.each { - clazz.addMethod(createTestMethod(it, configProperties.targetFramework)) - } - return clazz.build() - } + listOfFiles.each { + clazz.addMethod(createTestMethod(it, configProperties.targetFramework)) + } + return clazz.build() + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index f01b5398eb..a8dca060f4 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -13,60 +13,60 @@ import static io.coderate.accurest.util.NamesUtil.afterLast */ class TestGenerator { - private final AccurestConfigProperties configProperties - private AtomicInteger counter = new AtomicInteger() - private SingleTestGenerator generator - private FileSaver saver - private DirectoryScanner directoryScanner + private final AccurestConfigProperties configProperties + private AtomicInteger counter = new AtomicInteger() + private SingleTestGenerator generator + private FileSaver saver + private DirectoryScanner directoryScanner - TestGenerator(AccurestConfigProperties accurestConfigProperties) { - this(accurestConfigProperties, new SingleTestGenerator(accurestConfigProperties), - new FileSaver(accurestConfigProperties.generatedTestSourcesDir, accurestConfigProperties.targetFramework)) - } + TestGenerator(AccurestConfigProperties accurestConfigProperties) { + this(accurestConfigProperties, new SingleTestGenerator(accurestConfigProperties), + new FileSaver(accurestConfigProperties.generatedTestSourcesDir, accurestConfigProperties.targetFramework)) + } - TestGenerator(AccurestConfigProperties configProperties, SingleTestGenerator generator, FileSaver saver) { - this.configProperties = configProperties - if (configProperties.stubsBaseDirectory == null) { - throw new AccurestException("Stubs directory not found under " + configProperties.stubsBaseDirectory) - } - this.generator = generator - this.saver = saver - this.directoryScanner = new DirectoryScanner() - directoryScanner.setExcludes(configProperties.getIgnoredFiles() as String[]) - directoryScanner.setBasedir(configProperties.stubsBaseDirectory) - } + TestGenerator(AccurestConfigProperties configProperties, SingleTestGenerator generator, FileSaver saver) { + this.configProperties = configProperties + if (configProperties.stubsBaseDirectory == null) { + throw new AccurestException("Stubs directory not found under " + configProperties.stubsBaseDirectory) + } + this.generator = generator + this.saver = saver + this.directoryScanner = new DirectoryScanner() + directoryScanner.setExcludes(configProperties.getIgnoredFiles() as String[]) + directoryScanner.setBasedir(configProperties.stubsBaseDirectory) + } - int generate() { - generateTestClasses(configProperties.basePackageForTests) - return counter.get() - } + int generate() { + generateTestClasses(configProperties.basePackageForTests) + return counter.get() + } - @PackageScope - void generateTestClasses(final String packageName) { - directoryScanner.scan() - directoryScanner.getIncludedDirectories() - .each { String includedDirectoryRelativePath -> - processIncludedDirectory(includedDirectoryRelativePath, packageName) + @PackageScope + void generateTestClasses(final String packageName) { + directoryScanner.scan() + directoryScanner.getIncludedDirectories() + .each { String includedDirectoryRelativePath -> + processIncludedDirectory(includedDirectoryRelativePath, packageName) - } - } + } + } - private void processIncludedDirectory( - final String includedDirectoryRelativePath, final String packageNameForClass) { - if (!includedDirectoryRelativePath.isEmpty()) { - List filesToClass = directoryScanner.includedFiles. - grep { String includedFile -> - return includedFile.matches(includedDirectoryRelativePath + File.separator + "[A-Za-z0-9]*\\.json") - } - .collect { - return new File(configProperties.stubsBaseDirectory, it) - } - if (filesToClass.size()) { - def className = afterLast(includedDirectoryRelativePath, File.separator) - def classBytes = generator.buildClass(filesToClass, className, packageNameForClass).bytes - saver.saveClassFile(className, packageNameForClass, classBytes) - counter.incrementAndGet() - } - } - } + private void processIncludedDirectory( + final String includedDirectoryRelativePath, final String packageNameForClass) { + if (!includedDirectoryRelativePath.isEmpty()) { + List filesToClass = directoryScanner.includedFiles. + grep { String includedFile -> + return includedFile.matches(includedDirectoryRelativePath + File.separator + "[A-Za-z0-9]*\\.json") + } + .collect { + return new File(configProperties.stubsBaseDirectory, it) + } + if (filesToClass.size()) { + def className = afterLast(includedDirectoryRelativePath, File.separator) + def classBytes = generator.buildClass(filesToClass, className, packageNameForClass).bytes + saver.saveClassFile(className, packageNameForClass, classBytes) + counter.incrementAndGet() + } + } + } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index bac810fce6..93b2afe581 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,6 +1,5 @@ package io.coderate.accurest.builder -import groovy.json.JsonOutput import groovy.transform.PackageScope /** diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index e02c2a62ce..9dad3f56ea 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -1,4 +1,5 @@ package io.coderate.accurest.dsl + import groovy.transform.CompileStatic import io.coderate.accurest.dsl.internal.DslProperty import io.coderate.accurest.dsl.internal.Headers @@ -6,50 +7,50 @@ import io.coderate.accurest.dsl.internal.WithValuePattern @CompileStatic abstract class BaseWiremockStubStrategy { - protected Map buildClientHeadersSection(Headers headers) { - if (!headers) { - return null - } - return withAssertionHeaders(headers) { - Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] - } << headers.valueHeaders() - } + protected Map buildClientHeadersSection(Headers headers) { + if (!headers) { + return null + } + return withAssertionHeaders(headers) { + Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] + } << headers.valueHeaders() + } - protected Map buildServerHeadersSection(Headers headers) { - if (!headers) { - return null - } - return withAssertionHeaders(headers) { - Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] - } << headers.valueHeaders() - } + protected Map buildServerHeadersSection(Headers headers) { + if (!headers) { + return null + } + return withAssertionHeaders(headers) { + Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] + } << headers.valueHeaders() + } - private Map withAssertionHeaders(Headers headers, Closure closure) { - return headers?.assertionEntries()?.collectEntries(closure) - } + private Map withAssertionHeaders(Headers headers, Closure closure) { + return headers?.assertionEntries()?.collectEntries(closure) + } - private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) { - return getValuePatternSection(valuePattern) - .findAll { it.value } - .collectEntries { [(it.key): it.value.clientValue] } - } + private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) { + return getValuePatternSection(valuePattern) + .findAll { it.value } + .collectEntries { [(it.key): it.value.clientValue] } + } - private Map buildServerHeaderFromValuePattern(WithValuePattern valuePattern) { - return getValuePatternSection(valuePattern) - .findAll { it.value } - .collectEntries { [(it.key): it.value.serverValue] } - } + private Map buildServerHeaderFromValuePattern(WithValuePattern valuePattern) { + return getValuePatternSection(valuePattern) + .findAll { it.value } + .collectEntries { [(it.key): it.value.serverValue] } + } - private Map getValuePatternSection(WithValuePattern valuePattern) { - return [equalToJson : valuePattern.equalToJson, - equalToXml : valuePattern.equalToXml, - matchesXPath : valuePattern.matchesXPath, - jsonCompareMode: valuePattern.jsonCompareMode, - equalTo : valuePattern.equalTo, - contains : valuePattern.contains, - matches : valuePattern.matches, - doesNotMatch : valuePattern.doesNotMatch, - absent : valuePattern.absent, - matchesJsonPath: valuePattern.matchesJsonPath] - } + private Map getValuePatternSection(WithValuePattern valuePattern) { + return [equalToJson : valuePattern.equalToJson, + equalToXml : valuePattern.equalToXml, + matchesXPath : valuePattern.matchesXPath, + jsonCompareMode: valuePattern.jsonCompareMode, + equalTo : valuePattern.equalTo, + contains : valuePattern.contains, + matches : valuePattern.matches, + doesNotMatch : valuePattern.doesNotMatch, + absent : valuePattern.absent, + matchesJsonPath: valuePattern.matchesJsonPath] + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy index 225d5dce52..ad3d2f760a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -11,26 +11,26 @@ import io.coderate.accurest.dsl.internal.Response @ToString(includeFields = true, includePackage = false) class GroovyDsl { - Request request - Response response + Request request + Response response - static GroovyDsl make(Closure closure) { - GroovyDsl dsl = new GroovyDsl() - closure.delegate = dsl - closure() - return dsl - } + static GroovyDsl make(Closure closure) { + GroovyDsl dsl = new GroovyDsl() + closure.delegate = dsl + closure() + return dsl + } - void request(@DelegatesTo(Request) Closure closure) { - this.request = new Request() - closure.delegate = request - closure() - } + void request(@DelegatesTo(Request) Closure closure) { + this.request = new Request() + closure.delegate = request + closure() + } - void response(@DelegatesTo(Response) Closure closure) { - this.response = new Response() - closure.delegate = response - closure() - } + void response(@DelegatesTo(Response) Closure closure) { + this.response = new Response() + closure.delegate = response + closure() + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 369b082cf8..0bee93bfad 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -10,33 +10,35 @@ import io.coderate.accurest.dsl.internal.ServerRequest @PackageScope class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { - private final Request request + private final Request request - WiremockRequestStubStrategy(GroovyDsl groovyDsl) { - this.request = groovyDsl.request - } + WiremockRequestStubStrategy(GroovyDsl groovyDsl) { + this.request = groovyDsl.request + } - @PackageScope Map buildClientRequestContent() { - return buildRequestContent(new ClientRequest(request)) - } + @PackageScope + Map buildClientRequestContent() { + return buildRequestContent(new ClientRequest(request)) + } - @PackageScope Map buildServerRequestContent() { - return buildRequestContent(new ServerRequest(request)) - } + @PackageScope + Map buildServerRequestContent() { + return buildRequestContent(new ServerRequest(request)) + } - private Map buildRequestContent(ClientRequest request) { - return [method : request?.method?.clientValue, - url : request?.url?.clientValue, - urlPattern: request?.urlPattern?.clientValue, - urlPath : request?.urlPath?.clientValue, - headers : buildClientHeadersSection(request.headers)].findAll { it.value } - } + private Map buildRequestContent(ClientRequest request) { + return [method : request?.method?.clientValue, + url : request?.url?.clientValue, + urlPattern: request?.urlPattern?.clientValue, + urlPath : request?.urlPath?.clientValue, + headers : buildClientHeadersSection(request.headers)].findAll { it.value } + } - private Map buildRequestContent(ServerRequest request) { - return [method : request?.method?.serverValue, - url : request?.url?.serverValue, - urlPattern: request?.urlPattern?.serverValue, - urlPath : request?.urlPath?.serverValue, - headers : buildServerHeadersSection(request.headers)].findAll { it.value } - } + private Map buildRequestContent(ServerRequest request) { + return [method : request?.method?.serverValue, + url : request?.url?.serverValue, + urlPattern: request?.urlPattern?.serverValue, + urlPath : request?.urlPath?.serverValue, + headers : buildServerHeadersSection(request.headers)].findAll { it.value } + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index ab62663b51..70429c1ebc 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -10,30 +10,32 @@ import io.coderate.accurest.dsl.internal.ServerResponse @PackageScope class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { - private final Response response + private final Response response - WiremockResponseStubStrategy(GroovyDsl groovyDsl) { - this.response = groovyDsl.response - } + WiremockResponseStubStrategy(GroovyDsl groovyDsl) { + this.response = groovyDsl.response + } - @PackageScope Map buildClientResponseContent() { - return buildResponseContent(new ClientResponse(response)) - } + @PackageScope + Map buildClientResponseContent() { + return buildResponseContent(new ClientResponse(response)) + } - @PackageScope Map buildServerResponseContent() { - return buildResponseContent(new ServerResponse(response)) - } + @PackageScope + Map buildServerResponseContent() { + return buildResponseContent(new ServerResponse(response)) + } - private Map buildResponseContent(ClientResponse response) { - return [status : response?.status?.clientValue, - body : response?.body?.forClientSide(), - headers: buildClientHeadersSection(response.headers)].findAll { it.value } - } + private Map buildResponseContent(ClientResponse response) { + return [status : response?.status?.clientValue, + body : response?.body?.forClientSide(), + headers: buildClientHeadersSection(response.headers)].findAll { it.value } + } - private Map buildResponseContent(ServerResponse response) { - return [status : response?.status?.serverValue, - body : response?.body?.forServerSide(), - headers: buildServerHeadersSection(response.headers)].findAll { it.value } - } + private Map buildResponseContent(ServerResponse response) { + return [status : response?.status?.serverValue, + body : response?.body?.forServerSide(), + headers: buildServerHeadersSection(response.headers)].findAll { it.value } + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy index a3d3924fc0..4888537ec3 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy @@ -6,21 +6,21 @@ import groovy.transform.CompileStatic @CompileStatic class WiremockStubStrategy { - private final WiremockRequestStubStrategy wiremockRequestStubStrategy - private final WiremockResponseStubStrategy wiremockResponseStubStrategy + private final WiremockRequestStubStrategy wiremockRequestStubStrategy + private final WiremockResponseStubStrategy wiremockResponseStubStrategy - WiremockStubStrategy(GroovyDsl groovyDsl) { - this.wiremockRequestStubStrategy = new WiremockRequestStubStrategy(groovyDsl) - this.wiremockResponseStubStrategy = new WiremockResponseStubStrategy(groovyDsl) - } + WiremockStubStrategy(GroovyDsl groovyDsl) { + this.wiremockRequestStubStrategy = new WiremockRequestStubStrategy(groovyDsl) + this.wiremockResponseStubStrategy = new WiremockResponseStubStrategy(groovyDsl) + } - String toWiremockClientStub() { - return JsonOutput.prettyPrint(JsonOutput.toJson([request: wiremockRequestStubStrategy.buildClientRequestContent(), - response: wiremockResponseStubStrategy.buildClientResponseContent()])) - } + String toWiremockClientStub() { + return JsonOutput.prettyPrint(JsonOutput.toJson([request : wiremockRequestStubStrategy.buildClientRequestContent(), + response: wiremockResponseStubStrategy.buildClientResponseContent()])) + } - String toWiremockServerStub() { - return JsonOutput.prettyPrint(JsonOutput.toJson([request: wiremockRequestStubStrategy.buildServerRequestContent(), - response: wiremockResponseStubStrategy.buildServerResponseContent()])) - } + String toWiremockServerStub() { + return JsonOutput.prettyPrint(JsonOutput.toJson([request : wiremockRequestStubStrategy.buildServerRequestContent(), + response: wiremockResponseStubStrategy.buildServerResponseContent()])) + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index dcf033be1d..76723f7fac 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -9,65 +9,65 @@ import org.codehaus.groovy.runtime.GStringImpl @EqualsAndHashCode(includeFields = true) class Body { - private Map body - private DslProperty bodyAsValue - private List bodyAsList + private Map body + private DslProperty bodyAsValue + private List bodyAsList - Body() { - this.body = [:] - } + Body() { + this.body = [:] + } - Body(Map body) { - this.body = body - } + Body(Map body) { + this.body = body + } - Body(List bodyAsList) { - this.bodyAsList = bodyAsList - } + Body(List bodyAsList) { + this.bodyAsList = bodyAsList + } - Body(Object bodyAsValue) { - this.bodyAsValue = new DslProperty(bodyAsValue) - } + Body(Object bodyAsValue) { + this.bodyAsValue = new DslProperty(bodyAsValue) + } - Body(GString bodyAsValue) { - this.bodyAsValue = new DslProperty(getClientValue(bodyAsValue), getServerValue(bodyAsValue)) - } + Body(GString bodyAsValue) { + this.bodyAsValue = new DslProperty(getClientValue(bodyAsValue), getServerValue(bodyAsValue)) + } - private Map getClientValue(GString bodyAsValue) { - GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) - Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } as Object[] - return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString()) - } + private Map getClientValue(GString bodyAsValue) { + GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) + Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } as Object[] + return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString()) + } - private Map getServerValue(GString bodyAsValue) { - GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) - Object[] serverValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.serverValue: it } as Object[] - return new JsonSlurper().parseText(new GStringImpl(serverValues, clientGString.strings).toString()) - } + private Map getServerValue(GString bodyAsValue) { + GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) + Object[] serverValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.serverValue : it } as Object[] + return new JsonSlurper().parseText(new GStringImpl(serverValues, clientGString.strings).toString()) + } - Body(DslProperty bodyAsValue) { - this.bodyAsValue = bodyAsValue - } + Body(DslProperty bodyAsValue) { + this.bodyAsValue = bodyAsValue + } - Object forClientSide() { - if(bodyAsValue) { - return bodyAsValue.clientValue - } else if(bodyAsList) { - bodyAsList.collect { it.clientValue } - } - return body.collectEntries { Map.Entry entry -> - [(entry.key) : entry.value.clientValue] - } as Map - } + Object forClientSide() { + if (bodyAsValue) { + return bodyAsValue.clientValue + } else if (bodyAsList) { + bodyAsList.collect { it.clientValue } + } + return body.collectEntries { Map.Entry entry -> + [(entry.key): entry.value.clientValue] + } as Map + } - Object forServerSide() { - if(bodyAsValue) { - return bodyAsValue.serverValue - } else if(bodyAsList) { - bodyAsList.collect { it.serverValue } - } - return body.collectEntries { Map.Entry entry -> - [(entry.key) : entry.value.serverValue] - } as Map - } + Object forServerSide() { + if (bodyAsValue) { + return bodyAsValue.serverValue + } else if (bodyAsList) { + bodyAsList.collect { it.serverValue } + } + return body.collectEntries { Map.Entry entry -> + [(entry.key): entry.value.serverValue] + } as Map + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy index 5551688e02..7b8525a078 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ClientDslProperty.groovy @@ -1,10 +1,11 @@ package io.coderate.accurest.dsl.internal + import groovy.transform.CompileStatic @CompileStatic class ClientDslProperty extends DslProperty { - ClientDslProperty(Object singleValue) { - super(singleValue) - } + ClientDslProperty(Object singleValue) { + super(singleValue) + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy index 9afb7e115c..9d613c2ef6 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy @@ -11,60 +11,60 @@ import groovy.transform.TypeChecked @PackageScope class Common { - Map convertObjectsToDslProperties(Map body) { - return body.collectEntries { - Map.Entry entry -> - [(entry.key): toDslProperty(entry.value)] - } as Map - } + Map convertObjectsToDslProperties(Map body) { + return body.collectEntries { + Map.Entry entry -> + [(entry.key): toDslProperty(entry.value)] + } as Map + } - List convertObjectsToDslProperties(List body) { - return body.collect { - Object element -> toDslProperty(element) - } as List - } + List convertObjectsToDslProperties(List body) { + return body.collect { + Object element -> toDslProperty(element) + } as List + } - DslProperty toDslProperty(Object property) { - return new DslProperty(property) - } + DslProperty toDslProperty(Object property) { + return new DslProperty(property) + } - DslProperty toDslProperty(Map property) { - return new DslProperty(property.collectEntries { - [(it.key) : toDslProperty(it.value)] - }) - } + DslProperty toDslProperty(Map property) { + return new DslProperty(property.collectEntries { + [(it.key): toDslProperty(it.value)] + }) + } - DslProperty toDslProperty(List property) { - return new DslProperty(property.collect { - toDslProperty(it) - }) - } + DslProperty toDslProperty(List property) { + return new DslProperty(property.collect { + toDslProperty(it) + }) + } - DslProperty toDslProperty(DslProperty property) { - return property - } + DslProperty toDslProperty(DslProperty property) { + return property + } - DslProperty value(ClientDslProperty client, ServerDslProperty server) { - return new DslProperty(client.clientValue, server.serverValue) - } + DslProperty value(ClientDslProperty client, ServerDslProperty server) { + return new DslProperty(client.clientValue, server.serverValue) + } - DslProperty value(ServerDslProperty server, ClientDslProperty client) { - return new DslProperty(client.clientValue, server.serverValue) - } + DslProperty value(ServerDslProperty server, ClientDslProperty client) { + return new DslProperty(client.clientValue, server.serverValue) + } - DslProperty $(ClientDslProperty client, ServerDslProperty server) { - return value(client, server) - } + DslProperty $(ClientDslProperty client, ServerDslProperty server) { + return value(client, server) + } - DslProperty $(ServerDslProperty server, ClientDslProperty client) { - return value(server, client) - } + DslProperty $(ServerDslProperty server, ClientDslProperty client) { + return value(server, client) + } - ClientDslProperty client(Object clientValue) { - return new ClientDslProperty(clientValue) - } + ClientDslProperty client(Object clientValue) { + return new ClientDslProperty(clientValue) + } - ServerDslProperty server(Object serverValue) { - return new ServerDslProperty(serverValue) - } + ServerDslProperty server(Object serverValue) { + return new ServerDslProperty(serverValue) + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy index 6710b90958..d2a58dfbf8 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy @@ -9,16 +9,16 @@ import groovy.transform.ToString @ToString(includePackage = false) class DslProperty { - final T clientValue - final T serverValue + final T clientValue + final T serverValue - DslProperty(T clientValue, T serverValue) { - this.clientValue = clientValue - this.serverValue = serverValue - } + DslProperty(T clientValue, T serverValue) { + this.clientValue = clientValue + this.serverValue = serverValue + } - DslProperty(T singleValue) { - this.clientValue = singleValue - this.serverValue = singleValue - } + DslProperty(T singleValue) { + this.clientValue = singleValue + this.serverValue = singleValue + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index f2b5a5649b..80a848c2b6 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -7,26 +7,26 @@ import groovy.transform.ToString @ToString(includePackage = false, includeFields = true, ignoreNulls = true) class Headers { - private Map assertionHeaders = [:] - private Map valueHeaders = [:] + private Map assertionHeaders = [:] + private Map valueHeaders = [:] - WithValuePattern header(String headerName) { - WithValuePattern withValuePattern = new WithValuePattern() - assertionHeaders[headerName] = withValuePattern - return withValuePattern - } + WithValuePattern header(String headerName) { + WithValuePattern withValuePattern = new WithValuePattern() + assertionHeaders[headerName] = withValuePattern + return withValuePattern + } - void header(Map singleHeader) { - Map.Entry first = singleHeader.entrySet().first() - valueHeaders[first?.key] = first?.value - } + void header(Map singleHeader) { + Map.Entry first = singleHeader.entrySet().first() + valueHeaders[first?.key] = first?.value + } - Map valueHeaders() { - return Collections.unmodifiableMap(valueHeaders) - } + Map valueHeaders() { + return Collections.unmodifiableMap(valueHeaders) + } - Set> assertionEntries() { - return Collections.unmodifiableSet(assertionHeaders.entrySet()) - } + Set> assertionEntries() { + return Collections.unmodifiableSet(assertionHeaders.entrySet()) + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy index 7f07abb723..d4e7e3e15f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/JSONCompareMode.groovy @@ -1,5 +1,5 @@ package io.coderate.accurest.dsl.internal enum JSONCompareMode { - STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER + STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy index 1b12d8b296..a6ff0b9af0 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy @@ -1,4 +1,5 @@ package io.coderate.accurest.dsl.internal + import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @@ -9,76 +10,76 @@ import groovy.transform.TypeChecked @ToString(includePackage = false) class Request extends Common { - DslProperty method - DslProperty url - DslProperty urlPattern - DslProperty urlPath - Headers headers + DslProperty method + DslProperty url + DslProperty urlPattern + DslProperty urlPath + Headers headers - Request() { - } + Request() { + } - Request(Request request) { - this.method = request.method - this.url = request.url - this.urlPattern = request.urlPattern - this.urlPath = request.urlPath - this.headers = request.headers - } + Request(Request request) { + this.method = request.method + this.url = request.url + this.urlPattern = request.urlPattern + this.urlPath = request.urlPath + this.headers = request.headers + } - void method(String method) { - this.method = toDslProperty(method) - } + void method(String method) { + this.method = toDslProperty(method) + } - void method(DslProperty method) { - this.method = toDslProperty(method) - } + void method(DslProperty method) { + this.method = toDslProperty(method) + } - void url(String url) { - this.url = toDslProperty(url) - } + void url(String url) { + this.url = toDslProperty(url) + } - void url(DslProperty url) { - this.url = toDslProperty(url) - } + void url(DslProperty url) { + this.url = toDslProperty(url) + } - void urlPattern(String urlPattern) { - this.urlPattern = toDslProperty(urlPattern) - } + void urlPattern(String urlPattern) { + this.urlPattern = toDslProperty(urlPattern) + } - void urlPattern(DslProperty urlPattern) { - this.urlPattern = toDslProperty(urlPattern) - } + void urlPattern(DslProperty urlPattern) { + this.urlPattern = toDslProperty(urlPattern) + } - void headers(@DelegatesTo(Headers) Closure closure) { - this.headers = new Headers() - closure.delegate = headers - closure() - } + void headers(@DelegatesTo(Headers) Closure closure) { + this.headers = new Headers() + closure.delegate = headers + closure() + } - void urlPath(String urlPath) { - this.urlPath = toDslProperty(urlPath) - } + void urlPath(String urlPath) { + this.urlPath = toDslProperty(urlPath) + } - void urlPath(DslProperty urlPath) { - this.urlPath = toDslProperty(urlPath) - } + void urlPath(DslProperty urlPath) { + this.urlPath = toDslProperty(urlPath) + } } @CompileStatic @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false) class ServerRequest extends Request { - ServerRequest(Request request) { - super(request) - } + ServerRequest(Request request) { + super(request) + } } @CompileStatic @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false) class ClientRequest extends Request { - ClientRequest(Request request) { - super(request) - } + ClientRequest(Request request) { + super(request) + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index 46827b9875..7296a8c2da 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -10,72 +10,72 @@ import groovy.transform.TypeChecked @ToString(includePackage = false, includeFields = true) class Response extends Common { - private DslProperty status - private Headers headers - private Body body = new Body() + private DslProperty status + private Headers headers + private Body body = new Body() - Response() { - } + Response() { + } - Response(Response response) { - this.status = response.status - this.headers = response.headers - this.body = response.body - } + Response(Response response) { + this.status = response.status + this.headers = response.headers + this.body = response.body + } - void status(int status) { - this.status = toDslProperty(status) - } + void status(int status) { + this.status = toDslProperty(status) + } - void status(DslProperty status) { - this.status = toDslProperty(status) - } + void status(DslProperty status) { + this.status = toDslProperty(status) + } - void headers(@DelegatesTo(Headers) Closure closure) { - this.headers = new Headers() - closure.delegate = headers - closure() - } + void headers(@DelegatesTo(Headers) Closure closure) { + this.headers = new Headers() + closure.delegate = headers + closure() + } - void body(Map body) { - this.body = new Body(convertObjectsToDslProperties(body)) - } + void body(Map body) { + this.body = new Body(convertObjectsToDslProperties(body)) + } - void body(List body) { - this.body = new Body(convertObjectsToDslProperties(body)) - } + void body(List body) { + this.body = new Body(convertObjectsToDslProperties(body)) + } - void body(Object bodyAsValue) { - this.body = new Body(bodyAsValue) - } + void body(Object bodyAsValue) { + this.body = new Body(bodyAsValue) + } - Body getBody() { - return body - } + Body getBody() { + return body + } - DslProperty getStatus() { - return status - } + DslProperty getStatus() { + return status + } - Headers getHeaders() { - return headers - } + Headers getHeaders() { + return headers + } } @CompileStatic @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false) class ServerResponse extends Response { - ServerResponse(Response request) { - super(request) - } + ServerResponse(Response request) { + super(request) + } } @CompileStatic @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false) class ClientResponse extends Response { - ClientResponse(Response request) { - super(request) - } + ClientResponse(Response request) { + super(request) + } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy index dad9dec06d..3045736f1b 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/ServerDslProperty.groovy @@ -9,7 +9,7 @@ import groovy.transform.ToString @ToString(includePackage = false) class ServerDslProperty extends DslProperty { - ServerDslProperty(Object singleValue) { - super(singleValue) - } + ServerDslProperty(Object singleValue) { + super(singleValue) + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy index bad8bda88d..0fc53aefb3 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy @@ -9,94 +9,94 @@ import groovy.transform.TypeChecked @ToString(includePackage = false) class WithValuePattern { - DslProperty equalTo - DslProperty equalToJson - DslProperty equalToXml - DslProperty matchesXPath - DslProperty jsonCompareMode - DslProperty contains - DslProperty matches - DslProperty doesNotMatch - DslProperty absent - DslProperty matchesJsonPath + DslProperty equalTo + DslProperty equalToJson + DslProperty equalToXml + DslProperty matchesXPath + DslProperty jsonCompareMode + DslProperty contains + DslProperty matches + DslProperty doesNotMatch + DslProperty absent + DslProperty matchesJsonPath - void equalTo(String equalTo) { - this.equalTo = new DslProperty(equalTo) - } + void equalTo(String equalTo) { + this.equalTo = new DslProperty(equalTo) + } - void equalTo(DslProperty equalTo) { - this.equalTo = equalTo - } + void equalTo(DslProperty equalTo) { + this.equalTo = equalTo + } - void equalToJson(String equalToJson) { - this.equalToJson = new DslProperty(equalToJson) - } + void equalToJson(String equalToJson) { + this.equalToJson = new DslProperty(equalToJson) + } - void equalToJson(DslProperty equalToJson) { - this.equalToJson = equalToJson - } + void equalToJson(DslProperty equalToJson) { + this.equalToJson = equalToJson + } - void equalToXml(String equalToXml) { - this.equalToXml = new DslProperty(equalToXml) - } + void equalToXml(String equalToXml) { + this.equalToXml = new DslProperty(equalToXml) + } - void equalToXml(DslProperty equalToXml) { - this.equalToXml = equalToXml - } + void equalToXml(DslProperty equalToXml) { + this.equalToXml = equalToXml + } - void matchesXPath(String matchesXPath) { - this.matchesXPath = new DslProperty(matchesXPath) - } + void matchesXPath(String matchesXPath) { + this.matchesXPath = new DslProperty(matchesXPath) + } - void matchesXPath(DslProperty matchesXPath) { - this.matchesXPath = matchesXPath - } + void matchesXPath(DslProperty matchesXPath) { + this.matchesXPath = matchesXPath + } - void jsonCompareMode(JSONCompareMode jsonCompareMode) { - this.jsonCompareMode = new DslProperty(jsonCompareMode) - } + void jsonCompareMode(JSONCompareMode jsonCompareMode) { + this.jsonCompareMode = new DslProperty(jsonCompareMode) + } - void jsonCompareMode(DslProperty jsonCompareMode) { - this.jsonCompareMode = jsonCompareMode - } + void jsonCompareMode(DslProperty jsonCompareMode) { + this.jsonCompareMode = jsonCompareMode + } - void contains(String contains) { - this.contains = new DslProperty(contains) - } + void contains(String contains) { + this.contains = new DslProperty(contains) + } - void contains(DslProperty contains) { - this.contains = contains - } + void contains(DslProperty contains) { + this.contains = contains + } - void matches(String matches) { - this.matches = new DslProperty(matches) - } + void matches(String matches) { + this.matches = new DslProperty(matches) + } - void matches(DslProperty matches) { - this.matches = matches - } + void matches(DslProperty matches) { + this.matches = matches + } - void doesNotMatch(String doesNotMatch) { - this.doesNotMatch = new DslProperty(doesNotMatch) - } + void doesNotMatch(String doesNotMatch) { + this.doesNotMatch = new DslProperty(doesNotMatch) + } - void doesNotMatch(DslProperty doesNotMatch) { - this.doesNotMatch = doesNotMatch - } + void doesNotMatch(DslProperty doesNotMatch) { + this.doesNotMatch = doesNotMatch + } - void absent(String absent) { - this.absent = new DslProperty(absent) - } + void absent(String absent) { + this.absent = new DslProperty(absent) + } - void absent(DslProperty absent) { - this.absent = absent - } + void absent(DslProperty absent) { + this.absent = absent + } - void matchesJsonPath(String matchesJsonPath) { - this.matchesJsonPath = new DslProperty(matchesJsonPath) - } + void matchesJsonPath(String matchesJsonPath) { + this.matchesJsonPath = new DslProperty(matchesJsonPath) + } - void matchesJsonPath(DslProperty matchesJsonPath) { - this.matchesJsonPath = matchesJsonPath - } + void matchesJsonPath(DslProperty matchesJsonPath) { + this.matchesJsonPath = matchesJsonPath + } } diff --git a/accurest-core/src/main/resources/stubs/wiremocks/sample.json b/accurest-core/src/main/resources/stubs/wiremocks/sample.json index 97eaaa3cdb..92da92f7da 100644 --- a/accurest-core/src/main/resources/stubs/wiremocks/sample.json +++ b/accurest-core/src/main/resources/stubs/wiremocks/sample.json @@ -9,7 +9,7 @@ }, "bodyPatterns": [ { - "matches": "\\{\"clientPesel\":\"1234567890\",\"loanAmount\":123.123\\}" + "matches": "\\{\"clientPesel\":\"1234567890\",\"loanAmount\":123.123\\}" } ] }, 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 19e1914a8a..3c32375e38 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy @@ -11,7 +11,7 @@ class MainTest { stubsBaseDirectory: '/home/devel/projects/codearte/accurest/accurest-core/src/main/resources/stubs', generatedTestSourcesDir: '/tmp/accurest', targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', - staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], ignoredFiles: ["**/other"]) + staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], ignoredFiles: ["**/other"]) println new TestGenerator(properties).generate() } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy index f639dfe1cd..e952e74082 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy @@ -10,7 +10,7 @@ class TestGeneratorSpec extends Specification { private SingleTestGenerator classGenerator = Mock(SingleTestGenerator) - def "should find all .json files and generate 3 classes for them"() { + def "should find all .json files and generate 3 classes for them"() { given: File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() @@ -22,7 +22,7 @@ class TestGeneratorSpec extends Specification { 3 * classGenerator.buildClass(_, _, _) >> "qwerty" } - def "should filter other directory"() { + def "should filter other directory"() { given: File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() @@ -35,7 +35,7 @@ class TestGeneratorSpec extends Specification { 1 * classGenerator.buildClass(_, 'different', _) >> "qwerty" } - def "should ignore file"() { + def "should ignore file"() { given: File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() 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 f8aa6a6890..400ceadbf9 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 @@ -7,42 +7,42 @@ import spock.lang.Specification class WiremockGroovyDslResponseSpec extends Specification { - def 'should generate response without body for #side side'() { - given: - GroovyDsl dsl = GroovyDsl.make { - response { - status 200 - } - } - expect: - new WiremockResponseStubStrategy(dsl)."build${side}ResponseContent"() == new JsonSlurper().parseText(expectedStub) - where: - side << ['Client', 'Server'] - expectedStub << [''' + def 'should generate response without body for #side side'() { + given: + GroovyDsl dsl = GroovyDsl.make { + response { + status 200 + } + } + expect: + new WiremockResponseStubStrategy(dsl)."build${side}ResponseContent"() == new JsonSlurper().parseText(expectedStub) + where: + side << ['Client', 'Server'] + expectedStub << [''' { "status": 200 } ''', - ''' + ''' { "status": 200 } '''] - } + } - def 'should generate headers for response for client side'() { - given: - GroovyDsl dsl = GroovyDsl.make { - response { - headers { - header('Content-Type').matches $(client('text/xml'), server('text/*')) - } - status 200 - } - } - expect: - new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(''' + def 'should generate headers for response for client side'() { + given: + GroovyDsl dsl = GroovyDsl.make { + response { + headers { + header('Content-Type').matches $(client('text/xml'), server('text/*')) + } + status 200 + } + } + expect: + new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(''' { "headers": { "Content-Type": { @@ -52,20 +52,20 @@ class WiremockGroovyDslResponseSpec extends Specification { "status": 200 } ''') - } + } - def 'should generate headers for response for server side'() { - given: - GroovyDsl dsl = GroovyDsl.make { - response { - status 200 - headers { - header('Content-Type').matches $(client('text/xml'), server('text/*')) - } - } - } - expect: - new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText(''' + def 'should generate headers for response for server side'() { + given: + GroovyDsl dsl = GroovyDsl.make { + response { + status 200 + headers { + header('Content-Type').matches $(client('text/xml'), server('text/*')) + } + } + } + expect: + new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText(''' { "status": 200, "headers": { @@ -75,20 +75,20 @@ class WiremockGroovyDslResponseSpec extends Specification { } } ''') - } + } - def 'should generate an exact header for response for both sides '() { - given: - GroovyDsl dsl = GroovyDsl.make { - response { - status 200 - headers { - header 'Content-Type': 'text/xml' - } - } - } - expect: - new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText(''' + def 'should generate an exact header for response for both sides '() { + given: + GroovyDsl dsl = GroovyDsl.make { + response { + status 200 + headers { + header 'Content-Type': 'text/xml' + } + } + } + expect: + new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText(''' { "status": 200, "headers": { @@ -96,5 +96,5 @@ 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 9740c6f40e..c68b5643ec 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -9,36 +9,36 @@ import spock.lang.Specification class WiremockGroovyDslSpec extends Specification { - def 'should convert groovy dsl stub to wiremock stub for the client side'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - body ( - id : value( - client('123'), - server({ regex('[0-9]+') }) - ), - surname : $( - client('Kowalsky'), - server('Lewandowski') - ), - name: 'Jan', - created : $(client('2014-02-02 12:23:43'), server({ currentDate(it) })) - ) - headers { - header 'Content-Type': 'text/plain' - } - } - } - when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + def 'should convert groovy dsl stub to wiremock stub for the client side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body( + id: value( + client('123'), + server({ regex('[0-9]+') }) + ), + surname: $( + client('Kowalsky'), + server('Lewandowski') + ), + name: 'Jan', + created: $(client('2014-02-02 12:23:43'), server({ currentDate(it) })) + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -58,35 +58,35 @@ class WiremockGroovyDslSpec extends Specification { } } ''') - } + } - def 'should convert groovy dsl stub with Body as String to wiremock stub for the client side'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - body ("""\ + def 'should convert groovy dsl stub with Body as String to wiremock stub for the client side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body("""\ { - "id": "${value(client('123'),server('321'))}", - "surname": "${value(client('Kowalsky'),server('Lewandowski'))}", + "id": "${value(client('123'), server('321'))}", + "surname": "${value(client('Kowalsky'), server('Lewandowski'))}", "name": "Jan", "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" } """ - ) - headers { - header 'Content-Type': 'text/plain' - } - } - } - when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -106,35 +106,35 @@ class WiremockGroovyDslSpec extends Specification { } } ''') - } + } - def 'should convert groovy dsl stub with Body as String to wiremock stub for the server side'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - body ("""\ + def 'should convert groovy dsl stub with Body as String to wiremock stub for the server side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body("""\ { - "id": "${value(client('123'),server('321'))}", - "surname": "${value(client('Kowalsky'),server('Lewandowski'))}", + "id": "${value(client('123'), server('321'))}", + "surname": "${value(client('Kowalsky'), server('Lewandowski'))}", "name": "Jan", "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" } """ - ) - headers { - header 'Content-Type': 'text/plain' - } - } - } - when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -154,38 +154,38 @@ class WiremockGroovyDslSpec extends Specification { } } ''') - } + } - def 'should convert groovy dsl stub to wiremock stub for the server side'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status(200) - body ( - id : value( - client('123'), - server('321') - ), - surname : $( - client('Kowalsky'), - server('Lewandowski') - ), - name: 'Jan', - created : $(client('2014-02-02 12:23:43'), server('1999-01-01 01:23:45')) - ) - headers { - header('Content-Type': 'text/plain') - } - } - } - when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + def 'should convert groovy dsl stub to wiremock stub for the server side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status(200) + body( + id: value( + client('123'), + server('321') + ), + surname: $( + client('Kowalsky'), + server('Lewandowski') + ), + name: 'Jan', + created: $(client('2014-02-02 12:23:43'), server('1999-01-01 01:23:45')) + ) + headers { + header('Content-Type': 'text/plain') + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -205,129 +205,129 @@ class WiremockGroovyDslSpec extends Specification { } } ''') - } + } - def "should generate stub with GET"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method("GET") - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + def "should generate stub with GET"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method("GET") + } + } + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "method":"GET" } ''') - } + } - def "should generate request when two elements are provided "() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method("GET") - url("/sth") - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + def "should generate request when two elements are provided "() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method("GET") + url("/sth") + } + } + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "method":"GET", "url":"/sth" } ''') - } + } - def "should generate request with urlPattern for client side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - urlPattern $( - client('/^[0-9]{2}$'), - server('/12') - ) - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + def "should generate request with urlPattern for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + urlPattern $( + client('/^[0-9]{2}$'), + server('/12') + ) + } + } + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "urlPattern":"/^[0-9]{2}$" } ''') - } + } - def "should generate stub with urlPattern for server side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - urlPattern $( - client('/[0-9]{2}'), - server('/12') - ) - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText(''' + def "should generate stub with urlPattern for server side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + urlPattern $( + client('/[0-9]{2}'), + server('/12') + ) + } + } + expect: + new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText(''' { "urlPattern":"/12" } ''') - } + } - def "should generate stub with urlPath for client side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - urlPath ('/12') - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + def "should generate stub with urlPath for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + urlPath('/12') + } + } + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "urlPath":"/12" } ''') - } + } - def "should generate stub with urlPath for server side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - urlPath ('/12') - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + def "should generate stub with urlPath for server side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + urlPath('/12') + } + } + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "urlPath":"/12" } ''') - } + } - def "should generate stub with some headers section for client side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - headers { - header('Content-Type').equalTo('text/xml') - header('Accept').matches $( - client('text/.*'), - server('text/plain') - ) - header('etag').doesNotMatch $( - client('abcd.*'), - server('abcdef') - ) - header('X-Custom-Header').contains $( - client('2134'), - server('121345') - ) - } - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + def "should generate stub with some headers section for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + headers { + header('Content-Type').equalTo('text/xml') + header('Accept').matches $( + client('text/.*'), + server('text/plain') + ) + header('etag').doesNotMatch $( + client('abcd.*'), + server('abcdef') + ) + header('X-Custom-Header').contains $( + client('2134'), + server('121345') + ) + } + } + } + expect: + new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "headers": { "Content-Type": { @@ -345,31 +345,31 @@ class WiremockGroovyDslSpec extends Specification { } } ''') - } + } - def "should generate stub with some headers section for server side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - headers { - header('Content-Type').equalTo('text/xml') - header('Accept').matches $( - client('text/.*'), - server('text/plain') - ) - header('etag').doesNotMatch $( - client('abcd.*'), - server('abcdef') - ) - header('X-Custom-Header').contains $( - client('2134'), - server('121345') - ) - } - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText(''' + def "should generate stub with some headers section for server side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + headers { + header('Content-Type').equalTo('text/xml') + header('Accept').matches $( + client('text/.*'), + server('text/plain') + ) + header('etag').doesNotMatch $( + client('abcd.*'), + server('abcdef') + ) + header('X-Custom-Header').contains $( + client('2134'), + server('121345') + ) + } + } + } + expect: + new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText(''' { "headers": { "Content-Type": { @@ -387,11 +387,11 @@ class WiremockGroovyDslSpec extends Specification { } } ''') - } + } - @Ignore("Not implemented yet") - def "should generate stub with request body matching for server side"() {} + @Ignore("Not implemented yet") + def "should generate stub with request body matching for server side"() {} - @Ignore("Not implemented yet") - def "should generate stub with request query parameter matching for server side"() {} + @Ignore("Not implemented yet") + def "should generate stub with request query parameter matching for server side"() {} } 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 cc0c2b288e..3294fc22fe 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 @@ -11,8 +11,10 @@ import org.gradle.api.tasks.TaskAction class GenerateServerTestsTask extends DefaultTask { - @InputDirectory File groovyDslDir - @OutputDirectory File generatedTestSourcesDir + @InputDirectory + File groovyDslDir + @OutputDirectory + File generatedTestSourcesDir //TODO: How to deal with @Input*, @Output* and that domain object? AccurestConfigProperties configProperties diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy index 46111dc736..8805992dda 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy @@ -9,8 +9,10 @@ import org.gradle.api.tasks.TaskAction //TODO: Implement as an incremental task: https://gradle.org/docs/current/userguide/custom_tasks.html#incremental_tasks ? class GenerateWiremockClientStubsFromDslTask extends DefaultTask { - @InputDirectory File groovyDslDir - @InputDirectory File generatedWiremockClientStubsDir + @InputDirectory + File groovyDslDir + @InputDirectory + File generatedWiremockClientStubsDir @TaskAction void generate() { From 614f5438a887f6f67e4a190f1b5f5171b3814cd7 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 13:16:04 +0100 Subject: [PATCH 059/719] Fix #24 - GroovyDSL -> JSON - issue with new lines --- .../accurest/dsl/internal/Body.groovy | 2 +- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index 76723f7fac..f9442d0a8a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -26,7 +26,7 @@ class Body { } Body(Object bodyAsValue) { - this.bodyAsValue = new DslProperty(bodyAsValue) + this("${bodyAsValue}") } Body(GString bodyAsValue) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy index c68b5643ec..6022b95d4d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -108,6 +108,48 @@ class WiremockGroovyDslSpec extends Specification { ''') } + def 'should convert groovy dsl stub with simple Body as String to wiremock stub for the client side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body("""\ + { + "name": "Jan" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}" + }, + "response": { + "status": 200, + "body": { + "name": "Jan" + }, + "headers": { + "Content-Type": "text/plain" + } + } +} +''') + } + def 'should convert groovy dsl stub with Body as String to wiremock stub for the server side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From bb360c95e9be406e6b5e434d4ee7e94f99d523a8 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 14:14:45 +0100 Subject: [PATCH 060/719] Fixed body parsing - support for lists --- .../main/groovy/io/coderate/accurest/dsl/internal/Body.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index f9442d0a8a..a61b09e3ac 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -33,13 +33,13 @@ class Body { this.bodyAsValue = new DslProperty(getClientValue(bodyAsValue), getServerValue(bodyAsValue)) } - private Map getClientValue(GString bodyAsValue) { + private def getClientValue(GString bodyAsValue) { GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } as Object[] return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString()) } - private Map getServerValue(GString bodyAsValue) { + private def getServerValue(GString bodyAsValue) { GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) Object[] serverValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.serverValue : it } as Object[] return new JsonSlurper().parseText(new GStringImpl(serverValues, clientGString.strings).toString()) From 845f121a0c4324c2a36e66db51586a40441e2bc2 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 14:21:18 +0100 Subject: [PATCH 061/719] Extracted class naming configuration to framework enum --- .../io/coderate/accurest/FileSaver.groovy | 9 +-------- .../accurest/config/TestFramework.groovy | 17 +++++++++++++++-- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy index dd393993a6..1c12c01c93 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy @@ -25,16 +25,9 @@ class FileSaver { def testBaseDir = Paths.get(targetDirectory.absolutePath, NamesUtil.packageToDirectory(packageName)) Files.createDirectories(testBaseDir) - def classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + getTestClassSuffix() + getTestClassExtension()) + def classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + framework.classNameSuffix + framework.classExtension) .toAbsolutePath() Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) } - private String getTestClassSuffix() { - return framework == TestFramework.SPOCK ? 'Spec' : 'Test' - } - - private String getTestClassExtension() { - return framework == TestFramework.SPOCK ? '.groovy' : '.java' - } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy index 82e3b3ac90..af5af4a47c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/TestFramework.groovy @@ -4,16 +4,21 @@ package io.coderate.accurest.config * @author Jakub Kubrynski */ enum TestFramework { - JUNIT("public ", "public void ", ";"), SPOCK("", "def ", "") + JUNIT("public ", "public void ", ";", ".java", "Test"), + SPOCK("", "def ", "", ".groovy", "Spec") private final String classModifier private final String methodModifier private final String lineSuffix + private final String classExtension; + private final String classNameSuffix; - TestFramework(String classModifier, String methodModifier, String lineSuffix) { + TestFramework(String classModifier, String methodModifier, String lineSuffix, String classExtension, String classNameSuffix) { this.classModifier = classModifier this.lineSuffix = lineSuffix this.methodModifier = methodModifier + this.classExtension = classExtension + this.classNameSuffix = classNameSuffix } String getClassModifier() { @@ -27,4 +32,12 @@ enum TestFramework { String getLineSuffix() { return lineSuffix } + + String getClassExtension() { + return classExtension + } + + String getClassNameSuffix() { + return classNameSuffix + } } \ No newline at end of file From 672cad956c8a45de117314949870a61338c6a045 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 15:29:40 +0100 Subject: [PATCH 062/719] Request now contains body --- .../dsl/WiremockRequestStubStrategy.groovy | 8 ++++++-- .../accurest/dsl/internal/Request.groovy | 18 ++++++++++++++++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 11 ++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 0bee93bfad..e8396e15c7 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -31,7 +31,9 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { url : request?.url?.clientValue, urlPattern: request?.urlPattern?.clientValue, urlPath : request?.urlPath?.clientValue, - headers : buildClientHeadersSection(request.headers)].findAll { it.value } + headers : buildClientHeadersSection(request.headers), + body : request?.body?.forClientSide() + ].findAll { it.value } } private Map buildRequestContent(ServerRequest request) { @@ -39,6 +41,8 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { url : request?.url?.serverValue, urlPattern: request?.urlPattern?.serverValue, urlPath : request?.urlPath?.serverValue, - headers : buildServerHeadersSection(request.headers)].findAll { it.value } + headers : buildServerHeadersSection(request.headers), + body : request?.body?.forServerSide() + ].findAll { it.value } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy index a6ff0b9af0..bb8ae5b9bf 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy @@ -15,6 +15,7 @@ class Request extends Common { DslProperty urlPattern DslProperty urlPath Headers headers + Body body Request() { } @@ -25,6 +26,7 @@ class Request extends Common { this.urlPattern = request.urlPattern this.urlPath = request.urlPath this.headers = request.headers + this.body = request.body } void method(String method) { @@ -64,6 +66,22 @@ class Request extends Common { void urlPath(DslProperty urlPath) { this.urlPath = toDslProperty(urlPath) } + + void body(Map body) { + this.body = new Body(convertObjectsToDslProperties(body)) + } + + void body(List body) { + this.body = new Body(convertObjectsToDslProperties(body)) + } + + void body(Object bodyAsValue) { + this.body = new Body(bodyAsValue) + } + + Body getBody() { + return body + } } @CompileStatic 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 6022b95d4d..47e6a7cfd1 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -114,6 +114,12 @@ class WiremockGroovyDslSpec extends Specification { request { method('GET') urlPattern $(client('/[0-9]{2}'), server('/12')) + body("""\ + { + "name": "Jan" + } + """ + ) } response { status 200 @@ -135,7 +141,10 @@ class WiremockGroovyDslSpec extends Specification { { "request": { "method": "GET", - "urlPattern": "/[0-9]{2}" + "urlPattern": "/[0-9]{2}", + "body": { + "name": "Jan" + } }, "response": { "status": 200, From d19425cfc4e9a09368bb23fee7d549099a2175ee Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 15:31:14 +0100 Subject: [PATCH 063/719] Release version 0.3.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index e0130574b9..bbd32795df 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.3.1-SNAPSHOT' + projectVersion = '0.3.1' projectGroup = 'io.codearte.accurest' } From e7d1b4501f1f1237dc14c6572aff13182e682315 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 15:32:36 +0100 Subject: [PATCH 064/719] Next development version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bbd32795df..17393b0345 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.3.1' + projectVersion = '0.3.2-SNAPSHOT' projectGroup = 'io.codearte.accurest' } From 71789a6031e654ef6caf593d27fd57d4b2a8ed34 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 16:51:18 +0100 Subject: [PATCH 065/719] Body object now extends DslProperty --- .../WiremockToDslConverterSpec.groovy | 1 - .../dsl/WiremockRequestStubStrategy.groovy | 4 +- .../dsl/WiremockResponseStubStrategy.groovy | 4 +- .../accurest/dsl/internal/Body.groovy | 54 ++++++------------- 4 files changed, 21 insertions(+), 42 deletions(-) diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index ad551f3272..63ba9ad92b 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -219,7 +219,6 @@ class WiremockToDslConverterSpec extends Specification { ]) headers { header 'Content-Type': 'application/json' - } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index e8396e15c7..d572d30a61 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -32,7 +32,7 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { urlPattern: request?.urlPattern?.clientValue, urlPath : request?.urlPath?.clientValue, headers : buildClientHeadersSection(request.headers), - body : request?.body?.forClientSide() + body : request?.body?.clientValue ].findAll { it.value } } @@ -42,7 +42,7 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { urlPattern: request?.urlPattern?.serverValue, urlPath : request?.urlPath?.serverValue, headers : buildServerHeadersSection(request.headers), - body : request?.body?.forServerSide() + body : request?.body?.serverValue ].findAll { it.value } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index 70429c1ebc..740a3e69a1 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -28,13 +28,13 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { private Map buildResponseContent(ClientResponse response) { return [status : response?.status?.clientValue, - body : response?.body?.forClientSide(), + body : response?.body?.clientValue, headers: buildClientHeadersSection(response.headers)].findAll { it.value } } private Map buildResponseContent(ServerResponse response) { return [status : response?.status?.serverValue, - body : response?.body?.forServerSide(), + body : response?.body?.serverValue, headers: buildServerHeadersSection(response.headers)].findAll { it.value } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index a61b09e3ac..6dd1939fb5 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -7,22 +7,23 @@ import org.codehaus.groovy.runtime.GStringImpl @ToString(includePackage = false, includeFields = true) @EqualsAndHashCode(includeFields = true) -class Body { - - private Map body - private DslProperty bodyAsValue - private List bodyAsList +class Body extends DslProperty { Body() { - this.body = [:] + super(null) } Body(Map body) { - this.body = body + super(body.collectEntries { Map.Entry entry -> + [(entry.key): entry.value.clientValue] + } as Map, + body.collectEntries { Map.Entry entry -> + [(entry.key): entry.value.serverValue] + } as Map) } Body(List bodyAsList) { - this.bodyAsList = bodyAsList + super(bodyAsList.collect { it.clientValue }, bodyAsList.collect { it.serverValue }) } Body(Object bodyAsValue) { @@ -30,44 +31,23 @@ class Body { } Body(GString bodyAsValue) { - this.bodyAsValue = new DslProperty(getClientValue(bodyAsValue), getServerValue(bodyAsValue)) + super(extractClientValue(bodyAsValue), extractServerValue(bodyAsValue)) } - private def getClientValue(GString bodyAsValue) { + Body(DslProperty bodyAsValue) { + super(bodyAsValue.clientValue, bodyAsValue.serverValue) + } + + private static def extractClientValue(GString bodyAsValue) { GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } as Object[] return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString()) } - private def getServerValue(GString bodyAsValue) { + private static def extractServerValue(GString bodyAsValue) { GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) Object[] serverValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.serverValue : it } as Object[] return new JsonSlurper().parseText(new GStringImpl(serverValues, clientGString.strings).toString()) } - - Body(DslProperty bodyAsValue) { - this.bodyAsValue = bodyAsValue - } - - Object forClientSide() { - if (bodyAsValue) { - return bodyAsValue.clientValue - } else if (bodyAsList) { - bodyAsList.collect { it.clientValue } - } - return body.collectEntries { Map.Entry entry -> - [(entry.key): entry.value.clientValue] - } as Map - } - - Object forServerSide() { - if (bodyAsValue) { - return bodyAsValue.serverValue - } else if (bodyAsList) { - bodyAsList.collect { it.serverValue } - } - return body.collectEntries { Map.Entry entry -> - [(entry.key): entry.value.serverValue] - } as Map - } + } From 52622fd9923851c14e5c69e9f94ad5058a6ad523 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 17:08:12 +0100 Subject: [PATCH 066/719] Body refactoring --- .../accurest/dsl/internal/Body.groovy | 27 +++++++------------ .../accurest/dsl/internal/Response.groovy | 2 +- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index 6dd1939fb5..63003589f0 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -9,17 +9,14 @@ import org.codehaus.groovy.runtime.GStringImpl @EqualsAndHashCode(includeFields = true) class Body extends DslProperty { - Body() { - super(null) + Body(Map body) { + super(extractValue(body, {it.clientValue}), extractValue(body, {it.serverValue})) } - Body(Map body) { - super(body.collectEntries { Map.Entry entry -> - [(entry.key): entry.value.clientValue] - } as Map, - body.collectEntries { Map.Entry entry -> - [(entry.key): entry.value.serverValue] - } as Map) + private static Map extractValue(Map body, Closure valueProvider) { + body.collectEntries { Map.Entry entry -> + [(entry.key): valueProvider(entry.value)] + } as Map } Body(List bodyAsList) { @@ -31,23 +28,17 @@ class Body extends DslProperty { } Body(GString bodyAsValue) { - super(extractClientValue(bodyAsValue), extractServerValue(bodyAsValue)) + super(extractValue(bodyAsValue, {it.clientValue}), extractValue(bodyAsValue, {it.serverValue})) } Body(DslProperty bodyAsValue) { super(bodyAsValue.clientValue, bodyAsValue.serverValue) } - private static def extractClientValue(GString bodyAsValue) { + private static Object extractValue(GString bodyAsValue, Closure valueProvider) { GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) - Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } as Object[] + Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[] return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString()) } - - private static def extractServerValue(GString bodyAsValue) { - GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) - Object[] serverValues = bodyAsValue.values.collect { it instanceof DslProperty ? it.serverValue : it } as Object[] - return new JsonSlurper().parseText(new GStringImpl(serverValues, clientGString.strings).toString()) - } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy index 7296a8c2da..bb9a224de8 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Response.groovy @@ -12,7 +12,7 @@ class Response extends Common { private DslProperty status private Headers headers - private Body body = new Body() + private Body body Response() { } From 1af2964d2e515c00387166cf5665d9af81b7d8b5 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 17:49:36 +0100 Subject: [PATCH 067/719] Genrating server tests from Groovy DSL --- .../io/coderate/accurest/TestGenerator.groovy | 2 +- .../accurest/builder/MethodBuilder.groovy | 8 +++-- .../builder/SpockMethodBodyBuilder.groovy | 30 ++++++++++--------- .../io/codearte/accurest/MainTest.groovy | 4 +-- .../accurest/TestGeneratorSpec.groovy | 5 ++-- .../different/{diff.json => diff.groovy} | 0 .../different/{diff.json => diff.groovy} | 0 .../stubs/other/{other.json => other.groovy} | 0 .../other/{sample.json => sample.groovy} | 0 .../test/resources/dsl/basic/sampleDsl.groovy | 27 +++++++++++++++++ 10 files changed, 54 insertions(+), 22 deletions(-) rename accurest-core/src/test/resources/directory/with/stubs/different/{diff.json => diff.groovy} (100%) rename accurest-core/src/test/resources/directory/with/stubs/other/different/{diff.json => diff.groovy} (100%) rename accurest-core/src/test/resources/directory/with/stubs/other/{other.json => other.groovy} (100%) rename accurest-core/src/test/resources/directory/with/stubs/other/{sample.json => sample.groovy} (100%) create mode 100644 accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index a8dca060f4..105d102446 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -56,7 +56,7 @@ class TestGenerator { if (!includedDirectoryRelativePath.isEmpty()) { List filesToClass = directoryScanner.includedFiles. grep { String includedFile -> - return includedFile.matches(includedDirectoryRelativePath + File.separator + "[A-Za-z0-9]*\\.json") + return includedFile.matches(includedDirectoryRelativePath + File.separator + "[A-Za-z0-9]*\\.groovy") } .collect { return new File(configProperties.stubsBaseDirectory, it) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy index 951d1ebd5d..43d8046e1d 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy @@ -1,6 +1,8 @@ package io.coderate.accurest.builder import io.coderate.accurest.config.TestFramework +import io.coderate.accurest.dsl.GroovyDsl +import io.coderate.accurest.dsl.WiremockStubStrategy import io.coderate.accurest.util.NamesUtil import io.coderate.accurest.util.StubMappingConverter @@ -10,17 +12,17 @@ import io.coderate.accurest.util.StubMappingConverter class MethodBuilder { private final String methodName - private final Map stubContent + private final GroovyDsl stubContent private final TestFramework lang - private MethodBuilder(String methodName, Map stubContent, TestFramework lang) { + private MethodBuilder(String methodName, GroovyDsl stubContent, TestFramework lang) { this.stubContent = stubContent this.methodName = methodName this.lang = lang } static MethodBuilder createTestMethod(File stubsFile, TestFramework lang) { - Map stubContent = StubMappingConverter.toStubMappingOnServerSide(stubsFile) + GroovyDsl stubContent = new GroovyShell(this.classLoader).evaluate(stubsFile) String methodName = NamesUtil.camelCase(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) return new MethodBuilder(methodName, stubContent, lang) } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 93b2afe581..79cdf0998e 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,15 +1,18 @@ package io.coderate.accurest.builder +import groovy.json.JsonOutput +import groovy.json.JsonSlurper import groovy.transform.PackageScope +import io.coderate.accurest.dsl.GroovyDsl /** * @author Jakub Kubrynski */ @PackageScope class SpockMethodBodyBuilder { - private final Map stubDefinition + private final GroovyDsl stubDefinition - SpockMethodBodyBuilder(Map stubDefinition) { + SpockMethodBodyBuilder(GroovyDsl stubDefinition) { this.stubDefinition = stubDefinition } @@ -18,12 +21,11 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('given:').startBlock() blockBuilder.addLine('def request = given()') blockBuilder.indent() - stubDefinition.request.headers.each { - blockBuilder.addLine(".header('$it.key', '$it.value.equalTo')") + stubDefinition.request.headers.valueHeaders().each { + blockBuilder.addLine(".header('$it.key', '$it.value')") } - if (stubDefinition.request.bodyPatterns) { - String matches = stubDefinition.request.bodyPatterns[0].matches - matches = matches.replaceAll('\\\\', ''); + if (stubDefinition.request.body) { + String matches = new JsonOutput().toJson(stubDefinition.request.body.serverValue) blockBuilder.addLine(".body('$matches')") } @@ -32,28 +34,28 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('when:').startBlock() blockBuilder.addLine('def response = given().spec(request)') blockBuilder.indent() - blockBuilder.addLine(".${stubDefinition.request.method.toLowerCase()}(\"$stubDefinition.request.url\")") + blockBuilder.addLine(".${stubDefinition.request.method.serverValue.toLowerCase()}(\"$stubDefinition.request.urlPattern.serverValue\")") blockBuilder.unindent().endBlock().addEmptyLine() blockBuilder.addLine('then:').startBlock() - blockBuilder.addLine("response.statusCode == $stubDefinition.response.status") + blockBuilder.addLine("response.statusCode == $stubDefinition.response.status.serverValue") - stubDefinition.response.headers.each { + stubDefinition.response.headers?.valueHeaders().each { blockBuilder.addLine("response.header('$it.key') == '$it.value'") } if (stubDefinition.response.body) { blockBuilder.addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') - stubDefinition.response.body.each { + stubDefinition.response.body.serverValue.each { def value = it.value if (value instanceof String) { if (value.startsWith('$')) { - value = value.substring(1).replaceAll('\\$it', "responseBody.$it.key") + value = value.substring(1).replaceAll('\\$value', "responseBody.$it.key") blockBuilder.addLine(value) } else { - blockBuilder.addLine("responseBody.$it.key == \"$value\"") + blockBuilder.addLine("responseBody.$it.key == \"${value}\"") } } else { - blockBuilder.addLine("responseBody.$it.key == $value") + blockBuilder.addLine("responseBody.$it.key == ${value}") } } } 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 3c32375e38..27b9ec796d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy @@ -8,8 +8,8 @@ import io.coderate.accurest.config.TestMode class MainTest { public static void main(String[] args) { AccurestConfigProperties properties = new AccurestConfigProperties( - stubsBaseDirectory: '/home/devel/projects/codearte/accurest/accurest-core/src/main/resources/stubs', - generatedTestSourcesDir: '/tmp/accurest', + stubsBaseDirectory: new File('/home/devel/projects/codearte/accurest/accurest-core/src/test/resources/dsl'), + generatedTestSourcesDir: new File('/tmp/accurest'), targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], ignoredFiles: ["**/other"]) println new TestGenerator(properties).generate() diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy index e952e74082..0fcb65fe50 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy @@ -4,6 +4,7 @@ import io.coderate.accurest.FileSaver import io.coderate.accurest.SingleTestGenerator import io.coderate.accurest.TestGenerator import io.coderate.accurest.config.AccurestConfigProperties +import spock.lang.Ignore import spock.lang.Specification class TestGeneratorSpec extends Specification { @@ -39,13 +40,13 @@ class TestGeneratorSpec extends Specification { given: File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() - properties.ignoredFiles << "**/other.json" + properties.ignoredFiles << "**/other.groovy" properties.stubsBaseDirectory = resource.parentFile TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) classGenerator.buildClass(_, _, _) >> "sample" when: testGenerator.generateTestClasses("com.ofg") then: - 1 * classGenerator.buildClass({ it.size() == 1 }, 'other', _) >> "sample.json" + 1 * classGenerator.buildClass({ it.size() == 1 }, 'other', _) >> "sample.groovy" } } diff --git a/accurest-core/src/test/resources/directory/with/stubs/different/diff.json b/accurest-core/src/test/resources/directory/with/stubs/different/diff.groovy similarity index 100% rename from accurest-core/src/test/resources/directory/with/stubs/different/diff.json rename to accurest-core/src/test/resources/directory/with/stubs/different/diff.groovy diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/different/diff.json b/accurest-core/src/test/resources/directory/with/stubs/other/different/diff.groovy similarity index 100% rename from accurest-core/src/test/resources/directory/with/stubs/other/different/diff.json rename to accurest-core/src/test/resources/directory/with/stubs/other/different/diff.groovy diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/other.json b/accurest-core/src/test/resources/directory/with/stubs/other/other.groovy similarity index 100% rename from accurest-core/src/test/resources/directory/with/stubs/other/other.json rename to accurest-core/src/test/resources/directory/with/stubs/other/other.groovy diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/sample.json b/accurest-core/src/test/resources/directory/with/stubs/other/sample.groovy similarity index 100% rename from accurest-core/src/test/resources/directory/with/stubs/other/sample.json rename to accurest-core/src/test/resources/directory/with/stubs/other/sample.groovy diff --git a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy new file mode 100644 index 0000000000..e0e69eef4a --- /dev/null +++ b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy @@ -0,0 +1,27 @@ +io.coderate.accurest.dsl.GroovyDsl.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + body("""\ + { + "name": "Jan" + } + """ + ) + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body("""\ + { + "name": "Jan" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } +} From 5713fd15bf8eec6c476acc7436920d82b214a180 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 18:02:29 +0100 Subject: [PATCH 068/719] Extended sample groovy dsl with placeholders --- .../accurest/builder/SpockMethodBodyBuilder.groovy | 2 ++ .../src/test/resources/dsl/basic/sampleDsl.groovy | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 79cdf0998e..05f8a632ac 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -44,6 +44,8 @@ class SpockMethodBodyBuilder { blockBuilder.addLine("response.header('$it.key') == '$it.value'") } if (stubDefinition.response.body) { + blockBuilder.endBlock() + blockBuilder.addLine('and:').startBlock() blockBuilder.addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') stubDefinition.response.body.serverValue.each { def value = it.value diff --git a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy index e0e69eef4a..40dc6494de 100644 --- a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy +++ b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy @@ -6,7 +6,8 @@ io.coderate.accurest.dsl.GroovyDsl.make { } body("""\ { - "name": "Jan" + "name": "Jan", + "id": "${value(client('abc'), server('def'))}", } """ ) @@ -16,10 +17,12 @@ io.coderate.accurest.dsl.GroovyDsl.make { status 200 body("""\ { - "name": "Jan" + "name": "Jan", + "id": "${value(client('123'), server('321'))}", + "surname": "${value(client('Kowalsky'), server('$checkIfSurnameValid($value)'))}" } """ - ) + ) headers { header 'Content-Type': 'text/plain' } From c09d520c5d2bd3a357a9e22a5c26e586a627b901 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 18:13:58 +0100 Subject: [PATCH 069/719] Release version 0.4.0 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 17393b0345..390e2b6ec2 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.3.2-SNAPSHOT' + projectVersion = '0.4.0' projectGroup = 'io.codearte.accurest' } From be552a28b8dee3dbcb3d62b169b38f93d635052b Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 18:15:23 +0100 Subject: [PATCH 070/719] Next development version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 390e2b6ec2..059c52dd07 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.4.0' + projectVersion = '0.4.1-SNAPSHOT' projectGroup = 'io.codearte.accurest' } From dd4635fe95087234c9ade918c022d125921076c7 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 21:02:39 +0100 Subject: [PATCH 071/719] Removed server side stubs generation --- .../DslToWiremockServerConverter.groovy | 13 -- .../DslToWiremockServerConverterSpec.groovy | 29 --- .../dsl/WiremockRequestStubStrategy.groovy | 14 -- .../dsl/WiremockResponseStubStrategy.groovy | 12 -- .../accurest/dsl/WiremockStubStrategy.groovy | 5 - .../dsl/WiremockGroovyDslResponseSpec.groovy | 48 +---- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 180 ------------------ 7 files changed, 2 insertions(+), 299 deletions(-) delete mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy delete mode 100644 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy deleted file mode 100644 index ad62c8cc74..0000000000 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverter.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package io.codearte.accurest.wiremock - -import groovy.transform.CompileStatic -import io.coderate.accurest.dsl.WiremockStubStrategy - -@CompileStatic -class DslToWiremockServerConverter extends DslToWiremockConverter { - - @Override - String convertContent(String dslBody) { - return new WiremockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWiremockServerStub() - } -} diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy deleted file mode 100644 index b11f4460b3..0000000000 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockServerConverterSpec.groovy +++ /dev/null @@ -1,29 +0,0 @@ -package io.codearte.accurest.wiremock - -import groovy.json.JsonSlurper -import spock.lang.Specification - -class DslToWiremockServerConverterSpec extends Specification { - - def "should convert DSL file to Wiremock JSON"() { - given: - def converter = new DslToWiremockServerConverter() - and: - String dslBody = """ - io.coderate.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - urlPattern \$(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } - } -""" - when: - String json = converter.convertContent(dslBody) - then: - new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" -{"request":{"method":"PUT","urlPattern":"/12"},"response":{"status":200}}""") - } -} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index d572d30a61..0f0e803059 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -21,11 +21,6 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return buildRequestContent(new ClientRequest(request)) } - @PackageScope - Map buildServerRequestContent() { - return buildRequestContent(new ServerRequest(request)) - } - private Map buildRequestContent(ClientRequest request) { return [method : request?.method?.clientValue, url : request?.url?.clientValue, @@ -36,13 +31,4 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { ].findAll { it.value } } - private Map buildRequestContent(ServerRequest request) { - return [method : request?.method?.serverValue, - url : request?.url?.serverValue, - urlPattern: request?.urlPattern?.serverValue, - urlPath : request?.urlPath?.serverValue, - headers : buildServerHeadersSection(request.headers), - body : request?.body?.serverValue - ].findAll { it.value } - } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index 740a3e69a1..2f27d4293d 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -21,21 +21,9 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { return buildResponseContent(new ClientResponse(response)) } - @PackageScope - Map buildServerResponseContent() { - return buildResponseContent(new ServerResponse(response)) - } - private Map buildResponseContent(ClientResponse response) { return [status : response?.status?.clientValue, body : response?.body?.clientValue, headers: buildClientHeadersSection(response.headers)].findAll { it.value } } - - private Map buildResponseContent(ServerResponse response) { - return [status : response?.status?.serverValue, - body : response?.body?.serverValue, - headers: buildServerHeadersSection(response.headers)].findAll { it.value } - } - } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy index 4888537ec3..b6f1bcdf4b 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockStubStrategy.groovy @@ -18,9 +18,4 @@ class WiremockStubStrategy { return JsonOutput.prettyPrint(JsonOutput.toJson([request : wiremockRequestStubStrategy.buildClientRequestContent(), response: wiremockResponseStubStrategy.buildClientResponseContent()])) } - - String toWiremockServerStub() { - return JsonOutput.prettyPrint(JsonOutput.toJson([request : wiremockRequestStubStrategy.buildServerRequestContent(), - response: wiremockResponseStubStrategy.buildServerResponseContent()])) - } } 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 400ceadbf9..eba8b29783 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 @@ -7,7 +7,7 @@ import spock.lang.Specification class WiremockGroovyDslResponseSpec extends Specification { - def 'should generate response without body for #side side'() { + def 'should generate response without body for client side'() { given: GroovyDsl dsl = GroovyDsl.make { response { @@ -15,9 +15,8 @@ class WiremockGroovyDslResponseSpec extends Specification { } } expect: - new WiremockResponseStubStrategy(dsl)."build${side}ResponseContent"() == new JsonSlurper().parseText(expectedStub) + new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(expectedStub) where: - side << ['Client', 'Server'] expectedStub << [''' { "status": 200 @@ -54,47 +53,4 @@ class WiremockGroovyDslResponseSpec extends Specification { ''') } - def 'should generate headers for response for server side'() { - given: - GroovyDsl dsl = GroovyDsl.make { - response { - status 200 - headers { - header('Content-Type').matches $(client('text/xml'), server('text/*')) - } - } - } - expect: - new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText(''' - { - "status": 200, - "headers": { - "Content-Type": { - "matches": "text/*" - } - } - } - ''') - } - - def 'should generate an exact header for response for both sides '() { - given: - GroovyDsl dsl = GroovyDsl.make { - response { - status 200 - headers { - header 'Content-Type': 'text/xml' - } - } - } - expect: - new WiremockResponseStubStrategy(dsl).buildServerResponseContent() == new JsonSlurper().parseText(''' - { - "status": 200, - "headers": { - "Content-Type": "text/xml" - } - } - ''') - } } 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 47e6a7cfd1..165a4584fc 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -159,105 +159,6 @@ class WiremockGroovyDslSpec extends Specification { ''') } - def 'should convert groovy dsl stub with Body as String to wiremock stub for the server side'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - body("""\ - { - "id": "${value(client('123'), server('321'))}", - "surname": "${value(client('Kowalsky'), server('Lewandowski'))}", - "name": "Jan", - "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" - } - """ - ) - headers { - header 'Content-Type': 'text/plain' - } - } - } - when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' -{ - "request": { - "method": "GET", - "urlPattern": "/12" - }, - "response": { - "status": 200, - "body": { - "id": "321", - "surname": "Lewandowski", - "name": "Jan", - "created" : "2999-09-09 01:23:45" - }, - "headers": { - "Content-Type": "text/plain" - } - } -} -''') - } - - def 'should convert groovy dsl stub to wiremock stub for the server side'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status(200) - body( - id: value( - client('123'), - server('321') - ), - surname: $( - client('Kowalsky'), - server('Lewandowski') - ), - name: 'Jan', - created: $(client('2014-02-02 12:23:43'), server('1999-01-01 01:23:45')) - ) - headers { - header('Content-Type': 'text/plain') - } - } - } - when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockServerStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' -{ - "request": { - "method": "GET", - "urlPattern": "/12" - }, - "response": { - "status": 200, - "body": { - "id": "321", - "surname": "Lewandowski", - "name": "Jan", - "created" : "1999-01-01 01:23:45" - }, - "headers": { - "Content-Type": "text/plain" - } - } -} -''') - } - def "should generate stub with GET"() { given: GroovyDsl groovyDsl = GroovyDsl.make { @@ -308,24 +209,6 @@ class WiremockGroovyDslSpec extends Specification { ''') } - def "should generate stub with urlPattern for server side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - urlPattern $( - client('/[0-9]{2}'), - server('/12') - ) - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText(''' - { - "urlPattern":"/12" - } - ''') - } - def "should generate stub with urlPath for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make { @@ -341,21 +224,6 @@ class WiremockGroovyDslSpec extends Specification { ''') } - def "should generate stub with urlPath for server side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - urlPath('/12') - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' - { - "urlPath":"/12" - } - ''') - } - def "should generate stub with some headers section for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make { @@ -397,52 +265,4 @@ class WiremockGroovyDslSpec extends Specification { } ''') } - - def "should generate stub with some headers section for server side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - headers { - header('Content-Type').equalTo('text/xml') - header('Accept').matches $( - client('text/.*'), - server('text/plain') - ) - header('etag').doesNotMatch $( - client('abcd.*'), - server('abcdef') - ) - header('X-Custom-Header').contains $( - client('2134'), - server('121345') - ) - } - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildServerRequestContent() == new JsonSlurper().parseText(''' - { - "headers": { - "Content-Type": { - "equalTo": "text/xml" - }, - "Accept": { - "matches": "text/plain" - }, - "etag": { - "doesNotMatch": "abcdef" - }, - "X-Custom-Header": { - "contains": "121345" - } - } - } - ''') - } - - @Ignore("Not implemented yet") - def "should generate stub with request body matching for server side"() {} - - @Ignore("Not implemented yet") - def "should generate stub with request query parameter matching for server side"() {} } From 40a9534d74f98cb837a17feac3c5b0c56ded02a2 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 21:09:44 +0100 Subject: [PATCH 072/719] Renamed directories properties in plugin configuration --- .../main/groovy/io/coderate/accurest/TestGenerator.groovy | 8 ++++---- .../accurest/config/AccurestConfigProperties.groovy | 7 +++---- .../src/test/groovy/io/codearte/accurest/MainTest.groovy | 2 +- .../groovy/io/codearte/accurest/TestGeneratorSpec.groovy | 7 +++---- .../codearte/accurest/plugin/AccurestGradlePlugin.groovy | 6 +++--- 5 files changed, 14 insertions(+), 16 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 105d102446..8cfd7a7ac4 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -26,14 +26,14 @@ class TestGenerator { TestGenerator(AccurestConfigProperties configProperties, SingleTestGenerator generator, FileSaver saver) { this.configProperties = configProperties - if (configProperties.stubsBaseDirectory == null) { - throw new AccurestException("Stubs directory not found under " + configProperties.stubsBaseDirectory) + if (configProperties.contractsDslDir == null) { + throw new AccurestException("Stubs directory not found under " + configProperties.contractsDslDir) } this.generator = generator this.saver = saver this.directoryScanner = new DirectoryScanner() directoryScanner.setExcludes(configProperties.getIgnoredFiles() as String[]) - directoryScanner.setBasedir(configProperties.stubsBaseDirectory) + directoryScanner.setBasedir(configProperties.contractsDslDir) } int generate() { @@ -59,7 +59,7 @@ class TestGenerator { return includedFile.matches(includedDirectoryRelativePath + File.separator + "[A-Za-z0-9]*\\.groovy") } .collect { - return new File(configProperties.stubsBaseDirectory, it) + return new File(configProperties.contractsDslDir, it) } if (filesToClass.size()) { def className = afterLast(includedDirectoryRelativePath, File.separator) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy index 3f6e50c889..ea16a0a361 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy @@ -6,14 +6,13 @@ package io.coderate.accurest.config class AccurestConfigProperties { TestFramework targetFramework = TestFramework.SPOCK TestMode testMode = TestMode.MOCKMVC - File stubsBaseDirectory String basePackageForTests String baseClassForTests String ruleClassForTests List ignoredFiles = [] - File generatedTestSourcesDir String[] imports = [] String[] staticImports = [] - File groovyDslDir - File generatedWiremockClientStubsDir + File contractsDslDir + File generatedTestSourcesDir + File stubsOutputDir } 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 27b9ec796d..4f16ddde86 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy @@ -8,7 +8,7 @@ import io.coderate.accurest.config.TestMode class MainTest { public static void main(String[] args) { AccurestConfigProperties properties = new AccurestConfigProperties( - stubsBaseDirectory: new File('/home/devel/projects/codearte/accurest/accurest-core/src/test/resources/dsl'), + contractsDslDir: new File('/home/devel/projects/codearte/accurest/accurest-core/src/test/resources/dsl'), generatedTestSourcesDir: new File('/tmp/accurest'), targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], ignoredFiles: ["**/other"]) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy index 0fcb65fe50..f9f0233cbe 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy @@ -4,7 +4,6 @@ import io.coderate.accurest.FileSaver import io.coderate.accurest.SingleTestGenerator import io.coderate.accurest.TestGenerator import io.coderate.accurest.config.AccurestConfigProperties -import spock.lang.Ignore import spock.lang.Specification class TestGeneratorSpec extends Specification { @@ -15,7 +14,7 @@ class TestGeneratorSpec extends Specification { given: File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() - properties.stubsBaseDirectory = resource.parentFile + properties.contractsDslDir = resource.parentFile TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) when: testGenerator.generateTestClasses("com.ofg") @@ -28,7 +27,7 @@ class TestGeneratorSpec extends Specification { File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() properties.ignoredFiles << "**/other/**" - properties.stubsBaseDirectory = resource.parentFile + properties.contractsDslDir = resource.parentFile TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) when: testGenerator.generateTestClasses("com.ofg") @@ -41,7 +40,7 @@ class TestGeneratorSpec extends Specification { File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() properties.ignoredFiles << "**/other.groovy" - properties.stubsBaseDirectory = resource.parentFile + properties.contractsDslDir = resource.parentFile TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) classGenerator.buildClass(_, _, _) >> "sample" when: 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 11c9d75ba8..6f94c402ed 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 @@ -43,7 +43,7 @@ class AccurestGradlePlugin implements Plugin { void setConfigurationDefaults(AccurestConfigProperties extension) { extension.with { generatedTestSourcesDir = project.file("${project.buildDir}/generated-sources/accurest") - stubsBaseDirectory = project.file("${project.rootDir}/src/test/resources/stubs") //TODO: Use sourceset + contractsDslDir = project.file("${project.rootDir}/src/test/resources/stubs") //TODO: Use sourceset basePackageForTests = 'io.codearte.accurest.tests' } } @@ -61,8 +61,8 @@ class AccurestGradlePlugin implements Plugin { Task task = project.tasks.create(DSL_TO_WIREMOCK_CLIENT_TASK_NAME, GenerateWiremockClientStubsFromDslTask) task.description = "Generate Wiremock client stubs from GroovyDSL" task.conventionMapping.with { - groovyDslDir = { extension.groovyDslDir } - generatedWiremockClientStubsDir = { extension.generatedWiremockClientStubsDir } + groovyDslDir = { extension.contractsDslDir } + generatedWiremockClientStubsDir = { extension.stubsOutputDir } } } } From ed7e7e1a30b470b5221a1d87bc09d99bc56d58ba Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 21 Feb 2015 21:15:42 +0100 Subject: [PATCH 073/719] Added javadocs for extension parameters --- .../config/AccurestConfigProperties.groovy | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy index ea16a0a361..ec95b667b1 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/config/AccurestConfigProperties.groovy @@ -1,5 +1,4 @@ package io.coderate.accurest.config - /** * @author Jakub Kubrynski */ @@ -12,7 +11,20 @@ class AccurestConfigProperties { List ignoredFiles = [] String[] imports = [] String[] staticImports = [] + + /** + * Directory containing contracts written using the GroovyDSL + */ File contractsDslDir + + /** + * Test source directory where tests generated from Groovy DSL should be placed + */ File generatedTestSourcesDir + + /** + * Dir where the generated Wiremock stubs from Groovy DSL should be placed. + * You can then mention them in your packaging task to create jar with stubs + */ File stubsOutputDir } From a39d7f6fa83df3c7f2ec0b0406e46f6b68e18842 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 21:25:07 +0100 Subject: [PATCH 074/719] Add proper section for the gradle plugin - fix #26 --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 3 +++ 1 file changed, 3 insertions(+) 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 6f94c402ed..27af3dab97 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 @@ -14,6 +14,7 @@ class AccurestGradlePlugin implements Plugin { private static final String DSL_TO_WIREMOCK_CLIENT_TASK_NAME = 'generateWiremockClientStubs' private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin + private static final String GROUP_NAME = "Verification" private Project project @@ -51,6 +52,7 @@ class AccurestGradlePlugin implements Plugin { private void createGenerateTestsTask(AccurestConfigProperties extension) { Task task = project.tasks.create(GENERATE_SERVER_TESTS_TASK_NAME, GenerateServerTestsTask) task.description = "Generate server tests from GroovyDSL" + task.group = GROUP_NAME task.conventionMapping.with { generatedTestSourcesDir = { extension.generatedTestSourcesDir } configProperties = { extension } @@ -60,6 +62,7 @@ class AccurestGradlePlugin implements Plugin { private void createAndConfigureGenerateWiremockClientStubsFromDslTask(AccurestConfigProperties extension) { Task task = project.tasks.create(DSL_TO_WIREMOCK_CLIENT_TASK_NAME, GenerateWiremockClientStubsFromDslTask) task.description = "Generate Wiremock client stubs from GroovyDSL" + task.group = GROUP_NAME task.conventionMapping.with { groovyDslDir = { extension.contractsDslDir } generatedWiremockClientStubsDir = { extension.stubsOutputDir } From 6905e39dccb1ed080608cd11476ea2078b5f1c96 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Feb 2015 21:28:10 +0100 Subject: [PATCH 075/719] Fixed plugin configuration properties --- .../accurest/plugin/AccurestGradlePlugin.groovy | 4 ++-- .../accurest/plugin/GenerateServerTestsTask.groovy | 2 +- .../GenerateWiremockClientStubsFromDslTask.groovy | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) 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 27af3dab97..4b9ec6fe02 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 @@ -64,8 +64,8 @@ class AccurestGradlePlugin implements Plugin { task.description = "Generate Wiremock client stubs from GroovyDSL" task.group = GROUP_NAME task.conventionMapping.with { - groovyDslDir = { extension.contractsDslDir } - generatedWiremockClientStubsDir = { extension.stubsOutputDir } + contractsDslDir = { extension.contractsDslDir } + stubsOutputDir = { extension.stubsOutputDir } } } } 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 3294fc22fe..37611c81b1 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 @@ -12,7 +12,7 @@ import org.gradle.api.tasks.TaskAction class GenerateServerTestsTask extends DefaultTask { @InputDirectory - File groovyDslDir + File contractsDslDir @OutputDirectory File generatedTestSourcesDir diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy index 8805992dda..2ab2b704b4 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy @@ -10,17 +10,17 @@ import org.gradle.api.tasks.TaskAction class GenerateWiremockClientStubsFromDslTask extends DefaultTask { @InputDirectory - File groovyDslDir + File contractsDslDir @InputDirectory - File generatedWiremockClientStubsDir + File stubsOutputDir @TaskAction void generate() { project.logger.info("Accurest Plugin: Invoking GroovyDSL to Wiremock client stubs conversion") - project.logger.debug("From '${getGroovyDslDir()}' to '${getGeneratedWiremockClientStubsDir()}'") + project.logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWiremockClientConverter(), getGroovyDslDir(), - getGeneratedWiremockClientStubsDir()) + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWiremockClientConverter(), getContractsDslDir(), + getStubsOutputDir()) converter.processFiles() } } From f7b6c8ad23d1003785ceb79777bae139888d2dd9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 21 Feb 2015 22:33:27 +0100 Subject: [PATCH 076/719] Fixed issues with missing passing of input to task --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 1 + .../codearte/accurest/plugin/GenerateServerTestsTask.groovy | 4 ++-- .../plugin/GenerateWiremockClientStubsFromDslTask.groovy | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) 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 4b9ec6fe02..1e90009be0 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 @@ -54,6 +54,7 @@ class AccurestGradlePlugin implements Plugin { task.description = "Generate server tests from GroovyDSL" task.group = GROUP_NAME task.conventionMapping.with { + contractsDslDir = { extension.contractsDslDir } generatedTestSourcesDir = { extension.generatedTestSourcesDir } configProperties = { extension } } 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 37611c81b1..9cf7c64a2e 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 @@ -3,13 +3,13 @@ package io.codearte.accurest.plugin import io.coderate.accurest.AccurestException import io.coderate.accurest.TestGenerator import io.coderate.accurest.config.AccurestConfigProperties -import org.gradle.api.DefaultTask import org.gradle.api.GradleException +import org.gradle.api.internal.ConventionTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction -class GenerateServerTestsTask extends DefaultTask { +class GenerateServerTestsTask extends ConventionTask { @InputDirectory File contractsDslDir diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy index 2ab2b704b4..b812c318c3 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy @@ -2,12 +2,12 @@ package io.codearte.accurest.plugin import io.codearte.accurest.wiremock.DslToWiremockClientConverter import io.codearte.accurest.wiremock.RecursiveFilesConverter -import org.gradle.api.DefaultTask +import org.gradle.api.internal.ConventionTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.TaskAction //TODO: Implement as an incremental task: https://gradle.org/docs/current/userguide/custom_tasks.html#incremental_tasks ? -class GenerateWiremockClientStubsFromDslTask extends DefaultTask { +class GenerateWiremockClientStubsFromDslTask extends ConventionTask { @InputDirectory File contractsDslDir From b40128d31952db3ab78dd41b1c8dbce070bbe946 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 21 Feb 2015 22:33:57 +0100 Subject: [PATCH 077/719] Added more logging --- .../groovy/io/coderate/accurest/builder/MethodBuilder.groovy | 5 +++-- .../main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy | 2 +- .../groovy/io/coderate/accurest/dsl/internal/Body.groovy | 2 +- .../io/coderate/accurest/dsl/internal/DslProperty.groovy | 2 +- .../groovy/io/coderate/accurest/dsl/internal/Headers.groovy | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy index 43d8046e1d..956e165239 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy @@ -1,14 +1,14 @@ package io.coderate.accurest.builder +import groovy.util.logging.Slf4j import io.coderate.accurest.config.TestFramework import io.coderate.accurest.dsl.GroovyDsl -import io.coderate.accurest.dsl.WiremockStubStrategy import io.coderate.accurest.util.NamesUtil -import io.coderate.accurest.util.StubMappingConverter /** * @author Jakub Kubrynski */ +@Slf4j class MethodBuilder { private final String methodName @@ -23,6 +23,7 @@ class MethodBuilder { static MethodBuilder createTestMethod(File stubsFile, TestFramework lang) { GroovyDsl stubContent = new GroovyShell(this.classLoader).evaluate(stubsFile) + log.debug("Stub content Groovy DSL [$stubContent]") String methodName = NamesUtil.camelCase(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) return new MethodBuilder(methodName, stubContent, lang) } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy index ad3d2f760a..6b2e9bbbc6 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/GroovyDsl.groovy @@ -8,7 +8,7 @@ import io.coderate.accurest.dsl.internal.Response @TypeChecked @EqualsAndHashCode(includeFields = true) -@ToString(includeFields = true, includePackage = false) +@ToString(includeFields = true, includePackage = false, includeNames = true) class GroovyDsl { Request request diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy index 63003589f0..e5ec6a36f2 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Body.groovy @@ -5,7 +5,7 @@ import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import org.codehaus.groovy.runtime.GStringImpl -@ToString(includePackage = false, includeFields = true) +@ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) class Body extends DslProperty { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy index d2a58dfbf8..6887ffc88c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/DslProperty.groovy @@ -6,7 +6,7 @@ import groovy.transform.ToString @CompileStatic @EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) +@ToString(includePackage = false, includeNames = true) class DslProperty { final T clientValue diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index 80a848c2b6..625fd8658c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -4,7 +4,7 @@ import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false, includeFields = true, ignoreNulls = true) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) class Headers { private Map assertionHeaders = [:] From f8fd03288f191d9ac26885c46ee11cd1eb252402 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 21 Feb 2015 22:50:24 +0100 Subject: [PATCH 078/719] Introduced Dsl DslProperty with String or Pattern passing --- .../wiremock/WiremockToDslConverter.groovy | 4 +-- .../DslToWiremockClientConverterSpec.groovy | 2 +- .../WiremockToDslConverterSpec.groovy | 6 ++-- .../builder/SpockMethodBodyBuilder.groovy | 5 +--- .../dsl/WiremockRequestStubStrategy.groovy | 16 +++++----- .../accurest/dsl/internal/Request.groovy | 29 +++---------------- .../coderate/accurest/dsl/internal/Url.groovy | 18 ++++++++++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 27 ++++------------- 8 files changed, 43 insertions(+), 64 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Url.groovy 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 6a1ca4fbde..55b06753dd 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 @@ -20,8 +20,8 @@ class WiremockToDslConverter { request { ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} - ${request.urlPattern ? "urlPattern \"\"\"${escapeJava(request.urlPattern)}\"\"\"" : ""} - ${request.urlPath ? "urlPath \"\"\"$request.urlPath\"\"\"" : ""} + ${request.urlPattern ? "url \$(client(java.util.regex.Pattern.compile('${escapeJava(request.urlPattern)}')), server(''))" : ""} + ${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""} ${ request.headers ? """headers { ${ 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 4f2d5e060e..c3633db0da 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy @@ -13,7 +13,7 @@ class DslToWiremockClientConverterSpec extends Specification { io.coderate.accurest.dsl.GroovyDsl.make { request { method('PUT') - urlPattern \$(client('/[0-9]{2}'), server('/12')) + url \$(client(~/\\/[0-9]{2}/), server('/12')) } response { status 200 diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 63ba9ad92b..a2e7435cf8 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -11,7 +11,7 @@ class WiremockToDslConverterSpec extends Specification { { "request": { "method": "GET", - "urlPattern": "/[0-9]{2}", + "url": "/path", "headers" : { "Accept": { "matches": "text/.*" @@ -44,7 +44,7 @@ class WiremockToDslConverterSpec extends Specification { GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { method 'GET' - urlPattern '/[0-9]{2}' + url '/path' headers { header('Accept').matches('text/.*') header('etag').doesNotMatch('abcd.*') @@ -101,7 +101,7 @@ class WiremockToDslConverterSpec extends Specification { GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { method 'DELETE' - urlPattern '/credit-card-verification-data/[0-9]+' + url $(client(~/\/credit-card-verification-data\/[0-9]+/), server('')) headers { header('Content-Type').equalTo('application/vnd.mymoid-adapter.v2+json; charset=UTF-8') } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 05f8a632ac..6adbe09902 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,10 +1,7 @@ package io.coderate.accurest.builder - import groovy.json.JsonOutput -import groovy.json.JsonSlurper import groovy.transform.PackageScope import io.coderate.accurest.dsl.GroovyDsl - /** * @author Jakub Kubrynski */ @@ -34,7 +31,7 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('when:').startBlock() blockBuilder.addLine('def response = given().spec(request)') blockBuilder.indent() - blockBuilder.addLine(".${stubDefinition.request.method.serverValue.toLowerCase()}(\"$stubDefinition.request.urlPattern.serverValue\")") + blockBuilder.addLine(".${stubDefinition.request.method. serverValue.toLowerCase()}(\"$stubDefinition.request.url.serverValue\")") blockBuilder.unindent().endBlock().addEmptyLine() blockBuilder.addLine('then:').startBlock() diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 0f0e803059..7e18989e83 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,10 +1,10 @@ package io.coderate.accurest.dsl - import groovy.transform.CompileStatic import groovy.transform.PackageScope import io.coderate.accurest.dsl.internal.ClientRequest import io.coderate.accurest.dsl.internal.Request -import io.coderate.accurest.dsl.internal.ServerRequest + +import java.util.regex.Pattern @CompileStatic @PackageScope @@ -22,13 +22,15 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { } private Map buildRequestContent(ClientRequest request) { - return [method : request?.method?.clientValue, - url : request?.url?.clientValue, - urlPattern: request?.urlPattern?.clientValue, - urlPath : request?.urlPath?.clientValue, + return ([method : request?.method?.clientValue, headers : buildClientHeadersSection(request.headers), body : request?.body?.clientValue - ].findAll { it.value } + ] << appendUrl(request)).findAll { it.value } + } + + private Map appendUrl(ClientRequest clientRequest) { + Object url = clientRequest?.url?.clientValue + return url instanceof Pattern ? [urlPattern: ((Pattern)url).pattern()] : [url: url] } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy index bb8ae5b9bf..fc1a4a58d9 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Request.groovy @@ -1,5 +1,4 @@ package io.coderate.accurest.dsl.internal - import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @@ -7,13 +6,11 @@ import groovy.transform.TypeChecked @TypeChecked @EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) +@ToString(includePackage = false, includeNames = true) class Request extends Common { DslProperty method - DslProperty url - DslProperty urlPattern - DslProperty urlPath + Url url Headers headers Body body @@ -23,8 +20,6 @@ class Request extends Common { Request(Request request) { this.method = request.method this.url = request.url - this.urlPattern = request.urlPattern - this.urlPath = request.urlPath this.headers = request.headers this.body = request.body } @@ -38,19 +33,11 @@ class Request extends Common { } void url(String url) { - this.url = toDslProperty(url) + this.url = new Url(url) } void url(DslProperty url) { - this.url = toDslProperty(url) - } - - void urlPattern(String urlPattern) { - this.urlPattern = toDslProperty(urlPattern) - } - - void urlPattern(DslProperty urlPattern) { - this.urlPattern = toDslProperty(urlPattern) + this.url = new Url(url) } void headers(@DelegatesTo(Headers) Closure closure) { @@ -59,14 +46,6 @@ class Request extends Common { closure() } - void urlPath(String urlPath) { - this.urlPath = toDslProperty(urlPath) - } - - void urlPath(DslProperty urlPath) { - this.urlPath = toDslProperty(urlPath) - } - void body(Map body) { this.body = new Body(convertObjectsToDslProperties(body)) } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Url.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Url.groovy new file mode 100644 index 0000000000..a5c49944e3 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Url.groovy @@ -0,0 +1,18 @@ +package io.coderate.accurest.dsl.internal + +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +class Url extends DslProperty { + + Url(DslProperty bodyAsValue) { + super(bodyAsValue.clientValue, bodyAsValue.serverValue) + } + + Url(String bodyAsValue) { + super(bodyAsValue) + } + +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy index 165a4584fc..7b8a7ea5c9 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -1,10 +1,8 @@ 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.Ignore import spock.lang.Specification class WiremockGroovyDslSpec extends Specification { @@ -14,7 +12,7 @@ class WiremockGroovyDslSpec extends Specification { GroovyDsl groovyDsl = GroovyDsl.make { request { method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) + url $(client(~/\/[0-9]{2}/), server('/12')) } response { status 200 @@ -65,7 +63,7 @@ class WiremockGroovyDslSpec extends Specification { GroovyDsl groovyDsl = GroovyDsl.make { request { method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) + url $(client(~/\/[0-9]{2}/), server('/12')) } response { status 200 @@ -113,7 +111,7 @@ class WiremockGroovyDslSpec extends Specification { GroovyDsl groovyDsl = GroovyDsl.make { request { method('GET') - urlPattern $(client('/[0-9]{2}'), server('/12')) + url $(client(~/\/[0-9]{2}/), server('/12')) body("""\ { "name": "Jan" @@ -195,8 +193,8 @@ class WiremockGroovyDslSpec extends Specification { given: GroovyDsl groovyDsl = GroovyDsl.make { request { - urlPattern $( - client('/^[0-9]{2}$'), + url $( + client(~/\/^[0-9]{2}$/), server('/12') ) } @@ -209,21 +207,6 @@ class WiremockGroovyDslSpec extends Specification { ''') } - def "should generate stub with urlPath for client side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - urlPath('/12') - } - } - expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' - { - "urlPath":"/12" - } - ''') - } - def "should generate stub with some headers section for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make { From a908d2e3f2ab5e2fb0183a742049e5ba0d99416a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 21 Feb 2015 23:33:15 +0100 Subject: [PATCH 079/719] Converted request body to a equalTo matcher --- .../io/coderate/accurest/builder/MethodBuilder.groovy | 1 + .../accurest/dsl/WiremockRequestStubStrategy.groovy | 11 ++++++++--- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 4 +++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy index 956e165239..1695856b27 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/MethodBuilder.groovy @@ -22,6 +22,7 @@ class MethodBuilder { } static MethodBuilder createTestMethod(File stubsFile, TestFramework lang) { + log.debug("Stub content from file [${stubsFile.text}]") GroovyDsl stubContent = new GroovyShell(this.classLoader).evaluate(stubsFile) log.debug("Stub content Groovy DSL [$stubContent]") String methodName = NamesUtil.camelCase(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 7e18989e83..4ab842d6cd 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,4 +1,5 @@ package io.coderate.accurest.dsl + import groovy.transform.CompileStatic import groovy.transform.PackageScope import io.coderate.accurest.dsl.internal.ClientRequest @@ -23,9 +24,8 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map buildRequestContent(ClientRequest request) { return ([method : request?.method?.clientValue, - headers : buildClientHeadersSection(request.headers), - body : request?.body?.clientValue - ] << appendUrl(request)).findAll { it.value } + headers : buildClientHeadersSection(request.headers) + ] << appendUrl(request) << appendBody(request)).findAll { it.value } } private Map appendUrl(ClientRequest clientRequest) { @@ -33,4 +33,9 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return url instanceof Pattern ? [urlPattern: ((Pattern)url).pattern()] : [url: url] } + private Map appendBody(ClientRequest clientRequest) { + Object body = clientRequest?.body?.clientValue + return body != null ? [body: [equalTo: body]] : [:] + } + } 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 7b8a7ea5c9..14b6cd5952 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -141,7 +141,9 @@ class WiremockGroovyDslSpec extends Specification { "method": "GET", "urlPattern": "/[0-9]{2}", "body": { - "name": "Jan" + "equalTo": { + "name": "Jan" + } } }, "response": { From 078774c517831bd31ebb9718229acdc138fac8d7 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 21 Feb 2015 23:47:45 +0100 Subject: [PATCH 080/719] Fixed body with equalTo request section --- .../dsl/WiremockRequestStubStrategy.groovy | 31 ++++++++++++++++--- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 4 +-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 4ab842d6cd..95177f16bc 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,13 +1,17 @@ package io.coderate.accurest.dsl - -import groovy.transform.CompileStatic +import groovy.json.JsonOutput +import groovy.json.JsonSlurper 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 java.util.regex.Pattern -@CompileStatic +import static groovy.json.StringEscapeUtils.escapeJava + +@TypeChecked @PackageScope class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { @@ -35,7 +39,26 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map appendBody(ClientRequest clientRequest) { Object body = clientRequest?.body?.clientValue - return body != null ? [body: [equalTo: body]] : [:] + return body != null ? [body: [equalTo: parseBody(body)]] : [:] + } + + private String parseBody(Object responseBodyObject) { + String responseBody = responseBodyObject 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(Map responseBody) { + return JsonOutput.toJson(responseBody) } } 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 14b6cd5952..af5431b36a 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -141,9 +141,7 @@ class WiremockGroovyDslSpec extends Specification { "method": "GET", "urlPattern": "/[0-9]{2}", "body": { - "equalTo": { - "name": "Jan" - } + "equalTo":"{\\"name\\":\\"Jan\\"}" } }, "response": { From 5506edb6434fb723e72e456951f1d22159bcb5d1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 22 Feb 2015 09:45:17 +0100 Subject: [PATCH 081/719] Added regex helper method instead of calling static Pattern.compile --- .../accurest/wiremock/WiremockToDslConverter.groovy | 2 +- .../groovy/io/coderate/accurest/dsl/internal/Common.groovy | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) 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 55b06753dd..7cc47e2bf8 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 @@ -20,7 +20,7 @@ class WiremockToDslConverter { request { ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} - ${request.urlPattern ? "url \$(client(java.util.regex.Pattern.compile('${escapeJava(request.urlPattern)}')), server(''))" : ""} + ${request.urlPattern ? "url \$(client(regex('${escapeJava(request.urlPattern)}')), server(''))" : ""} ${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""} ${ request.headers ? """headers { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy index 9d613c2ef6..934f98c2f5 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Common.groovy @@ -3,6 +3,8 @@ package io.coderate.accurest.dsl.internal import groovy.transform.PackageScope import groovy.transform.TypeChecked +import java.util.regex.Pattern + /** * @TypeChecked instead of @CompileStatic due to usage of double dispatch. * Double dispatch doesn't work if you're using @CompileStatic @@ -60,6 +62,10 @@ class Common { return value(server, client) } + Pattern regex(String regex) { + return Pattern.compile(regex) + } + ClientDslProperty client(Object clientValue) { return new ClientDslProperty(clientValue) } From 3ca2cd35cbcb7476a8feb14a5272212d5478337d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 22 Feb 2015 10:50:27 +0100 Subject: [PATCH 082/719] Fixed header generation (someone can review this code later ;) ) --- .../wiremock/WiremockToDslConverter.groovy | 12 ++- .../WiremockToDslConverterSpec.groovy | 23 ++-- .../builder/SpockMethodBodyBuilder.groovy | 10 +- .../dsl/BaseWiremockStubStrategy.groovy | 53 ++++----- .../dsl/WiremockRequestStubStrategy.groovy | 2 +- .../dsl/WiremockResponseStubStrategy.groovy | 4 +- .../accurest/dsl/internal/Header.groovy | 23 ++++ .../accurest/dsl/internal/Headers.groovy | 25 ++--- .../dsl/internal/WithValuePattern.groovy | 102 ------------------ .../dsl/WiremockGroovyDslResponseSpec.groovy | 6 +- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 23 ++-- 11 files changed, 90 insertions(+), 193 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy delete mode 100644 accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy 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 7cc47e2bf8..d6da45bef5 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -1,5 +1,4 @@ package io.codearte.accurest.wiremock - import groovy.io.FileType import groovy.json.JsonOutput import groovy.json.JsonSlurper @@ -29,7 +28,7 @@ class WiremockToDslConverter { def assertion = it.value String headerName = it.key as String def entry = assertion.entrySet().first() - """header(\"\"\"$headerName\"\"\").$entry.key(\"\"\"${escapeJava(entry.value)}\"\"\")\n""" + """header(\"\"\"$headerName\"\"\", ${buildHeader(entry.key, entry.value)})\n""" }.join('') } } @@ -49,6 +48,15 @@ class WiremockToDslConverter { """ } + private String buildHeader(String method, Object value) { + switch (method) { + case 'equalTo': + return wrapWithMultilineGString(value) + default: + return "regex(${wrapWithMultilineGString(escapeJava(value as String))})" + } + } + private Object buildBody(Map responseBody) { return responseBody.entrySet().collectAll(withQuotedMapStringElements()).inject([:], appendToIterable()) } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index a2e7435cf8..35a5c88caf 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -16,9 +16,6 @@ class WiremockToDslConverterSpec extends Specification { "Accept": { "matches": "text/.*" }, - "etag": { - "doesNotMatch": "abcd.*" - }, "X-Custom-Header": { "contains": "2134" } @@ -46,9 +43,15 @@ class WiremockToDslConverterSpec extends Specification { method 'GET' url '/path' headers { - header('Accept').matches('text/.*') - header('etag').doesNotMatch('abcd.*') - header('X-Custom-Header').contains('2134') + header('Accept': $( + client(regex('text/.*')), + server('text/plain') + )) + header('X-Custom-Header': $( + client(regex('^.*2134.*$')), + server('121345') + )) + } } response { @@ -103,7 +106,7 @@ class WiremockToDslConverterSpec extends Specification { method 'DELETE' url $(client(~/\/credit-card-verification-data\/[0-9]+/), server('')) headers { - header('Content-Type').equalTo('application/vnd.mymoid-adapter.v2+json; charset=UTF-8') + header('Content-Type': 'application/vnd.mymoid-adapter.v2+json; charset=UTF-8') } } response { @@ -154,7 +157,7 @@ class WiremockToDslConverterSpec extends Specification { method 'POST' url '/charge/count' headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + header('Content-Type': 'application/vnd.creditcard-reporter.v1+json') } } response { @@ -207,7 +210,7 @@ class WiremockToDslConverterSpec extends Specification { method 'POST' url '/charge/count' headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + header('Content-Type': 'application/vnd.creditcard-reporter.v1+json') } } response { @@ -257,7 +260,7 @@ class WiremockToDslConverterSpec extends Specification { method 'POST' url '/charge/search?pageNumber=0&size=2147483647' headers { - header('Content-Type').equalTo('application/vnd.creditcard-reporter.v1+json') + header('Content-Type': 'application/vnd.creditcard-reporter.v1+json') } } response { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 6adbe09902..f37f74143f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -18,8 +18,8 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('given:').startBlock() blockBuilder.addLine('def request = given()') blockBuilder.indent() - stubDefinition.request.headers.valueHeaders().each { - blockBuilder.addLine(".header('$it.key', '$it.value')") + stubDefinition.request.headers.headers.collectEntries { [(it.name): it.serverValue] }.each { Map.Entry entry -> + blockBuilder.addLine(".header('${entry.key}', '${entry.value}')") } if (stubDefinition.request.body) { String matches = new JsonOutput().toJson(stubDefinition.request.body.serverValue) @@ -31,14 +31,14 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('when:').startBlock() blockBuilder.addLine('def response = given().spec(request)') blockBuilder.indent() - blockBuilder.addLine(".${stubDefinition.request.method. serverValue.toLowerCase()}(\"$stubDefinition.request.url.serverValue\")") + blockBuilder.addLine(".${stubDefinition.request.method.serverValue.toLowerCase()}(\"$stubDefinition.request.url.serverValue\")") blockBuilder.unindent().endBlock().addEmptyLine() blockBuilder.addLine('then:').startBlock() blockBuilder.addLine("response.statusCode == $stubDefinition.response.status.serverValue") - stubDefinition.response.headers?.valueHeaders().each { - blockBuilder.addLine("response.header('$it.key') == '$it.value'") + stubDefinition.response.headers?.headers?.collectEntries { [(it.name): it.serverValue] }?.each { Map.Entry entry -> + blockBuilder.addLine("response.header('$entry.key') == '$entry.value'") } if (stubDefinition.response.body) { blockBuilder.endBlock() diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index 9dad3f56ea..3052e7efd4 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -1,56 +1,41 @@ package io.coderate.accurest.dsl -import groovy.transform.CompileStatic -import io.coderate.accurest.dsl.internal.DslProperty +import groovy.transform.TypeChecked +import io.coderate.accurest.dsl.internal.Header import io.coderate.accurest.dsl.internal.Headers -import io.coderate.accurest.dsl.internal.WithValuePattern -@CompileStatic +import java.util.regex.Pattern + +@TypeChecked abstract class BaseWiremockStubStrategy { - protected Map buildClientHeadersSection(Headers headers) { + protected Map buildClientRequestHeadersSection(Headers headers) { if (!headers) { return null } - return withAssertionHeaders(headers) { - Map.Entry entry -> [(entry.key): buildClientHeaderFromValuePattern(entry.value)] - } << headers.valueHeaders() + return headers.headers.collectEntries { Header entry -> + parseHeader(entry.name, entry.clientValue) + } } - protected Map buildServerHeadersSection(Headers headers) { + protected Map buildClientResponseHeadersSection(Headers headers) { if (!headers) { return null } - return withAssertionHeaders(headers) { - Map.Entry entry -> [(entry.key): buildServerHeaderFromValuePattern(entry.value)] - } << headers.valueHeaders() + return headers.headers.collectEntries { Header entry -> + [(entry.name) : entry.clientValue] + } } - private Map withAssertionHeaders(Headers headers, Closure closure) { - return headers?.assertionEntries()?.collectEntries(closure) + protected Map parseHeader(String entryKey, Object entry) { + return [(entryKey): [equalTo : entry]] } - private Map buildClientHeaderFromValuePattern(WithValuePattern valuePattern) { - return getValuePatternSection(valuePattern) - .findAll { it.value } - .collectEntries { [(it.key): it.value.clientValue] } + protected Map parseHeader(String entryKey, String entry) { + return [(entryKey): [equalTo : entry]] } - private Map buildServerHeaderFromValuePattern(WithValuePattern valuePattern) { - return getValuePatternSection(valuePattern) - .findAll { it.value } - .collectEntries { [(it.key): it.value.serverValue] } + protected Map parseHeader(String entryKey, Pattern entry) { + return [(entryKey): [matches : entry.pattern()]] } - private Map getValuePatternSection(WithValuePattern valuePattern) { - return [equalToJson : valuePattern.equalToJson, - equalToXml : valuePattern.equalToXml, - matchesXPath : valuePattern.matchesXPath, - jsonCompareMode: valuePattern.jsonCompareMode, - equalTo : valuePattern.equalTo, - contains : valuePattern.contains, - matches : valuePattern.matches, - doesNotMatch : valuePattern.doesNotMatch, - absent : valuePattern.absent, - matchesJsonPath: valuePattern.matchesJsonPath] - } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 95177f16bc..65d6dea03a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -28,7 +28,7 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map buildRequestContent(ClientRequest request) { return ([method : request?.method?.clientValue, - headers : buildClientHeadersSection(request.headers) + headers : buildClientRequestHeadersSection(request.headers) ] << appendUrl(request) << appendBody(request)).findAll { it.value } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy index 2f27d4293d..a1d9f2eb68 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -1,10 +1,8 @@ package io.coderate.accurest.dsl - import groovy.transform.CompileStatic import groovy.transform.PackageScope import io.coderate.accurest.dsl.internal.ClientResponse import io.coderate.accurest.dsl.internal.Response -import io.coderate.accurest.dsl.internal.ServerResponse @CompileStatic @PackageScope @@ -24,6 +22,6 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { private Map buildResponseContent(ClientResponse response) { return [status : response?.status?.clientValue, body : response?.body?.clientValue, - headers: buildClientHeadersSection(response.headers)].findAll { it.value } + headers: buildClientResponseHeadersSection(response.headers)].findAll { it.value } } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy new file mode 100644 index 0000000000..90de0873f8 --- /dev/null +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Header.groovy @@ -0,0 +1,23 @@ +package io.coderate.accurest.dsl.internal +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@CompileStatic +class Header extends DslProperty { + + String name + + Header(String name, DslProperty dslProperty) { + super(dslProperty.clientValue, dslProperty.serverValue) + this.name = name + } + + Header(String name, Object value) { + super(value) + this.name = name + } + +} diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index 625fd8658c..06e294e488 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -2,31 +2,22 @@ package io.coderate.accurest.dsl.internal import groovy.transform.EqualsAndHashCode import groovy.transform.ToString +import groovy.transform.TypeChecked @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@TypeChecked class Headers { - private Map assertionHeaders = [:] - private Map valueHeaders = [:] + Set

headers = [] - WithValuePattern header(String headerName) { - WithValuePattern withValuePattern = new WithValuePattern() - assertionHeaders[headerName] = withValuePattern - return withValuePattern + void header(Map singleHeader) { + Map.Entry first = singleHeader.entrySet().first() + headers << new Header(first?.key, first?.value) } - void header(Map singleHeader) { - Map.Entry first = singleHeader.entrySet().first() - valueHeaders[first?.key] = first?.value - } - - Map valueHeaders() { - return Collections.unmodifiableMap(valueHeaders) - } - - Set> assertionEntries() { - return Collections.unmodifiableSet(assertionHeaders.entrySet()) + void header(String headerKey, Object headerValue) { + headers << new Header(headerKey, headerValue) } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy deleted file mode 100644 index 0fc53aefb3..0000000000 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/WithValuePattern.groovy +++ /dev/null @@ -1,102 +0,0 @@ -package io.coderate.accurest.dsl.internal - -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString -import groovy.transform.TypeChecked - -@TypeChecked -@EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) -class WithValuePattern { - - DslProperty equalTo - DslProperty equalToJson - DslProperty equalToXml - DslProperty matchesXPath - DslProperty jsonCompareMode - DslProperty contains - DslProperty matches - DslProperty doesNotMatch - DslProperty absent - DslProperty matchesJsonPath - - void equalTo(String equalTo) { - this.equalTo = new DslProperty(equalTo) - } - - void equalTo(DslProperty equalTo) { - this.equalTo = equalTo - } - - void equalToJson(String equalToJson) { - this.equalToJson = new DslProperty(equalToJson) - } - - void equalToJson(DslProperty equalToJson) { - this.equalToJson = equalToJson - } - - void equalToXml(String equalToXml) { - this.equalToXml = new DslProperty(equalToXml) - } - - void equalToXml(DslProperty equalToXml) { - this.equalToXml = equalToXml - } - - void matchesXPath(String matchesXPath) { - this.matchesXPath = new DslProperty(matchesXPath) - } - - void matchesXPath(DslProperty matchesXPath) { - this.matchesXPath = matchesXPath - } - - void jsonCompareMode(JSONCompareMode jsonCompareMode) { - this.jsonCompareMode = new DslProperty(jsonCompareMode) - } - - void jsonCompareMode(DslProperty jsonCompareMode) { - this.jsonCompareMode = jsonCompareMode - } - - void contains(String contains) { - this.contains = new DslProperty(contains) - } - - void contains(DslProperty contains) { - this.contains = contains - } - - void matches(String matches) { - this.matches = new DslProperty(matches) - } - - void matches(DslProperty matches) { - this.matches = matches - } - - void doesNotMatch(String doesNotMatch) { - this.doesNotMatch = new DslProperty(doesNotMatch) - } - - void doesNotMatch(DslProperty doesNotMatch) { - this.doesNotMatch = doesNotMatch - } - - void absent(String absent) { - this.absent = new DslProperty(absent) - } - - void absent(DslProperty absent) { - this.absent = absent - } - - void matchesJsonPath(String matchesJsonPath) { - this.matchesJsonPath = new DslProperty(matchesJsonPath) - } - - void matchesJsonPath(DslProperty matchesJsonPath) { - this.matchesJsonPath = matchesJsonPath - } -} 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 eba8b29783..ae33f3ccdc 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 @@ -35,7 +35,7 @@ class WiremockGroovyDslResponseSpec extends Specification { GroovyDsl dsl = GroovyDsl.make { response { headers { - header('Content-Type').matches $(client('text/xml'), server('text/*')) + header 'Content-Type', $(client('text/xml'), server('text/*')) } status 200 } @@ -44,9 +44,7 @@ class WiremockGroovyDslResponseSpec extends Specification { new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(''' { "headers": { - "Content-Type": { - "matches": "text/xml" - }, + "Content-Type": "text/xml" }, "status": 200 } 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 af5431b36a..75c0e17cfb 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -212,19 +212,15 @@ class WiremockGroovyDslSpec extends Specification { GroovyDsl groovyDsl = GroovyDsl.make { request { headers { - header('Content-Type').equalTo('text/xml') - header('Accept').matches $( - client('text/.*'), + header('Content-Type': 'text/xml') + header('Accept': $( + client(regex('text/.*')), server('text/plain') - ) - header('etag').doesNotMatch $( - client('abcd.*'), - server('abcdef') - ) - header('X-Custom-Header').contains $( - client('2134'), + )) + header('X-Custom-Header': $( + client(regex('^.*2134.*$')), server('121345') - ) + )) } } } @@ -238,11 +234,8 @@ class WiremockGroovyDslSpec extends Specification { "Accept": { "matches": "text/.*" }, - "etag": { - "doesNotMatch": "abcd.*" - }, "X-Custom-Header": { - "contains": "2134" + "matches": "^.*2134.*$" } } } From dfee248b0f4cdc74ea8e84df71eaae66c5a0452e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 22 Feb 2015 13:58:01 +0100 Subject: [PATCH 083/719] Fixed nested lists etc. --- .../DslToWiremockClientConverterSpec.groovy | 72 +++++++++++++++++++ .../dsl/WiremockRequestStubStrategy.groovy | 4 ++ 2 files changed, 76 insertions(+) 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 c3633db0da..1f1a105142 100644 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy @@ -26,4 +26,76 @@ class DslToWiremockClientConverterSpec extends Specification { new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" {"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}}""") } + + + def "should convert DSL file with a nested list to Wiremock JSON"() { + given: + def converter = new DslToWiremockClientConverter() + and: + String dslBody = """ + io.coderate.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/api/12' + headers { + header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json' + + } + body ''' + [{ + "created_at": "Sat Jul 26 09:38:57 +0000 2014", + "id": 492967299297845248, + "id_str": "492967299297845248", + "text": "Gonna see you at Warsaw", + "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" + } + }] + ''' + } + response { + status 200 + } + } +""" + when: + String json = converter.convertContent(dslBody) + then: + new JsonSlurper().parseText(json) == new JsonSlurper().parseText("""{ + "request":{ + "method":"PUT", + "url":"/api/12", + "body": { + "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" + } + } + }, + "response":{ + "status":200} + } +""") + } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 65d6dea03a..d32919aa6c 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -57,6 +57,10 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { } } + private String parseBody(List responseBody) { + return JsonOutput.toJson(responseBody) + } + private String parseBody(Map responseBody) { return JsonOutput.toJson(responseBody) } From a8adb76e970c92a45fadfa18c3e2a7062d44b6e1 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sun, 22 Feb 2015 14:26:40 +0100 Subject: [PATCH 084/719] Release version 0.4.1 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 059c52dd07..213be5a5b0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.4.1-SNAPSHOT' + projectVersion = '0.4.1' projectGroup = 'io.codearte.accurest' } From 943516b70e0ffcaa4147023d9924c217e39f1da9 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sun, 22 Feb 2015 14:30:56 +0100 Subject: [PATCH 085/719] Next development version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 213be5a5b0..259248d732 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.4.1' + projectVersion = '0.4.2-SNAPSHOT' projectGroup = 'io.codearte.accurest' } From 42783e8b03d456756a16e117c3b204af7d7511cb Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Mon, 23 Feb 2015 16:11:18 +0100 Subject: [PATCH 086/719] [#18] Add basic functional tests for Gradle plugin --- .../plugin/BasicFunctionalSpec.groovy | 58 +++++++ .../functionalTest/bootSimple/build.gradle | 75 ++++++++ .../bootSimple/gradle.properties | 5 + .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 51018 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .../functionalTest/bootSimple/gradlew | 164 ++++++++++++++++++ .../functionalTest/bootSimple/gradlew.bat | 90 ++++++++++ .../pairId/colleratePlacesFromTweet.groovy | 17 ++ .../ofg/twitter/place/PairIdController.groovy | 30 ++++ .../groovy/com/ofg/twitter/place/Tweet.java | 13 ++ .../ofg/twitter/places/AcceptanceSpec.groovy | 23 +++ .../ofg/twitter/places/BaseMockMvcSpec.groovy | 12 ++ .../src/test/resources/logback-test.groovy | 14 ++ build.gradle | 21 ++- 14 files changed, 527 insertions(+), 1 deletion(-) create mode 100644 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties create mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar create mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties create mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew create mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/colleratePlacesFromTweet.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy 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 new file mode 100644 index 0000000000..a494d2d837 --- /dev/null +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy @@ -0,0 +1,58 @@ +package io.codearte.accurest.plugin + +import groovy.json.JsonSlurper +import nebula.test.IntegrationSpec +import spock.lang.Stepwise + +@Stepwise +class BasicFunctionalSpec extends IntegrationSpec { + + def "should pass basic flow"() { + when: + copyResources("functionalTest/bootSimple", "") + then: + fileExists('build.gradle') + when: + def result = runTasksSuccessfully('check') + then: + result.wasExecuted(":generateWiremockClientStubs") + result.wasExecuted(":generateAccurest") + + and: "tests generated" + fileExists("build/generated-sources/accurest/accurest/PairIdSpec.groovy") + + and: "client stubs generated" + fileExists("build/production/bootSimple-stubs/repository/mappings/pairId/colleratePlacesFromTweet.json") + + and: "generated tests executed" + fileExists("build/test-results/TEST-accurest.PairId.xml") + } + + def "should generate valid client json stubs for simple input"() { + given: + copyResources("functionalTest/bootSimple", "") + when: + runTasksSuccessfully('generateWiremockClientStubs') + then: + def generatedClientJsonStub = file("build/production/bootSimple-stubs/repository/mappings/pairId/colleratePlacesFromTweet.json").text + new JsonSlurper().parseText(generatedClientJsonStub) == new JsonSlurper().parseText(""" +{ + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/json" + } + }, + "url": "/api/12", + "body": { + "equalTo": "[{\\"text\\":\\"Gonna see you at Warsaw\\"}]" + } + }, + "response": { + "status": 200 + } +} +""") + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle new file mode 100644 index 0000000000..1241194253 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -0,0 +1,75 @@ +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath "io.codearte.accurest:accurest-gradle-plugin:$accurestVersion" + } +} + +apply plugin: 'groovy' +apply plugin: 'accurest' + +ext { + contractsDir = file("${project.rootDir}/repository/mappings/com/ofg/twitter-places-analyzer") + wiremockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") + wiremockStubsOutputDir = new File(wiremockStubsOutputDirRoot, 'repository/mappings/') +} + +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() +} + +dependencies { + compile "org.springframework:spring-web:$springVersion" + compile "org.springframework:spring-context-support:$springVersion" + compile "org.codehaus.groovy:groovy-all:2.4.1" + compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' + compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonMapper" + compile "org.codehaus.jackson:jackson-core-asl:$jacksonMapper" + compile 'com.jayway.jsonpath:json-path-assert:1.2.0' + + testCompile('com.github.tomakehurst:wiremock:1.53') { + exclude group: 'org.mortbay.jetty', module: 'servlet-api' + } + testCompile "org.spockframework:spock-spring:0.7-groovy-2.0" + testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" + testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" + testCompile "io.codearte.accurest:accurest-core:$accurestVersion" + testCompile "javax.servlet:javax.servlet-api:3.0.1" //provided + testCompile "ch.qos.logback:logback-classic:1.1.2" +} + +accurest { + baseClassForTests = 'com.ofg.twitter.places.BaseMockMvcSpec' + basePackageForTests = 'accurest' + 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.2.1' +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties new file mode 100644 index 0000000000..6e02ac3599 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties @@ -0,0 +1,5 @@ +groupId=com.ofg +jacksonMapper=1.9.13 +restAssuredVersion=2.4.0 +accurestVersion=0.4.1 +springVersion=4.1.4.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar new file mode 100755 index 0000000000000000000000000000000000000000..c97a8bdb9088d370da7e88784a7a093b971aa23a GIT binary patch literal 51018 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +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"` + + # 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 "$@" diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat new file mode 100755 index 0000000000..8a0b282aa6 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat @@ -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 Windowz 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 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 new file mode 100644 index 0000000000..767b51797e --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/colleratePlacesFromTweet.groovy @@ -0,0 +1,17 @@ +io.coderate.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/api/12' + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] +''' + } + response { + status 200 + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy new file mode 100644 index 0000000000..8a4e1e2e63 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy @@ -0,0 +1,30 @@ +package com.ofg.twitter.place + +import groovy.transform.TypeChecked +import groovy.util.logging.Slf4j +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +import static org.springframework.web.bind.annotation.RequestMethod.PUT + +@Slf4j +@RestController +@RequestMapping('/api') +@TypeChecked +class PairIdController { + + @RequestMapping( + value = '{pairId}', + method = PUT, + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + void getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { + log.info("Inside PairIdController, doing very important logic") + if (tweets?.text != ["Gonna see you at Warsaw"]) { + throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") + } + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java new file mode 100644 index 0000000000..96fdd52262 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java @@ -0,0 +1,13 @@ +package com.ofg.twitter.place; + +public class Tweet { + private String text; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy new file mode 100644 index 0000000000..6a3bef53d7 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy @@ -0,0 +1,23 @@ +package com.ofg.twitter.places + +import com.ofg.twitter.place.PairIdController +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import spock.lang.Specification + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +class AcceptanceSpec extends Specification { + + def "should have controller up and running"() { + given: + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PairIdController()).build() + expect: + mockMvc.perform(put("/api/${1}"). + contentType(MediaType.APPLICATION_JSON). + content("""[{"text":"Gonna see you at Warsaw"}]""")). + andExpect(status().isOk()) + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy new file mode 100644 index 0000000000..b88c863fcc --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy @@ -0,0 +1,12 @@ +package com.ofg.twitter.places + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import com.ofg.twitter.place.PairIdController +import spock.lang.Specification + +abstract class BaseMockMvcSpec extends Specification { + + def setup() { + RestAssuredMockMvc.standaloneSetup(new PairIdController()) + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy new file mode 100644 index 0000000000..315c39c794 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy @@ -0,0 +1,14 @@ +import ch.qos.logback.classic.encoder.PatternLayoutEncoder +import ch.qos.logback.core.ConsoleAppender + +String console = "CONSOLE" +String logPattern = "%d{yyyy-MM-dd HH:mm:ss.SSSZ, Europe/Warsaw} | %-5level | %X{correlationId} | %thread | %logger{1} | %m%n" + +appender(console, ConsoleAppender) { + encoder(PatternLayoutEncoder) { + pattern = logPattern + } +} + +root(INFO, [console]) +logger("com.ofg", DEBUG) diff --git a/build.gradle b/build.gradle index 259248d732..fb54c77910 100644 --- a/build.gradle +++ b/build.gradle @@ -43,6 +43,8 @@ subprojects { } } } + + uploadArchives.dependsOn { check } } project(':accurest-core') { @@ -67,9 +69,26 @@ project(':accurest-gradle-plugin') { compile project(':accurest-core') compile project(':accurest-converters') compile gradleApi() + + testCompile('com.netflix.nebula:nebula-test:2.2.0') { + exclude(group: 'org.spockframework') + } } + + test { + exclude '**/*FunctionalSpec.*' + } + task funcTest(type: Test) { + include '**/*FunctionalSpec.*' + + reports.html { + destination = file("${reporting.baseDir}/funcTests") + } + } + + uploadArchives.dependsOn { funcTest } } task wrapper(type: Wrapper) { gradleVersion = '2.2.1' -} \ No newline at end of file +} From cd81251f377013506baac9ea4efd42c04443d28f Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 23 Feb 2015 22:33:03 +0100 Subject: [PATCH 087/719] Fix #32 - Generating assertions for map elements --- .../builder/SpockMethodBodyBuilder.groovy | 29 ++++++++++++------- .../test/resources/dsl/basic/sampleDsl.groovy | 2 +- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index f37f74143f..2b2548bd11 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -45,21 +45,28 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('and:').startBlock() blockBuilder.addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') stubDefinition.response.body.serverValue.each { - def value = it.value - if (value instanceof String) { - if (value.startsWith('$')) { - value = value.substring(1).replaceAll('\\$value', "responseBody.$it.key") - blockBuilder.addLine(value) - } else { - blockBuilder.addLine("responseBody.$it.key == \"${value}\"") - } - } else { - blockBuilder.addLine("responseBody.$it.key == ${value}") - } + processBodyElement(blockBuilder, "", it) } } blockBuilder.endBlock() blockBuilder.endBlock() } + + private void processBodyElement(BlockBuilder blockBuilder, String rootProperty, def element) { + def value = element.value + String property = rootProperty + "." + element.key + if (value instanceof String) { + if (value.startsWith('$')) { + value = value.substring(1).replaceAll('\\$value', "responseBody$property") + blockBuilder.addLine(value) + } else { + blockBuilder.addLine("responseBody$property == \"${value}\"") + } + } else if (value instanceof Map) { + value.each { entry -> processBodyElement(blockBuilder, property, entry) } + } else { + blockBuilder.addLine("responseBody$property == ${value}") + } + } } diff --git a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy index 40dc6494de..7200a71dae 100644 --- a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy +++ b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy @@ -11,7 +11,7 @@ io.coderate.accurest.dsl.GroovyDsl.make { } """ ) - urlPattern $(client('/[0-9]{2}'), server('/12')) + url $(client('/[0-9]{2}'), server('/12')) } response { status 200 From 3777f77de0727e63bf7a2847e7fda0e7ce6aac37 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 23 Feb 2015 22:34:57 +0100 Subject: [PATCH 088/719] Release version 0.4.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 259248d732..abcea8d5ad 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.4.2-SNAPSHOT' + projectVersion = '0.4.2' projectGroup = 'io.codearte.accurest' } From 8a8de92bbf38137332bb013ed5dc0f441be9e58a Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 23 Feb 2015 22:38:33 +0100 Subject: [PATCH 089/719] Next development version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index abcea8d5ad..35b4641954 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.4.2' + projectVersion = '0.4.3-SNAPSHOT' projectGroup = 'io.codearte.accurest' } From 736ae1b79063de3840d852e72f21a5c1f31c1a89 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 24 Feb 2015 11:46:26 +0100 Subject: [PATCH 090/719] Headers refactoring --- .../accurest/builder/SpockMethodBodyBuilder.groovy | 10 ++++++---- .../accurest/dsl/BaseWiremockStubStrategy.groovy | 4 ++-- .../io/coderate/accurest/dsl/internal/Headers.groovy | 12 +++++++++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index 2b2548bd11..fc7abc910f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -2,6 +2,8 @@ package io.coderate.accurest.builder import groovy.json.JsonOutput import groovy.transform.PackageScope import io.coderate.accurest.dsl.GroovyDsl +import io.coderate.accurest.dsl.internal.Header + /** * @author Jakub Kubrynski */ @@ -18,8 +20,8 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('given:').startBlock() blockBuilder.addLine('def request = given()') blockBuilder.indent() - stubDefinition.request.headers.headers.collectEntries { [(it.name): it.serverValue] }.each { Map.Entry entry -> - blockBuilder.addLine(".header('${entry.key}', '${entry.value}')") + stubDefinition.request.headers?.collect { Header header -> + blockBuilder.addLine(".header('${header.name}', '${header.serverValue}')") } if (stubDefinition.request.body) { String matches = new JsonOutput().toJson(stubDefinition.request.body.serverValue) @@ -37,8 +39,8 @@ class SpockMethodBodyBuilder { blockBuilder.addLine('then:').startBlock() blockBuilder.addLine("response.statusCode == $stubDefinition.response.status.serverValue") - stubDefinition.response.headers?.headers?.collectEntries { [(it.name): it.serverValue] }?.each { Map.Entry entry -> - blockBuilder.addLine("response.header('$entry.key') == '$entry.value'") + stubDefinition.response.headers?.collect { Header header -> + blockBuilder.addLine("response.header('$header.name') == '$header.serverValue'") } if (stubDefinition.response.body) { blockBuilder.endBlock() diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy index 3052e7efd4..5e89c3d3bc 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -12,7 +12,7 @@ abstract class BaseWiremockStubStrategy { if (!headers) { return null } - return headers.headers.collectEntries { Header entry -> + return headers.entries.collectEntries { Header entry -> parseHeader(entry.name, entry.clientValue) } } @@ -21,7 +21,7 @@ abstract class BaseWiremockStubStrategy { if (!headers) { return null } - return headers.headers.collectEntries { Header entry -> + return headers.entries.collectEntries { Header entry -> [(entry.name) : entry.clientValue] } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy index 06e294e488..be6f90c66f 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/internal/Headers.groovy @@ -9,15 +9,21 @@ import groovy.transform.TypeChecked @TypeChecked class Headers { - Set

headers = [] + Set
entries = [] void header(Map singleHeader) { Map.Entry first = singleHeader.entrySet().first() - headers << new Header(first?.key, first?.value) + entries << new Header(first?.key, first?.value) } void header(String headerKey, Object headerValue) { - headers << new Header(headerKey, headerValue) + entries << new Header(headerKey, headerValue) + } + + void collect(Closure closure) { + entries?.each { + header -> closure(header) + } } } From 076fe266b156bee1a37908892d2e2b7df29185ba Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Tue, 24 Feb 2015 11:58:57 +0100 Subject: [PATCH 091/719] Stubs output directory is created automatically when needed --- .../plugin/GenerateWiremockClientStubsFromDslTask.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy index b812c318c3..6a6f08f692 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy @@ -4,6 +4,7 @@ import io.codearte.accurest.wiremock.DslToWiremockClientConverter import io.codearte.accurest.wiremock.RecursiveFilesConverter import org.gradle.api.internal.ConventionTask import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction //TODO: Implement as an incremental task: https://gradle.org/docs/current/userguide/custom_tasks.html#incremental_tasks ? @@ -11,7 +12,7 @@ class GenerateWiremockClientStubsFromDslTask extends ConventionTask { @InputDirectory File contractsDslDir - @InputDirectory + @OutputDirectory File stubsOutputDir @TaskAction From cbf82e7d73523320aa984b0e63bf2eb4be8576c0 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Tue, 24 Feb 2015 12:34:03 +0100 Subject: [PATCH 092/719] Add logging what class files were generated --- .../src/main/groovy/io/coderate/accurest/FileSaver.groovy | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy index 1c12c01c93..e0fcf760c8 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy @@ -1,16 +1,19 @@ package io.coderate.accurest import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j import io.coderate.accurest.config.TestFramework import io.coderate.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 @CompileStatic +@Slf4j class FileSaver { File targetDirectory @@ -23,10 +26,11 @@ class FileSaver { void saveClassFile(String fileName, String packageName, byte[] classBytes) { - def testBaseDir = Paths.get(targetDirectory.absolutePath, NamesUtil.packageToDirectory(packageName)) + Path testBaseDir = Paths.get(targetDirectory.absolutePath, NamesUtil.packageToDirectory(packageName)) Files.createDirectories(testBaseDir) - def classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + framework.classNameSuffix + framework.classExtension) + Path classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + framework.classNameSuffix + framework.classExtension) .toAbsolutePath() + log.info("Creating new class file [$classPath]") Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) } From 209f3ce2a0dee678d9601bb69547be7add0841ea Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Tue, 24 Feb 2015 13:13:43 +0100 Subject: [PATCH 093/719] Test suffix is used also in class name (not only in file name) --- .../src/main/groovy/io/coderate/accurest/FileSaver.groovy | 3 +-- .../src/main/groovy/io/coderate/accurest/TestGenerator.groovy | 2 +- .../test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy | 4 ++-- .../io/codearte/accurest/plugin/BasicFunctionalSpec.groovy | 4 ++-- .../test/resources/functionalTest/bootSimple/settings.gradle | 1 + 5 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy index e0fcf760c8..2d20399d8a 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/FileSaver.groovy @@ -28,8 +28,7 @@ class FileSaver { Path testBaseDir = Paths.get(targetDirectory.absolutePath, NamesUtil.packageToDirectory(packageName)) Files.createDirectories(testBaseDir) - Path classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + framework.classNameSuffix + framework.classExtension) - .toAbsolutePath() + Path classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + framework.classExtension).toAbsolutePath() log.info("Creating new class file [$classPath]") Files.write(classPath, classBytes, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING) } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 8cfd7a7ac4..f8a7e25496 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -62,7 +62,7 @@ class TestGenerator { return new File(configProperties.contractsDslDir, it) } if (filesToClass.size()) { - def className = afterLast(includedDirectoryRelativePath, File.separator) + def className = afterLast(includedDirectoryRelativePath, File.separator) + configProperties.targetFramework.classNameSuffix def classBytes = generator.buildClass(filesToClass, className, packageNameForClass).bytes saver.saveClassFile(className, packageNameForClass, classBytes) counter.incrementAndGet() diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy index f9f0233cbe..84eb77ab58 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy @@ -32,7 +32,7 @@ class TestGeneratorSpec extends Specification { when: testGenerator.generateTestClasses("com.ofg") then: - 1 * classGenerator.buildClass(_, 'different', _) >> "qwerty" + 1 * classGenerator.buildClass(_, 'differentSpec', _) >> "qwerty" } def "should ignore file"() { @@ -46,6 +46,6 @@ class TestGeneratorSpec extends Specification { when: testGenerator.generateTestClasses("com.ofg") then: - 1 * classGenerator.buildClass({ it.size() == 1 }, 'other', _) >> "sample.groovy" + 1 * classGenerator.buildClass({ it.size() == 1 }, 'otherSpec', _) >> "sample.groovy" } } 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 a494d2d837..16c48b2516 100644 --- 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 @@ -13,7 +13,7 @@ class BasicFunctionalSpec extends IntegrationSpec { then: fileExists('build.gradle') when: - def result = runTasksSuccessfully('check') + def result = runTasksSuccessfully('clean', 'check') //clean to remove accidental output when importing SimpleBoot into Idea then: result.wasExecuted(":generateWiremockClientStubs") result.wasExecuted(":generateAccurest") @@ -25,7 +25,7 @@ class BasicFunctionalSpec extends IntegrationSpec { fileExists("build/production/bootSimple-stubs/repository/mappings/pairId/colleratePlacesFromTweet.json") and: "generated tests executed" - fileExists("build/test-results/TEST-accurest.PairId.xml") + fileExists("build/test-results/TEST-accurest.PairIdSpec.xml") } def "should generate valid client json stubs for simple input"() { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle new file mode 100644 index 0000000000..d227b869a2 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle @@ -0,0 +1 @@ +rootProject.name='bootSimple' From 2f0315af1ece3e55c2addb8176fbac4d27855d59 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Tue, 24 Feb 2015 14:38:20 +0100 Subject: [PATCH 094/719] Add functional tests for being up-to-date --- .../plugin/BasicFunctionalSpec.groovy | 61 +++++++++++++++---- 1 file changed, 50 insertions(+), 11 deletions(-) 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 16c48b2516..05385ea28a 100644 --- 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 @@ -7,34 +7,40 @@ import spock.lang.Stepwise @Stepwise class BasicFunctionalSpec extends IntegrationSpec { + private static final String GENERATED_TEST = "build//generated-sources//accurest//accurest//PairIdSpec.groovy" + private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//pairId//colleratePlacesFromTweet.json" + private static final String GROOVY_DSL_CONTRACT = "repository//mappings//com//ofg//twitter-places-analyzer//pairId//colleratePlacesFromTweet.groovy" + private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.PairIdSpec.xml" + + void setup() { + copyResources("functionalTest/bootSimple", "") + runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it + } + def "should pass basic flow"() { + given: + assert fileExists('build.gradle') when: - copyResources("functionalTest/bootSimple", "") - then: - fileExists('build.gradle') - when: - def result = runTasksSuccessfully('clean', 'check') //clean to remove accidental output when importing SimpleBoot into Idea + def result = runTasksSuccessfully('check') then: result.wasExecuted(":generateWiremockClientStubs") result.wasExecuted(":generateAccurest") and: "tests generated" - fileExists("build/generated-sources/accurest/accurest/PairIdSpec.groovy") + fileExists(GENERATED_TEST) and: "client stubs generated" - fileExists("build/production/bootSimple-stubs/repository/mappings/pairId/colleratePlacesFromTweet.json") + fileExists(GENERATED_CLIENT_JSON_STUB) and: "generated tests executed" - fileExists("build/test-results/TEST-accurest.PairIdSpec.xml") + fileExists(TEST_EXECUTION_XML_REPORT) } def "should generate valid client json stubs for simple input"() { - given: - copyResources("functionalTest/bootSimple", "") when: runTasksSuccessfully('generateWiremockClientStubs') then: - def generatedClientJsonStub = file("build/production/bootSimple-stubs/repository/mappings/pairId/colleratePlacesFromTweet.json").text + def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text new JsonSlurper().parseText(generatedClientJsonStub) == new JsonSlurper().parseText(""" { "request": { @@ -55,4 +61,37 @@ class BasicFunctionalSpec extends IntegrationSpec { } """) } + + def "tasks should be up-to-date when appropriate"() { + given: + assert !fileExists(GENERATED_CLIENT_JSON_STUB) + assert !fileExists(TEST_EXECUTION_XML_REPORT) + when: + runTasksSuccessfully('generateWiremockClientStubs', 'generateAccurest') + then: + fileExists(GENERATED_CLIENT_JSON_STUB) + fileExists(GENERATED_TEST) + + when: "running generation without change inputs" + def secondExecutionResult = runTasksSuccessfully('generateWiremockClientStubs', 'generateAccurest') + + then: "tasks should be up-to-date" + secondExecutionResult.wasUpToDate(":generateWiremockClientStubs") + secondExecutionResult.wasUpToDate(":generateAccurest") + + when: "inputs changed" + def groovyDslFile = file(GROOVY_DSL_CONTRACT) + groovyDslFile.text = groovyDslFile.text.replace("200", "599") + + and: "tasks run" + def thirdExecutionResult = runTasksSuccessfully('generateWiremockClientStubs', 'generateAccurest') + + then: "tasks should be reexecuted" + thirdExecutionResult.wasExecuted(":generateWiremockClientStubs") + thirdExecutionResult.wasExecuted(":generateAccurest") + + and: "changes visible in generate files" + file(GENERATED_CLIENT_JSON_STUB).text.contains("599") + file(GENERATED_TEST).text.contains("599") + } } From 38301d1dd950e9e632fa3dff0e4dc48fe508c717 Mon Sep 17 00:00:00 2001 From: Madalina Bidilita Date: Wed, 25 Feb 2015 10:13:47 +0100 Subject: [PATCH 095/719] Fix file separators on windows. --- .../wiremock/RecursiveFilesConverterSpec.groovy | 12 +++++------- .../groovy/io/coderate/accurest/TestGenerator.groovy | 6 +++++- 2 files changed, 10 insertions(+), 8 deletions(-) mode change 100644 => 100755 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy mode change 100644 => 100755 accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy old mode 100644 new mode 100755 index f450449046..583de32c0b --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy @@ -11,8 +11,7 @@ import java.nio.file.Paths class RecursiveFilesConverterSpec extends Specification { - private static - final Set EXPECTED_TARGET_FILES = ["dslRoot.json", "dir1/dsl1.json", "dir1/dsl1b.json", "dir2/dsl2.json"] + private static final Set EXPECTED_TARGET_FILES = [Paths.get("dslRoot.json"), Paths.get("dir1/dsl1.json"), Paths.get("dir1/dsl1b.json"), Paths.get("dir2/dsl2.json")] @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); @@ -56,12 +55,11 @@ class RecursiveFilesConverterSpec extends Specification { e.cause?.message == "Test conversion error" } - private - static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { + private static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { Path rootSourcePath = Paths.get(targetRootDirectory.toURI()) - Set relativizedCreatedFiles = createdFiles.collect { File file -> - rootSourcePath.relativize(Paths.get(file.toURI())).toString() + Set relativizedCreatedFiles = createdFiles.collect { File file -> + rootSourcePath.relativize(Paths.get(file.toURI())) } - relativizedCreatedFiles + return relativizedCreatedFiles } } diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy old mode 100644 new mode 100755 index f8a7e25496..aad644fed1 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -56,7 +56,7 @@ class TestGenerator { if (!includedDirectoryRelativePath.isEmpty()) { List filesToClass = directoryScanner.includedFiles. grep { String includedFile -> - return includedFile.matches(includedDirectoryRelativePath + File.separator + "[A-Za-z0-9]*\\.groovy") + return normalizePath(includedFile).matches(normalizePath(includedDirectoryRelativePath + File.separator) + "[A-Za-z0-9]*\\.groovy") } .collect { return new File(configProperties.contractsDslDir, it) @@ -69,4 +69,8 @@ class TestGenerator { } } } + + private String normalizePath(String path) { + return path.replaceAll(/\\+/, '/') + } } \ No newline at end of file From 59716fd8e0cd80ab0f1a0e79c3f8789e3c12cbe1 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 25 Feb 2015 21:56:24 +0100 Subject: [PATCH 096/719] Release version 0.4.3 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 97863492ca..d347ea81b1 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.4.3-SNAPSHOT' + projectVersion = '0.4.3' projectGroup = 'io.codearte.accurest' } From 802582381de93ad4a6350b09606b896ba7b18d7d Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 25 Feb 2015 21:59:36 +0100 Subject: [PATCH 097/719] Next development version --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d347ea81b1..d488248174 100644 --- a/build.gradle +++ b/build.gradle @@ -1,5 +1,5 @@ ext { - projectVersion = '0.4.3' + projectVersion = '0.4.4-SNAPSHOT' projectGroup = 'io.codearte.accurest' } From 6cf969ca0b3130bf5e6358c7ab612dbb3c69ac69 Mon Sep 17 00:00:00 2001 From: Maciej Ziarko Date: Thu, 26 Feb 2015 14:03:11 +0100 Subject: [PATCH 098/719] Commons IO instead of custom solution --- .../src/main/groovy/io/coderate/accurest/TestGenerator.groovy | 3 ++- build.gradle | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index aad644fed1..20bde442ae 100755 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -2,6 +2,7 @@ package io.coderate.accurest import groovy.transform.PackageScope import io.coderate.accurest.config.AccurestConfigProperties +import org.apache.commons.io.FilenameUtils import org.codehaus.plexus.util.DirectoryScanner import java.util.concurrent.atomic.AtomicInteger @@ -71,6 +72,6 @@ class TestGenerator { } private String normalizePath(String path) { - return path.replaceAll(/\\+/, '/') + return FilenameUtils.normalize(path, true) } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index d488248174..3a76dfeea2 100644 --- a/build.gradle +++ b/build.gradle @@ -51,6 +51,7 @@ project(':accurest-core') { dependencies { compile 'org.slf4j:slf4j-api:[1.6.0,)' compile 'org.codehaus.plexus:plexus-utils:3.0.21' + compile 'commons-io:commons-io:2.4' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' } From 0972cb893c8568eeb4c0329128358f9ee98f7bc3 Mon Sep 17 00:00:00 2001 From: Maciej Ziarko Date: Thu, 26 Feb 2015 15:23:47 +0100 Subject: [PATCH 099/719] FilenameUtils.separatorsToUnix --- .../src/main/groovy/io/coderate/accurest/TestGenerator.groovy | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy index 20bde442ae..45ba0ff497 100755 --- a/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/TestGenerator.groovy @@ -1,5 +1,4 @@ package io.coderate.accurest - import groovy.transform.PackageScope import io.coderate.accurest.config.AccurestConfigProperties import org.apache.commons.io.FilenameUtils @@ -8,7 +7,6 @@ import org.codehaus.plexus.util.DirectoryScanner import java.util.concurrent.atomic.AtomicInteger import static io.coderate.accurest.util.NamesUtil.afterLast - /** * @author Jakub Kubrynski */ @@ -72,6 +70,6 @@ class TestGenerator { } private String normalizePath(String path) { - return FilenameUtils.normalize(path, true) + return FilenameUtils.separatorsToUnix(path) } } \ No newline at end of file From 816dbf0489006fa3d9c90958e9b644149ea4a087 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Mon, 2 Mar 2015 21:20:39 +0100 Subject: [PATCH 100/719] Update version in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 98d84e56c0..3df5125f8b 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'io.codearte.accurest:accurest-gradle-plugin:0.3.0' + classpath 'io.codearte.accurest:accurest-gradle-plugin:0.4.3' } } From ce491088b6610ed7caa9c59a9d62737f66f24e30 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Mon, 2 Mar 2015 21:27:43 +0100 Subject: [PATCH 101/719] Switch releasing to Axion plugin --- build.gradle | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 3a76dfeea2..c67ab2c5a8 100644 --- a/build.gradle +++ b/build.gradle @@ -1,18 +1,38 @@ -ext { - projectVersion = '0.4.4-SNAPSHOT' - projectGroup = 'io.codearte.accurest' +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath "pl.allegro.tech.build:axion-release-plugin:1.2.0" + } +} + +apply plugin: "pl.allegro.tech.build.axion-release" + +scmVersion { + tag { prefix = "accurest" } + createReleaseCommit = true + releaseCommitMessage { version, position -> "Release version: ${version}\n\n[ci skip]" } + hooks { + pre "fileUpdate", [file : "README.md", + pattern : { v, p -> /'io\.codearte\.accurest:accurest-gradle-plugin:.*'/ }, + replacement: { v, p -> "'io.codearte.accurest:accurest-gradle-plugin:$v'" }] + } +} + +allprojects { + project.version = scmVersion.version } subprojects { apply plugin: 'groovy' apply plugin: 'maven-publish' - if (!projectVersion.contains('SNAPSHOT')) { + if (!version.contains('SNAPSHOT')) { apply from: "$rootDir/release.gradle" } - group = projectGroup - version = projectVersion + group = 'io.codearte.accurest' sourceCompatibility = 1.7 targetCompatibility = 1.7 @@ -36,9 +56,6 @@ subprojects { publishing { publications { maven(MavenPublication) { - groupId projectGroup - version projectVersion - from components.java } } From eb9149baab9011ab40ba637d408c8fbfbd4a874a Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Mon, 2 Mar 2015 21:39:39 +0100 Subject: [PATCH 102/719] Fix broken dependencies' scope in pom.xml Known limitation in maven-publish: http://forums.gradle.org/gradle/topics/maven_publish_plugin_generated_pom_making_dependency_scope_runtime#reply_14120711 --- build.gradle | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/build.gradle b/build.gradle index c67ab2c5a8..9372d26f62 100644 --- a/build.gradle +++ b/build.gradle @@ -57,6 +57,17 @@ subprojects { publications { maven(MavenPublication) { from components.java + pom.withXml { + //#89 - workaround to not to have only runtime dependencies in generated pom.xml + //Known limitation in maven-publish - - http://forums.gradle.org/gradle/topics/maven_publish_plugin_generated_pom_making_dependency_scope_runtime#reply_14120711 + asNode().dependencies.'*'.findAll() { + it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep -> + dep.name == it.artifactId.text() + } + }.each() { + it.scope*.value = 'compile' + } + } } } } From 6166ff021bd8b27b98ab6276a28012557ad86479 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Mon, 2 Mar 2015 21:41:59 +0100 Subject: [PATCH 103/719] Move release.gradle to better directory --- build.gradle | 2 +- release.gradle => gradle/release.gradle | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename release.gradle => gradle/release.gradle (100%) diff --git a/build.gradle b/build.gradle index 9372d26f62..16bfe25d5e 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ subprojects { apply plugin: 'maven-publish' if (!version.contains('SNAPSHOT')) { - apply from: "$rootDir/release.gradle" + apply from: "$rootDir/gradle/release.gradle" } group = 'io.codearte.accurest' diff --git a/release.gradle b/gradle/release.gradle similarity index 100% rename from release.gradle rename to gradle/release.gradle From 64fcac070f8be8e553487a9d877ddf49078cb389 Mon Sep 17 00:00:00 2001 From: Catalin Buleandra Date: Sat, 21 Mar 2015 22:04:38 +0100 Subject: [PATCH 104/719] Wiremock stubs should have the body defined under bodyPatterns, and not body. --- .../accurest/wiremock/DslToWiremockClientConverterSpec.groovy | 2 +- .../io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy | 2 +- .../io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy | 2 +- .../io/codearte/accurest/plugin/BasicFunctionalSpec.groovy | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) mode change 100644 => 100755 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy mode change 100644 => 100755 accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy mode change 100644 => 100755 accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy mode change 100644 => 100755 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy 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 old mode 100644 new mode 100755 index 1f1a105142..f753cc6bf4 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy @@ -84,7 +84,7 @@ class DslToWiremockClientConverterSpec extends Specification { "request":{ "method":"PUT", "url":"/api/12", - "body": { + "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": { diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy old mode 100644 new mode 100755 index d32919aa6c..885c53483b --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -39,7 +39,7 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map appendBody(ClientRequest clientRequest) { Object body = clientRequest?.body?.clientValue - return body != null ? [body: [equalTo: parseBody(body)]] : [:] + return body != null ? [bodyPatterns: [equalTo: parseBody(body)]] : [:] } private String parseBody(Object responseBodyObject) { 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 old mode 100644 new mode 100755 index 75c0e17cfb..f849bc717d --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy @@ -140,7 +140,7 @@ class WiremockGroovyDslSpec extends Specification { "request": { "method": "GET", "urlPattern": "/[0-9]{2}", - "body": { + "bodyPatterns": { "equalTo":"{\\"name\\":\\"Jan\\"}" } }, 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 old mode 100644 new mode 100755 index 05385ea28a..d1b3d976bd --- 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,7 +51,7 @@ class BasicFunctionalSpec extends IntegrationSpec { } }, "url": "/api/12", - "body": { + "bodyPatterns": { "equalTo": "[{\\"text\\":\\"Gonna see you at Warsaw\\"}]" } }, From b912e60c4cbd9ec44daa97bb614d1e458fe78778 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Mar 2015 22:51:03 +0100 Subject: [PATCH 105/719] Updated axion to 1.2.2 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 16bfe25d5e..5d7f1b504f 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,7 @@ buildscript { mavenCentral() } dependencies { - classpath "pl.allegro.tech.build:axion-release-plugin:1.2.0" + classpath "pl.allegro.tech.build:axion-release-plugin:1.2.2" } } From eac0e67c15ff8ba100afcc237c2dfcd3df749a62 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Mar 2015 22:54:16 +0100 Subject: [PATCH 106/719] Release version: 0.4.4 [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3df5125f8b..43e94094cd 100644 --- a/README.md +++ b/README.md @@ -184,7 +184,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'io.codearte.accurest:accurest-gradle-plugin:0.4.3' + classpath 'io.codearte.accurest:accurest-gradle-plugin:0.4.4' } } From 1387e47f16acf1bc3b51b3982440c0a6cc15b5b6 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 21 Mar 2015 23:01:44 +0100 Subject: [PATCH 107/719] Added nexus-staging plugin --- build.gradle | 7 +++++++ gradle.properties | 4 ++-- gradle/release.gradle | 4 ++-- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 5d7f1b504f..e0a87bd555 100644 --- a/build.gradle +++ b/build.gradle @@ -4,10 +4,17 @@ buildscript { } dependencies { classpath "pl.allegro.tech.build:axion-release-plugin:1.2.2" + classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.1" } } apply plugin: "pl.allegro.tech.build.axion-release" +apply plugin: 'io.codearte.nexus-staging' + +nexusStaging { + packageGroup = "io.codearte" + stagingProfileId = '93c08fdebde1ff' +} scmVersion { tag { prefix = "accurest" } diff --git a/gradle.properties b/gradle.properties index 87021638cf..fe3cdf2fd8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,2 @@ -sonatypeUsername = -sonatypePassword = \ No newline at end of file +nexusUsername = +nexusPassword = \ No newline at end of file diff --git a/gradle/release.gradle b/gradle/release.gradle index e772848864..34e8ae08ef 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -25,11 +25,11 @@ uploadArchives { beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: sonatypeUsername, password: sonatypePassword) + authentication(userName: nexusUsername, password: nexusPassword) } snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: sonatypeUsername, password: sonatypePassword) + authentication(userName: nexusUsername, password: nexusPassword) } pom.project { From 3867ee867615c8e55bfc21f860b3bef2d480b1c0 Mon Sep 17 00:00:00 2001 From: Catalin Buleandra Date: Sun, 22 Mar 2015 16:14:30 +0100 Subject: [PATCH 108/719] Wiremock stubs should be generated with bodyPatterns as array, and response body as String literal --- .../DslToWiremockClientConverterSpec.groovy | 6 ++-- .../WiremockToDslConverterSpec.groovy | 15 ++------- .../dsl/BaseWiremockStubStrategy.groovy | 28 +++++++++++++++- .../dsl/WiremockRequestStubStrategy.groovy | 32 ++----------------- .../dsl/WiremockResponseStubStrategy.groovy | 15 ++++++--- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 26 +++++---------- .../plugin/BasicFunctionalSpec.groovy | 6 ++-- 7 files changed, 55 insertions(+), 73 deletions(-) mode change 100644 => 100755 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy mode change 100644 => 100755 accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy mode change 100644 => 100755 accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy 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..e4ccc28328 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 @@ -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..af1ba33e1b --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -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", } @@ -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" } 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 old mode 100644 new mode 100755 index 5e89c3d3bc..c297a8757b --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -1,11 +1,15 @@ package io.coderate.accurest.dsl - +import groovy.json.JsonOutput +import groovy.json.JsonSlurper import groovy.transform.TypeChecked +import groovy.xml.XmlUtil import io.coderate.accurest.dsl.internal.Header import io.coderate.accurest.dsl.internal.Headers import java.util.regex.Pattern +import static groovy.json.StringEscapeUtils.escapeJava + @TypeChecked abstract class BaseWiremockStubStrategy { protected Map buildClientRequestHeadersSection(Headers headers) { @@ -38,4 +42,26 @@ abstract class BaseWiremockStubStrategy { 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/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 885c53483b..02b78deb3e 100755 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,16 +1,12 @@ package io.coderate.accurest.dsl -import groovy.json.JsonOutput -import groovy.json.JsonSlurper + 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 java.util.regex.Pattern -import static groovy.json.StringEscapeUtils.escapeJava - @TypeChecked @PackageScope class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { @@ -39,30 +35,6 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map appendBody(ClientRequest clientRequest) { Object body = clientRequest?.body?.clientValue - return body != null ? [bodyPatterns: [equalTo: parseBody(body)]] : [:] + return body != null ? [bodyPatterns: [[equalTo: parseBody(body)]]] : [:] } - - private String parseBody(Object responseBodyObject) { - String responseBody = responseBodyObject 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/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy old mode 100644 new mode 100755 index a1d9f2eb68..4c905bf4dc --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -1,10 +1,10 @@ package io.coderate.accurest.dsl -import groovy.transform.CompileStatic import groovy.transform.PackageScope +import groovy.transform.TypeChecked import io.coderate.accurest.dsl.internal.ClientResponse import io.coderate.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/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy index f849bc717d..a5db188554 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 @@ -44,12 +44,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 +87,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" } @@ -140,15 +130,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-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 From 8479bed5b7be9a3d3eb47373a13a8a8ec54384c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kubry=C5=84ski?= Date: Sun, 5 Apr 2015 20:07:02 +0200 Subject: [PATCH 109/719] Update README.md --- README.md | 238 ++---------------------------------------------------- 1 file changed, 5 insertions(+), 233 deletions(-) diff --git a/README.md b/README.md index 43e94094cd..fed801fe93 100644 --- a/README.md +++ b/README.md @@ -2,238 +2,10 @@ Accurate REST ============= 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) From a732359b80d76ea38db4440a9ccdd5e6ebfccd0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kubry=C5=84ski?= Date: Sun, 5 Apr 2015 20:44:27 +0200 Subject: [PATCH 110/719] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index fed801fe93..7cead077d6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ 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 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: From dca1fbcf30ec21a99aed0b6e8d9fa1a74909ffa3 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Fri, 10 Apr 2015 11:29:53 +0200 Subject: [PATCH 111/719] Release version: 0.4.5 [ci skip] From a8b964884ec2140aed94c188e6ee1dcf9c81a839 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 13 Apr 2015 18:42:41 +0200 Subject: [PATCH 112/719] Fix #48 - Assertions for array in response body --- .../builder/SpockMethodBodyBuilder.groovy | 25 +++++- ...pec.groovy => GeneratorScannerSpec.groovy} | 2 +- .../builder/SpockMethodBuilderSpec.groovy | 87 +++++++++++++++++++ 3 files changed, 110 insertions(+), 4 deletions(-) rename accurest-core/src/test/groovy/io/codearte/accurest/{TestGeneratorSpec.groovy => GeneratorScannerSpec.groovy} (97%) create mode 100644 accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy index fc7abc910f..f8b9a62eff 100644 --- a/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,4 +1,5 @@ package io.coderate.accurest.builder + import groovy.json.JsonOutput import groovy.transform.PackageScope import io.coderate.accurest.dsl.GroovyDsl @@ -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/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy similarity index 97% 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..97aa6df799 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/TestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy @@ -6,7 +6,7 @@ import io.coderate.accurest.TestGenerator import io.coderate.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/coderate/accurest/builder/SpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy new file mode 100644 index 0000000000..6aad086cd2 --- /dev/null +++ b/accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy @@ -0,0 +1,87 @@ +package io.coderate.accurest.builder + +import io.coderate.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\"") + } +} From f94815bcf4756aae81c45c9a3c7f3288a6a47381 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 13 Apr 2015 18:46:28 +0200 Subject: [PATCH 113/719] Fix #46 - Added test for nested objects in response body --- .../builder/SpockMethodBuilderSpec.groovy | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy index 6aad086cd2..aa4d4547d0 100644 --- a/accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy @@ -84,4 +84,30 @@ class SpockMethodBuilderSpec extends Specification { 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\"") + } } From cd7e004f678db28628c6569ca51604d0126d2dd2 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 13 Apr 2015 21:20:31 +0200 Subject: [PATCH 114/719] Release version: 0.4.6 [ci skip] From 7f0b99034ae875f4b720eda09da0d6c0493d6cdc Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 13 Apr 2015 21:29:04 +0200 Subject: [PATCH 115/719] Fixed package name - renamed from coderate to codearte --- .../wiremock/ConversionAccurestException.groovy | 2 +- .../wiremock/DslToWiremockClientConverter.groovy | 2 +- .../wiremock/DslToWiremockConverter.groovy | 2 +- .../DslToWiremockClientConverterSpec.groovy | 4 ++-- .../wiremock/WiremockToDslConverterSpec.groovy | 12 ++++++------ .../resources/converter/source/dir1/dsl1.groovy | 2 +- .../resources/converter/source/dir1/dsl1b.groovy | 2 +- .../resources/converter/source/dir2/dsl2.groovy | 2 +- .../resources/converter/source/dslRoot.groovy | 2 +- .../accurest/AccurestException.groovy | 2 +- .../accurest/FileSaver.groovy | 8 ++++---- .../accurest/SingleTestGenerator.groovy | 16 ++++++++-------- .../accurest/TestGenerator.groovy | 6 +++--- .../accurest/builder/BlockBuilder.groovy | 2 +- .../accurest/builder/ClassBuilder.groovy | 8 ++++---- .../builder/JUnitMethodBodyBuilder.groovy | 2 +- .../accurest/builder/MethodBuilder.groovy | 8 ++++---- .../builder/SpockMethodBodyBuilder.groovy | 6 +++--- .../config/AccurestConfigProperties.groovy | 2 +- .../accurest/config/TestFramework.groovy | 2 +- .../accurest/config/TestMode.groovy | 2 +- .../accurest/dsl/BaseWiremockStubStrategy.groovy | 6 +++--- .../accurest/dsl/GroovyDsl.groovy | 6 +++--- .../dsl/WiremockRequestStubStrategy.groovy | 6 +++--- .../dsl/WiremockResponseStubStrategy.groovy | 6 +++--- .../accurest/dsl/WiremockStubStrategy.groovy | 2 +- .../accurest/dsl/internal/Body.groovy | 2 +- .../dsl/internal/ClientDslProperty.groovy | 2 +- .../accurest/dsl/internal/Common.groovy | 2 +- .../accurest/dsl/internal/DslProperty.groovy | 2 +- .../accurest/dsl/internal/Header.groovy | 2 +- .../accurest/dsl/internal/Headers.groovy | 2 +- .../accurest/dsl/internal/JSONCompareMode.groovy | 2 +- .../accurest/dsl/internal/Request.groovy | 2 +- .../accurest/dsl/internal/Response.groovy | 2 +- .../dsl/internal/ServerDslProperty.groovy | 2 +- .../accurest/dsl/internal/Url.groovy | 2 +- .../accurest/util/NamesUtil.groovy | 2 +- .../accurest/util/StubMappingConverter.groovy | 2 +- .../accurest/GeneratorScannerSpec.groovy | 5 +---- .../groovy/io/codearte/accurest/MainTest.groovy | 7 +++---- .../builder/SpockMethodBuilderSpec.groovy | 4 ++-- .../dsl/WiremockGroovyDslResponseSpec.groovy | 2 -- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 3 --- .../test/resources/dsl/basic/sampleDsl.groovy | 2 +- .../accurest/plugin/AccurestGradlePlugin.groovy | 2 +- .../plugin/GenerateServerTestsTask.groovy | 6 +++--- .../pairId/colleratePlacesFromTweet.groovy | 2 +- 48 files changed, 85 insertions(+), 94 deletions(-) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/AccurestException.groovy (88%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/FileSaver.groovy (83%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/SingleTestGenerator.groovy (75%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/TestGenerator.groovy (94%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/builder/BlockBuilder.groovy (96%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/builder/ClassBuilder.groovy (92%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/builder/JUnitMethodBodyBuilder.groovy (90%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/builder/MethodBuilder.groovy (86%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/builder/SpockMethodBodyBuilder.groovy (96%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/config/AccurestConfigProperties.groovy (95%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/config/TestFramework.groovy (96%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/config/TestMode.groovy (66%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/BaseWiremockStubStrategy.groovy (93%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/GroovyDsl.groovy (84%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/WiremockRequestStubStrategy.groovy (89%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/WiremockResponseStubStrategy.groovy (86%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/WiremockStubStrategy.groovy (95%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/Body.groovy (97%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/ClientDslProperty.groovy (80%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/Common.groovy (97%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/DslProperty.groovy (92%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/Header.groovy (93%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/Headers.groovy (94%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/JSONCompareMode.groovy (63%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/Request.groovy (97%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/Response.groovy (97%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/ServerDslProperty.groovy (88%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/dsl/internal/Url.groovy (89%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/util/NamesUtil.groovy (96%) rename accurest-core/src/main/groovy/io/{coderate => codearte}/accurest/util/StubMappingConverter.groovy (97%) rename accurest-core/src/test/groovy/io/{coderate => codearte}/accurest/builder/SpockMethodBuilderSpec.groovy (97%) 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/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy index e4ccc28328..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' diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index af1ba33e1b..7466b2e7f5 100755 --- 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 { @@ -65,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 } @@ -117,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 } @@ -166,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 } @@ -218,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 } @@ -282,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 96% 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 f8b9a62eff..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,9 +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 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/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy similarity index 93% rename from accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy index c297a8757b..77866f1437 100755 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -1,10 +1,10 @@ -package io.coderate.accurest.dsl +package io.codearte.accurest.dsl import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.transform.TypeChecked import groovy.xml.XmlUtil -import io.coderate.accurest.dsl.internal.Header -import io.coderate.accurest.dsl.internal.Headers +import io.codearte.accurest.dsl.internal.Header +import io.codearte.accurest.dsl.internal.Headers import java.util.regex.Pattern 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 89% 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 02b78deb3e..02d7497a9c 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,9 +1,9 @@ -package io.coderate.accurest.dsl +package io.codearte.accurest.dsl import groovy.transform.PackageScope import groovy.transform.TypeChecked -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 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 similarity index 86% 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 4c905bf4dc..e0b7556547 100755 --- 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,8 +1,8 @@ -package io.coderate.accurest.dsl +package io.codearte.accurest.dsl import groovy.transform.PackageScope import groovy.transform.TypeChecked -import io.coderate.accurest.dsl.internal.ClientResponse -import io.coderate.accurest.dsl.internal.Response +import io.codearte.accurest.dsl.internal.ClientResponse +import io.codearte.accurest.dsl.internal.Response @TypeChecked @PackageScope 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/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy index 97aa6df799..6a478e3d92 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy @@ -1,9 +1,6 @@ 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 GeneratorScannerSpec extends Specification { 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/coderate/accurest/builder/SpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy similarity index 97% rename from accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy index aa4d4547d0..c68a96a1e6 100644 --- a/accurest-core/src/test/groovy/io/coderate/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -1,6 +1,6 @@ -package io.coderate.accurest.builder +package io.codearte.accurest.builder -import io.coderate.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification /** 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 a5db188554..2a2c500a3a 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 { 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/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' From 159000cd4516594701c8586f7616e8805b87bbcb Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 13 Apr 2015 21:32:33 +0200 Subject: [PATCH 116/719] Release version: 0.4.7 [ci skip] From 8aca30f2747c0fd6d3d80268cb20ae4fd8e227e4 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 18 Apr 2015 08:44:24 +0200 Subject: [PATCH 117/719] [#51] Added wrapping of generated DSL with a factory method --- .../accurest/wiremock/WiremockToDslConverter.groovy | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index d6da45bef5..925595b49c 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 @@ -139,14 +139,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 """\ +io.coderate.accurest.dsl.GroovyDsl.make { + $dslFromWiremockStub +} +""" + } } From 8113879dc03bc6294e1bd685df858f41b12e7d8d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 18 Apr 2015 08:46:14 +0200 Subject: [PATCH 118/719] [#51] Made reference to the FQN of GroovyDsl --- .../codearte/accurest/wiremock/WiremockToDslConverter.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 925595b49c..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 @@ -153,7 +154,7 @@ class WiremockToDslConverter { static String wrapWithFactoryMethod(String dslFromWiremockStub) { return """\ -io.coderate.accurest.dsl.GroovyDsl.make { +${GroovyDsl.name}.make { $dslFromWiremockStub } """ From 57afecd5c6682946206864d84a4996f9f227ac9b Mon Sep 17 00:00:00 2001 From: Jan Marcis Date: Wed, 6 May 2015 16:50:24 +0200 Subject: [PATCH 119/719] added possibility to generate wiremock stubs with regexp matching --- .../dsl/WiremockRequestStubStrategy.groovy | 18 ++++- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 65 +++++++++++++++++-- 2 files changed, 73 insertions(+), 10 deletions(-) diff --git a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy index 885c53483b..6d20d5d7f1 100755 --- a/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/coderate/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -39,11 +39,23 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map appendBody(ClientRequest clientRequest) { Object body = clientRequest?.body?.clientValue - return body != null ? [bodyPatterns: [equalTo: parseBody(body)]] : [:] + if (body == null) { + return [:] + } + if (containsRegex(body)) { + return [bodyPatterns: [matches: parseBody(body)]] + } + + return [bodyPatterns: [equalTo: parseBody(body)]] } - private String parseBody(Object responseBodyObject) { - String responseBody = responseBodyObject as String + boolean containsRegex(Object bodyObject) { + String bodyString = bodyObject as String + 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)) 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 f849bc717d..7112e6c6e1 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 @@ -111,13 +111,12 @@ class WiremockGroovyDslSpec extends Specification { GroovyDsl groovyDsl = GroovyDsl.make { request { method('GET') - url $(client(~/\/[0-9]{2}/), server('/12')) - body("""\ - { - "name": "Jan" - } - """ - ) + url $(client(regex('/[0-9]{2}')), server('/12')) + body """ + { + "name": "Jan" + } + """ } response { status 200 @@ -157,6 +156,58 @@ class WiremockGroovyDslSpec extends Specification { ''') } + + def 'should convert groovy dsl stub with regexp Body as String to wiremock stub for the client side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + url $(client(regex('/[0-9]{2}')), server('/12')) + body """ + { + "personalId": "${value(client(regex('^[0-9]{11}$')), server('57593728525'))}" + } + """ + } + response { + status 200 + body("""\ + { + "name": "Jan" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}", + "bodyPatterns": { + "matches":"{\\"personalId\\":\\"^[0-9]{11}$\\"}" + } + }, + "response": { + "status": 200, + "body": { + "name": "Jan" + }, + "headers": { + "Content-Type": "text/plain" + } + } +} +''') + } + + def "should generate stub with GET"() { given: GroovyDsl groovyDsl = GroovyDsl.make { From f5794617cc72e7840cc330741882cd2e8fbe551a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 6 May 2015 18:40:02 +0200 Subject: [PATCH 120/719] Merged upstream, fixed tests --- .../dsl/WiremockRequestStubStrategy.groovy | 7 ++--- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 29 ++++++++++++------- .../codearte/accurest/dsl/WiremockSpec.groovy | 12 ++++++++ build.gradle | 1 + 4 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index c0dfe0c43c..36f7ec1ab5 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,5 +1,4 @@ package io.codearte.accurest.dsl - import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientRequest @@ -7,8 +6,6 @@ import io.codearte.accurest.dsl.internal.Request import java.util.regex.Pattern -import static groovy.json.StringEscapeUtils.escapeJava - @TypeChecked @PackageScope class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { @@ -41,10 +38,10 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return [:] } if (containsRegex(body)) { - return [bodyPatterns: [matches: parseBody(body)]] + return [bodyPatterns: [[matches: parseBody(body)]]] } - return [bodyPatterns: [equalTo: parseBody(body)]] + return [bodyPatterns: [[equalTo: parseBody(body)]]] } boolean containsRegex(Object bodyObject) { 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 5f1684ec7d..4ff7fa09f5 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,7 @@ package io.codearte.accurest.dsl import groovy.json.JsonSlurper -import spock.lang.Specification -class WiremockGroovyDslSpec extends Specification { +class WiremockGroovyDslSpec extends WiremockSpec { def 'should convert groovy dsl stub to wiremock stub for the client side'() { given: @@ -48,6 +47,8 @@ class WiremockGroovyDslSpec extends Specification { } } ''') + and: + stubMappingIsValidWiremockStub(wiremockStub) } def 'should convert groovy dsl stub with Body as String to wiremock stub for the client side'() { @@ -91,6 +92,8 @@ class WiremockGroovyDslSpec extends Specification { } } ''') + and: + stubMappingIsValidWiremockStub(wiremockStub) } def 'should convert groovy dsl stub with simple Body as String to wiremock stub for the client side'() { @@ -141,12 +144,14 @@ class WiremockGroovyDslSpec extends Specification { } } ''') + and: + stubMappingIsValidWiremockStub(wiremockStub) } def 'should convert groovy dsl stub with regexp Body as String to wiremock stub for the client side'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + GroovyDsl groovyDsl = GroovyDsl.make { request { method('GET') url $(client(regex('/[0-9]{2}')), server('/12')) @@ -170,28 +175,30 @@ class WiremockGroovyDslSpec extends Specification { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", "urlPattern": "/[0-9]{2}", - "bodyPatterns": { - "matches":"{\\"personalId\\":\\"^[0-9]{11}$\\"}" - } + "bodyPatterns": [ + { + "matches":"{\\"personalId\\":\\"^[0-9]{11}$\\"}" + } + ] }, "response": { "status": 200, - "body": { - "name": "Jan" - }, + "body": "{\\"name\\":\\"Jan\\"}", "headers": { "Content-Type": "text/plain" } } } ''') + and: + stubMappingIsValidWiremockStub(wiremockStub) } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy new file mode 100644 index 0000000000..2a6237d89d --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy @@ -0,0 +1,12 @@ +package io.codearte.accurest.dsl + +import com.github.tomakehurst.wiremock.stubbing.StubMapping +import spock.lang.Specification + +class WiremockSpec extends Specification { + + void stubMappingIsValidWiremockStub(String mappingDefinition) { + StubMapping.buildFrom(mappingDefinition) + } + +} diff --git a/build.gradle b/build.gradle index e0a87bd555..c2d42cfdf1 100644 --- a/build.gradle +++ b/build.gradle @@ -89,6 +89,7 @@ project(':accurest-core') { compile 'commons-io:commons-io:2.4' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' + testCompile 'com.github.tomakehurst:wiremock:1.53' } } From ce42dd5e85c3aa91ae8e4884893bb265ca897cd0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 11 May 2015 18:17:06 +0200 Subject: [PATCH 121/719] [#55] Fixed regex processing on the server side --- .../builder/SpockMethodBodyBuilder.groovy | 7 +++++++ .../accurest/dsl/internal/Common.groovy | 4 ++++ .../dsl/internal/MethodProperty.groovy | 13 ++++++++++++ .../pairId/moreComplexVersion.groovy | 20 +++++++++++++++++++ .../ofg/twitter/place/PairIdController.groovy | 7 ++++++- 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MethodProperty.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 25ebd02b99..babee4264c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -5,6 +5,8 @@ import groovy.transform.PackageScope import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.Header +import java.util.regex.Pattern + /** * @author Jakub Kubrynski */ @@ -73,6 +75,8 @@ class SpockMethodBodyBuilder { processMapElement(value, blockBuilder, property) } else if (value instanceof List) { processArrayElements(value, property, blockBuilder) + } else if (value instanceof Pattern) { + blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") } else { blockBuilder.addLine("responseBody$property == ${value}") } @@ -90,4 +94,7 @@ class SpockMethodBodyBuilder { } } } + private void processClosure(Closure value, BlockBuilder blockBuilder, String property) { + blockBuilder.addLine() + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index f6eb65ab9e..864c52efe4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -66,6 +66,10 @@ class Common { return Pattern.compile(regex) } + MethodProperty execute(String closureDefinition) { + return new MethodProperty(closureDefinition) + } + ClientDslProperty client(Object clientValue) { return new ClientDslProperty(clientValue) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MethodProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MethodProperty.groovy new file mode 100644 index 0000000000..b707a8a7c1 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MethodProperty.groovy @@ -0,0 +1,13 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic + +@CompileStatic +class MethodProperty { + + final String closureDefinition + + MethodProperty(String closureDefinition) { + this.closureDefinition = closureDefinition + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy new file mode 100644 index 0000000000..9937b43721 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy @@ -0,0 +1,20 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] +''' + } + response { + body ( + path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))) + ) + status 200 + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy index 8a4e1e2e63..ee02469454 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy @@ -21,10 +21,15 @@ class PairIdController { method = PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - void getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { + String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { log.info("Inside PairIdController, doing very important logic") if (tweets?.text != ["Gonna see you at Warsaw"]) { throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") } + return """ + { + "path" : "/api/$pairId" + } + """ } } From 4bf33387604138c1eb1d7aefd1e1749a65941e94 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 11 May 2015 18:17:06 +0200 Subject: [PATCH 122/719] [#55] Fixed regex processing on the server side --- .../builder/SpockMethodBodyBuilder.groovy | 7 +++++++ .../pairId/moreComplexVersion.groovy | 20 +++++++++++++++++++ .../ofg/twitter/place/PairIdController.groovy | 7 ++++++- 3 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 25ebd02b99..babee4264c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -5,6 +5,8 @@ import groovy.transform.PackageScope import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.Header +import java.util.regex.Pattern + /** * @author Jakub Kubrynski */ @@ -73,6 +75,8 @@ class SpockMethodBodyBuilder { processMapElement(value, blockBuilder, property) } else if (value instanceof List) { processArrayElements(value, property, blockBuilder) + } else if (value instanceof Pattern) { + blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") } else { blockBuilder.addLine("responseBody$property == ${value}") } @@ -90,4 +94,7 @@ class SpockMethodBodyBuilder { } } } + private void processClosure(Closure value, BlockBuilder blockBuilder, String property) { + blockBuilder.addLine() + } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy new file mode 100644 index 0000000000..9937b43721 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy @@ -0,0 +1,20 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] +''' + } + response { + body ( + path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))) + ) + status 200 + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy index 8a4e1e2e63..ee02469454 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy @@ -21,10 +21,15 @@ class PairIdController { method = PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - void getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { + String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { log.info("Inside PairIdController, doing very important logic") if (tweets?.text != ["Gonna see you at Warsaw"]) { throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") } + return """ + { + "path" : "/api/$pairId" + } + """ } } From efc8e9ec72b62f86dd3af6c4b8aec4369f77a3d8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 11 May 2015 18:40:06 +0200 Subject: [PATCH 123/719] Revert "[#55] Fixed regex processing on the server side" This reverts commit ce42dd5e85c3aa91ae8e4884893bb265ca897cd0. --- .../builder/SpockMethodBodyBuilder.groovy | 7 ------- .../accurest/dsl/internal/Common.groovy | 4 ---- .../dsl/internal/MethodProperty.groovy | 13 ------------ .../pairId/moreComplexVersion.groovy | 20 ------------------- .../ofg/twitter/place/PairIdController.groovy | 7 +------ 5 files changed, 1 insertion(+), 50 deletions(-) delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MethodProperty.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index babee4264c..25ebd02b99 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -5,8 +5,6 @@ import groovy.transform.PackageScope import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.Header -import java.util.regex.Pattern - /** * @author Jakub Kubrynski */ @@ -75,8 +73,6 @@ class SpockMethodBodyBuilder { processMapElement(value, blockBuilder, property) } else if (value instanceof List) { processArrayElements(value, property, blockBuilder) - } else if (value instanceof Pattern) { - blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") } else { blockBuilder.addLine("responseBody$property == ${value}") } @@ -94,7 +90,4 @@ class SpockMethodBodyBuilder { } } } - private void processClosure(Closure value, BlockBuilder blockBuilder, String property) { - blockBuilder.addLine() - } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 864c52efe4..f6eb65ab9e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -66,10 +66,6 @@ class Common { return Pattern.compile(regex) } - MethodProperty execute(String closureDefinition) { - return new MethodProperty(closureDefinition) - } - ClientDslProperty client(Object clientValue) { return new ClientDslProperty(clientValue) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MethodProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MethodProperty.groovy deleted file mode 100644 index b707a8a7c1..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MethodProperty.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.CompileStatic - -@CompileStatic -class MethodProperty { - - final String closureDefinition - - MethodProperty(String closureDefinition) { - this.closureDefinition = closureDefinition - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy deleted file mode 100644 index 9937b43721..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy +++ /dev/null @@ -1,20 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - body ( - path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))) - ) - status 200 - } -} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy index ee02469454..8a4e1e2e63 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy @@ -21,15 +21,10 @@ class PairIdController { method = PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { + void getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { log.info("Inside PairIdController, doing very important logic") if (tweets?.text != ["Gonna see you at Warsaw"]) { throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") } - return """ - { - "path" : "/api/$pairId" - } - """ } } From 4d02af97114b485d4b594e985f760831ab6fdefe Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 11 May 2015 19:03:08 +0200 Subject: [PATCH 124/719] [#58] Added method execution on server side --- .../builder/SpockMethodBodyBuilder.groovy | 4 ++++ .../accurest/dsl/internal/Common.groovy | 4 ++++ .../dsl/internal/ExecutionProperty.groovy | 19 +++++++++++++++++++ .../dsl/internal/ExecutionPropertySpec.groovy | 19 +++++++++++++++++++ .../pairId/moreComplexVersion.groovy | 3 ++- .../ofg/twitter/place/PairIdController.groovy | 3 ++- .../ofg/twitter/places/BaseMockMvcSpec.groovy | 4 ++++ 7 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index babee4264c..532e429952 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.builder import groovy.json.JsonOutput import groovy.transform.PackageScope import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Header import java.util.regex.Pattern @@ -77,6 +78,9 @@ class SpockMethodBodyBuilder { processArrayElements(value, property, blockBuilder) } else if (value instanceof Pattern) { blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") + } else if (value instanceof ExecutionProperty) { + ExecutionProperty exec = (ExecutionProperty) value + blockBuilder.addLine("${exec.insertValue("responseBody$property")}") } else { blockBuilder.addLine("responseBody$property == ${value}") } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index f6eb65ab9e..91549f6409 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -66,6 +66,10 @@ class Common { return Pattern.compile(regex) } + ExecutionProperty execute(String commandToExecute) { + return new ExecutionProperty(commandToExecute) + } + ClientDslProperty client(Object clientValue) { return new ClientDslProperty(clientValue) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy new file mode 100644 index 0000000000..ccc7037575 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy @@ -0,0 +1,19 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic + +@CompileStatic +class ExecutionProperty { + + private static final String PLACEHOLDER_VALUE = '\\$it' + + final String executionCommand + + ExecutionProperty(String executionCommand) { + this.executionCommand = executionCommand + } + + String insertValue(String valueToInsert) { + return executionCommand.replaceAll(PLACEHOLDER_VALUE, valueToInsert) + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy new file mode 100644 index 0000000000..d8660a8433 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy @@ -0,0 +1,19 @@ +package io.codearte.accurest.dsl.internal + +import spock.lang.Specification + +class ExecutionPropertySpec extends Specification { + + def 'should insert passed value in place of $it placeholder'() { + given: + String commandToExecute = 'commandToExecute($it)' + ExecutionProperty executionProperty = new ExecutionProperty(commandToExecute) + and: + String valueToInsert = 'someObject.itsValue' + when: + String commandWithInsertedValue = executionProperty.insertValue(valueToInsert) + then: + 'commandToExecute(someObject.itsValue)' == commandWithInsertedValue + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy index 9937b43721..fdeb658215 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy @@ -13,7 +13,8 @@ io.codearte.accurest.dsl.GroovyDsl.make { } response { body ( - path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))) + path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), + correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) ) status 200 } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy index ee02469454..4f49f1ed3b 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy @@ -28,7 +28,8 @@ class PairIdController { } return """ { - "path" : "/api/$pairId" + "path" : "/api/$pairId", + "correlationId" : 123456 } """ } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy index b88c863fcc..cade991eaa 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy @@ -9,4 +9,8 @@ abstract class BaseMockMvcSpec extends Specification { def setup() { RestAssuredMockMvc.standaloneSetup(new PairIdController()) } + + void isProperCorrelationId(Integer correlationId) { + assert correlationId == 123456 + } } From 25f8e94556b3d8d90a94e3d44f590f1cdb05cb9c Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 11 May 2015 21:15:55 +0200 Subject: [PATCH 125/719] Release version: 0.6.0 [ci skip] From bd6a4c4b4c4609a2fe8c2c2d1d268a7b0b99ecec Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 May 2015 00:02:04 +0200 Subject: [PATCH 126/719] [#49] Added missing request body conversion of Wiremock to DSL --- .../wiremock/WiremockToDslConverter.groovy | 27 +++--- .../WiremockToDslConverterSpec.groovy | 84 ++++++++++++++++++- .../io/codearte/accurest/dsl/GroovyDsl.groovy | 2 +- .../accurest/dsl/internal/Request.groovy | 6 +- .../accurest/dsl/internal/Response.groovy | 23 ++--- 5 files changed, 105 insertions(+), 37 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index bfc58cc17d..beb15bfd2b 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 @@ -16,6 +16,7 @@ class WiremockToDslConverter { Object wiremockStub = new JsonSlurper().parseText(wiremockStringStub) def request = wiremockStub.request def response = wiremockStub.response + def bodyPatterns = request.bodyPatterns return """\ request { ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} @@ -23,18 +24,20 @@ class WiremockToDslConverter { ${request.urlPattern ? "url \$(client(regex('${escapeJava(request.urlPattern)}')), server(''))" : ""} ${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""} ${ - request.headers ? """headers { - ${ - request.headers.collect { - def assertion = it.value - String headerName = it.key as String - def entry = assertion.entrySet().first() - """header(\"\"\"$headerName\"\"\", ${buildHeader(entry.key, entry.value)})\n""" - }.join('') - } - } - """ : "" - } + request.headers ? """headers { + ${ + request.headers.collect { + def assertion = it.value + String headerName = it.key as String + def entry = assertion.entrySet().first() + """header(\"\"\"$headerName\"\"\", ${buildHeader(entry.key, entry.value)})\n""" + }.join('') + } + } + """ : "" + } + ${bodyPatterns?.equalTo ? "body('''${bodyPatterns.equalTo}''')" : '' } + ${bodyPatterns?.matches ? "body \$(client(regex('${escapeJava(bodyPatterns.matches)}')), server(''))" : ""} } response { ${response.status ? "status $response.status" : ""} diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 7466b2e7f5..a88c05681e 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -71,7 +71,7 @@ class WiremockToDslConverterSpec extends Specification { } - def 'should convert Wiremock stub with body containing simple JSON'() { + def 'should convert Wiremock stub with response body containing simple JSON'() { given: String wiremockStub = '''\ { @@ -122,7 +122,7 @@ class WiremockToDslConverterSpec extends Specification { }""") == expectedGroovyDsl } - def 'should convert Wiremock stub with body containing integer'() { + def 'should convert Wiremock stub with response body containing integer'() { given: String wiremockStub = '''\ { @@ -171,7 +171,7 @@ class WiremockToDslConverterSpec extends Specification { }""") == expectedGroovyDsl } - def 'should convert Wiremock stub with body as a list'() { + def 'should convert Wiremock stub with response body as a list'() { given: String wiremockStub = '''\ { @@ -224,7 +224,7 @@ class WiremockToDslConverterSpec extends Specification { } - def 'should convert Wiremock stub with body containing a nested list'() { + def 'should convert Wiremock stub with response body containing a nested list'() { given: String wiremockStub = '''\ { @@ -287,4 +287,80 @@ class WiremockToDslConverterSpec extends Specification { }""") == expectedGroovyDsl } + def 'should convert Wiremock stub with request body checking equality to Json'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/test", + "bodyPatterns": { + "equalTo": "{\\"property1\\":\\"abc\\",\\"property2\\":\\"2017-01\\",\\"property3\\":\\"666\\",\\"property4\\":1428566412}" + } + }, + "response": { + "status": 200 + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/test' + body ('''{"property1":"abc","property2":"2017-01","property3":"666","property4":1428566412}''') + } + response { + status 200 + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + """ io.codearte.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") + and: + evaluatedGroovyDsl == expectedGroovyDsl + } + + def 'should convert Wiremock stub with request body checking matching to Json'() { + given: + String wiremockStub = '''\ +{ + "request": { + "method": "POST", + "url": "/test", + "bodyPatterns": { + "matches": "[0-9]{5}" + } + }, + "response": { + "status": 200 + } +} +''' + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/test' + body $(client(~/[0-9]{5}/), server('')) + } + response { + status 200 + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + """ io.codearte.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") + and: + evaluatedGroovyDsl == expectedGroovyDsl + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy index 717047341d..1007e14cec 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy @@ -7,7 +7,7 @@ import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.dsl.internal.Response @TypeChecked -@EqualsAndHashCode(includeFields = true) +@EqualsAndHashCode @ToString(includeFields = true, includePackage = false, includeNames = true) class GroovyDsl { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 77652a9396..50bd42910c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -5,7 +5,7 @@ import groovy.transform.ToString import groovy.transform.TypeChecked @TypeChecked -@EqualsAndHashCode(includeFields = true) +@EqualsAndHashCode @ToString(includePackage = false, includeNames = true) class Request extends Common { @@ -64,7 +64,7 @@ class Request extends Common { } @CompileStatic -@EqualsAndHashCode(includeFields = true) +@EqualsAndHashCode @ToString(includePackage = false) class ServerRequest extends Request { ServerRequest(Request request) { @@ -73,7 +73,7 @@ class ServerRequest extends Request { } @CompileStatic -@EqualsAndHashCode(includeFields = true) +@EqualsAndHashCode @ToString(includePackage = false) class ClientRequest extends Request { ClientRequest(Request request) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy index ce8a7b3b7d..3715f0c243 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy @@ -6,13 +6,13 @@ import groovy.transform.ToString import groovy.transform.TypeChecked @TypeChecked -@EqualsAndHashCode(includeFields = true) +@EqualsAndHashCode @ToString(includePackage = false, includeFields = true) class Response extends Common { - private DslProperty status - private Headers headers - private Body body + DslProperty status + Headers headers + Body body Response() { } @@ -49,21 +49,10 @@ class Response extends Common { this.body = new Body(bodyAsValue) } - Body getBody() { - return body - } - - DslProperty getStatus() { - return status - } - - Headers getHeaders() { - return headers - } } @CompileStatic -@EqualsAndHashCode(includeFields = true) +@EqualsAndHashCode @ToString(includePackage = false) class ServerResponse extends Response { ServerResponse(Response request) { @@ -72,7 +61,7 @@ class ServerResponse extends Response { } @CompileStatic -@EqualsAndHashCode(includeFields = true) +@EqualsAndHashCode @ToString(includePackage = false) class ClientResponse extends Response { ClientResponse(Response request) { From 40bce485df1e9608fc6d98343cf222e101ab3b85 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 May 2015 11:15:06 +0200 Subject: [PATCH 127/719] [#49] Fixed two more issues with the conversion --- .../wiremock/WiremockToDslConverter.groovy | 39 +- .../WiremockToDslConverterSpec.groovy | 376 ++++++++++++------ build.gradle | 1 + 3 files changed, 279 insertions(+), 137 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index beb15bfd2b..76570ee2b2 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 @@ -18,12 +18,12 @@ class WiremockToDslConverter { def response = wiremockStub.response def bodyPatterns = request.bodyPatterns return """\ - request { - ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} - ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} - ${request.urlPattern ? "url \$(client(regex('${escapeJava(request.urlPattern)}')), server(''))" : ""} - ${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""} - ${ + request { + ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} + ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} + ${request.urlPattern ? "url \$(client(regex('${escapeJava(request.urlPattern)}')), server(''))" : ""} + ${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""} + ${ request.headers ? """headers { ${ request.headers.collect { @@ -36,20 +36,21 @@ class WiremockToDslConverter { } """ : "" } - ${bodyPatterns?.equalTo ? "body('''${bodyPatterns.equalTo}''')" : '' } - ${bodyPatterns?.matches ? "body \$(client(regex('${escapeJava(bodyPatterns.matches)}')), server(''))" : ""} - } - response { - ${response.status ? "status $response.status" : ""} - ${response.body ? "body( ${buildBody(response.body)})" : ""} - ${ + ${bodyPatterns?.equalTo?.every { it } ? "body('''${bodyPatterns.equalTo[0]}''')" : ''} + ${bodyPatterns?.equalToJson?.every { it } ? "body('''${bodyPatterns.equalToJson[0]}''')" : ''} + ${bodyPatterns?.matches?.every { it } ? "body \$(client(regex('${escapeJava(bodyPatterns.matches[0])}')), server(''))" : ""} + } + response { + ${response.status ? "status $response.status" : ""} + ${response.body ? "body( ${buildBody(response.body)})" : ""} + ${ response.headers ? """headers { - ${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')} - } - """ : "" + ${response.headers.collect { "header('$it.key': '${it.value}')\n" }.join('')} + } + """ : "" } - } - """ + } + """ } private String buildHeader(String method, Object value) { @@ -158,7 +159,7 @@ class WiremockToDslConverter { static String wrapWithFactoryMethod(String dslFromWiremockStub) { return """\ ${GroovyDsl.name}.make { - $dslFromWiremockStub + $dslFromWiremockStub } """ } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index a88c05681e..98d74e6ca2 100755 --- 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,5 +1,6 @@ package io.codearte.accurest.wiremock +import com.github.tomakehurst.wiremock.stubbing.StubMapping import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification @@ -9,27 +10,29 @@ class WiremockToDslConverterSpec extends Specification { given: String wiremockStub = '''\ { - "request": { - "method": "GET", - "url": "/path", - "headers" : { - "Accept": { - "matches": "text/.*" - }, - "X-Custom-Header": { - "contains": "2134" - } - } - }, - "response": { - "status": 200, - "body": "{ \\"id\\": { \\"value\\": \\"132\\" }, \\"surname\\": \\"Kowalsky\\", \\"name\\": \\"Jan\\", \\"created\\": \\"2014-02-02 12:23:43\\" }", - "headers": { - "Content-Type": "text/plain", - } - } + "request": { + "method": "GET", + "url": "/path", + "headers" : { + "Accept": { + "matches": "text/.*" + }, + "X-Custom-Header": { + "contains": "2134" + } + } + }, + "response": { + "status": 200, + "body": "{ \\"id\\": { \\"value\\": \\"132\\" }, \\"surname\\": \\"Kowalsky\\", \\"name\\": \\"Jan\\", \\"created\\": \\"2014-02-02 12:23:43\\" }", + "headers": { + "Content-Type": "text/plain" + } + } } ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -66,8 +69,8 @@ class WiremockToDslConverterSpec extends Specification { then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { - $groovyDsl - }""") == expectedGroovyDsl + $groovyDsl + }""") == expectedGroovyDsl } @@ -75,24 +78,26 @@ class WiremockToDslConverterSpec extends Specification { given: String wiremockStub = '''\ { - "request": { - "method": "DELETE", - "urlPattern": "/credit-card-verification-data/[0-9]+", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8" - } - } - }, - "response": { - "status": 200, - "body": "{\\"status\\": \\"OK\\"}", - "headers": { - "Content-Type": "application/json" - } - } + "request": { + "method": "DELETE", + "urlPattern": "/credit-card-verification-data/[0-9]+", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.mymoid-adapter.v2+json; charset=UTF-8" + } + } + }, + "response": { + "status": 200, + "body": "{\\"status\\": \\"OK\\"}", + "headers": { + "Content-Type": "application/json" + } + } } ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -105,7 +110,7 @@ class WiremockToDslConverterSpec extends Specification { response { status 200 body("""{ - "status": "OK" + "status": "OK" }""") headers { header 'Content-Type': 'application/json' @@ -118,8 +123,8 @@ class WiremockToDslConverterSpec extends Specification { then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { - $groovyDsl - }""") == expectedGroovyDsl + $groovyDsl + }""") == expectedGroovyDsl } def 'should convert Wiremock stub with response body containing integer'() { @@ -127,23 +132,25 @@ class WiremockToDslConverterSpec extends Specification { String wiremockStub = '''\ { "request": { - "method": "POST", - "url": "/charge/count", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.creditcard-reporter.v1+json" - } - } + "method": "POST", + "url": "/charge/count", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } }, "response": { - "status": 200, - "body": 200, - "headers": { - "Content-Type": "application/json" - } + "status": 200, + "body": 200, + "headers": { + "Content-Type": "application/json" + } } } ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -167,8 +174,8 @@ class WiremockToDslConverterSpec extends Specification { then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { - $groovyDsl - }""") == expectedGroovyDsl + $groovyDsl + }""") == expectedGroovyDsl } def 'should convert Wiremock stub with response body as a list'() { @@ -176,23 +183,25 @@ class WiremockToDslConverterSpec extends Specification { String wiremockStub = '''\ { "request": { - "method": "POST", - "url": "/charge/count", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.creditcard-reporter.v1+json" - } - } + "method": "POST", + "url": "/charge/count", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } }, "response": { - "status": 200, - "body": "[ {\\"a\\":1, \\"c\\":\\"3\\"}, \\"b\\", \\"a\\" ]", - "headers": { - "Content-Type": "application/json" - } + "status": 200, + "body": "[ {\\"a\\":1, \\"c\\":\\"3\\"}, \\"b\\", \\"a\\" ]", + "headers": { + "Content-Type": "application/json" + } } } ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -219,8 +228,8 @@ class WiremockToDslConverterSpec extends Specification { then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { - $groovyDsl - }""") == expectedGroovyDsl + $groovyDsl + }""") == expectedGroovyDsl } @@ -229,20 +238,22 @@ class WiremockToDslConverterSpec extends Specification { String wiremockStub = '''\ { "request": { - "method": "POST", - "url": "/charge/search?pageNumber=0&size=2147483647", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.creditcard-reporter.v1+json" - } - } + "method": "POST", + "url": "/charge/search?pageNumber=0&size=2147483647", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.creditcard-reporter.v1+json" + } + } }, "response": { - "status": 200, - "body":"[{\\"amount\\":1.01,\\"name\\":\\"Name\\",\\"info\\":{\\"title\\":\\"title1\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null},{\\"amount\\":2.01,\\"name\\":\\"Name2\\",\\"info\\":{\\"title\\":\\"title2\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null}]" - } + "status": 200, + "body":"[{\\"amount\\":1.01,\\"name\\":\\"Name\\",\\"info\\":{\\"title\\":\\"title1\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null},{\\"amount\\":2.01,\\"name\\":\\"Name2\\",\\"info\\":{\\"title\\":\\"title2\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null}]" + } } ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -255,26 +266,26 @@ class WiremockToDslConverterSpec extends Specification { response { status 200 body("""[ - { - "amount": 1.01, - "name": "Name", - "info": { - "title": "title1", - "payload": null - }, - "booleanvalue": true, - "user": null - }, - { - "amount": 2.01, - "name": "Name2", - "info": { - "title": "title2", - "payload": null - }, - "booleanvalue": true, - "user": null - } + { + "amount": 1.01, + "name": "Name", + "info": { + "title": "title1", + "payload": null + }, + "booleanvalue": true, + "user": null + }, + { + "amount": 2.01, + "name": "Name2", + "info": { + "title": "title2", + "payload": null + }, + "booleanvalue": true, + "user": null + } ]""") } } @@ -283,8 +294,8 @@ class WiremockToDslConverterSpec extends Specification { then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { - $groovyDsl - }""") == expectedGroovyDsl + $groovyDsl + }""") == expectedGroovyDsl } def 'should convert Wiremock stub with request body checking equality to Json'() { @@ -292,17 +303,19 @@ class WiremockToDslConverterSpec extends Specification { String wiremockStub = '''\ { "request": { - "method": "POST", - "url": "/test", - "bodyPatterns": { - "equalTo": "{\\"property1\\":\\"abc\\",\\"property2\\":\\"2017-01\\",\\"property3\\":\\"666\\",\\"property4\\":1428566412}" - } + "method": "POST", + "url": "/test", + "bodyPatterns": [{ + "equalTo": "{\\"property1\\":\\"abc\\",\\"property2\\":\\"2017-01\\",\\"property3\\":\\"666\\",\\"property4\\":1428566412}" + }] }, "response": { - "status": 200 - } + "status": 200 + } } ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -319,8 +332,8 @@ class WiremockToDslConverterSpec extends Specification { then: GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { - $groovyDsl - }""") + $groovyDsl + }""") and: evaluatedGroovyDsl == expectedGroovyDsl } @@ -330,17 +343,19 @@ class WiremockToDslConverterSpec extends Specification { String wiremockStub = '''\ { "request": { - "method": "POST", - "url": "/test", - "bodyPatterns": { - "matches": "[0-9]{5}" - } + "method": "POST", + "url": "/test", + "bodyPatterns": [{ + "matches": "[0-9]{5}" + }] }, "response": { - "status": 200 - } + "status": 200 + } } ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -357,10 +372,135 @@ class WiremockToDslConverterSpec extends Specification { then: GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { - $groovyDsl - }""") + $groovyDsl + }""") and: evaluatedGroovyDsl == expectedGroovyDsl } + def 'should convert Wiremock stub with request body with equalToJson'() { + given: + String wiremockStub = '''\ +{ + "request" : { + "url" : "/test", + "method" : "POST", + "bodyPatterns" : [ { + "equalToJson" : "{\\"pan\\":\\"4855141150107894\\",\\"expirationDate\\":\\"2017-01\\",\\"dcvx\\":\\"178\\"}", + "jsonCompareMode" : "LENIENT" + } ] + }, + "response" : { + "status" : 200 + } +} +''' + and: + stubMappingIsValidWiremockStub(wiremockStub) + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/test' + body '''{"pan":"4855141150107894","expirationDate":"2017-01","dcvx":"178"}''' + } + response { + status 200 + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + """ io.codearte.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") + and: + evaluatedGroovyDsl == expectedGroovyDsl + } + + def 'should convert Wiremock stub with request body with equalTo'() { + given: + String wiremockStub = '''\ + { + "request" : { + "url" : "/test", + "method" : "POST", + "bodyPatterns" : [ { + "equalTo" : "{\\"pan\\":\\"4855141150107894\\",\\"expirationDate\\":\\"2017-01\\",\\"dcvx\\":\\"178\\"}" + } ] + }, + "response" : { + "status" : 200 + } + } + ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/test' + body '''{"pan":"4855141150107894","expirationDate":"2017-01","dcvx":"178"}''' + } + response { + status 200 + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + """ io.codearte.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") + and: + evaluatedGroovyDsl == expectedGroovyDsl + } + + def 'should convert Wiremock stub with request body with matches'() { + given: + String wiremockStub = '''\ + { + "request" : { + "url" : "/test", + "method" : "POST", + "bodyPatterns" : [ { + "matches" : "[0-9]{2}" + } ] + }, + "response" : { + "status" : 200 + } + } + ''' + and: + stubMappingIsValidWiremockStub(wiremockStub) + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/test' + body $(client(~/[0-9]{2}/), server('')) + } + response { + status 200 + } + } + when: + String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + then: + GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + """ io.codearte.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") + and: + evaluatedGroovyDsl == expectedGroovyDsl + } + + void stubMappingIsValidWiremockStub(String mappingDefinition) { + StubMapping.buildFrom(mappingDefinition) + } + } diff --git a/build.gradle b/build.gradle index c2d42cfdf1..28d6b6d0a2 100644 --- a/build.gradle +++ b/build.gradle @@ -98,6 +98,7 @@ project(':accurest-converters') { compile project(':accurest-core') compile 'org.apache.commons:commons-lang3:3.3.2' compile 'commons-io:commons-io:[2.4,)' + testCompile 'com.github.tomakehurst:wiremock:1.53' } } From f581bb561f93406ff0da8c8eecf9d96a3af4155e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 May 2015 12:20:25 +0200 Subject: [PATCH 128/719] [#5] Adding assertions of patterns --- .../wiremock/WiremockToDslConverter.groovy | 6 ++++-- .../wiremock/WiremockToDslConverterSpec.groovy | 6 +++--- .../codearte/accurest/dsl/internal/Common.groovy | 14 ++++++++++++++ build.gradle | 4 ++++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index 76570ee2b2..543f9eff89 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy @@ -4,6 +4,7 @@ import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.xml.XmlUtil import io.codearte.accurest.dsl.GroovyDsl +import nl.flotsam.xeger.Xeger import static org.apache.commons.lang3.StringEscapeUtils.escapeJava @@ -17,11 +18,12 @@ class WiremockToDslConverter { def request = wiremockStub.request def response = wiremockStub.response def bodyPatterns = request.bodyPatterns + String urlPattern = request.urlPattern return """\ request { ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} - ${request.urlPattern ? "url \$(client(regex('${escapeJava(request.urlPattern)}')), server(''))" : ""} + ${urlPattern ? "url \$(client(regex('${escapeJava(urlPattern)}')), server('${new Xeger(escapeJava(urlPattern)).generate()}'))" : ""} ${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""} ${ request.headers ? """headers { @@ -38,7 +40,7 @@ class WiremockToDslConverter { } ${bodyPatterns?.equalTo?.every { it } ? "body('''${bodyPatterns.equalTo[0]}''')" : ''} ${bodyPatterns?.equalToJson?.every { it } ? "body('''${bodyPatterns.equalToJson[0]}''')" : ''} - ${bodyPatterns?.matches?.every { it } ? "body \$(client(regex('${escapeJava(bodyPatterns.matches[0])}')), server(''))" : ""} + ${bodyPatterns?.matches?.every { it } ? "body \$(client(regex('${escapeJava(bodyPatterns.matches[0])}')), server('${new Xeger(escapeJava(bodyPatterns.matches[0])).generate()}'))" : ""} } response { ${response.status ? "status $response.status" : ""} diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy index 98d74e6ca2..b147d9da93 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy @@ -102,7 +102,7 @@ class WiremockToDslConverterSpec extends Specification { GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { method 'DELETE' - url $(client(~/\/credit-card-verification-data\/[0-9]+/), server('')) + url $(client(~/\/credit-card-verification-data\/[0-9]+/), server('/credit-card-verification-data/1')) headers { header('Content-Type': 'application/vnd.mymoid-adapter.v2+json; charset=UTF-8') } @@ -361,7 +361,7 @@ class WiremockToDslConverterSpec extends Specification { request { method 'POST' url '/test' - body $(client(~/[0-9]{5}/), server('')) + body $(client(~/[0-9]{5}/), server('12345')) } response { status 200 @@ -482,7 +482,7 @@ class WiremockToDslConverterSpec extends Specification { request { method 'POST' url '/test' - body $(client(~/[0-9]{2}/), server('')) + body $(client(~/[0-9]{2}/), server('12')) } response { status 200 diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 91549f6409..608f15eec3 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -47,10 +47,12 @@ class Common { } DslProperty value(ClientDslProperty client, ServerDslProperty server) { + assertThatSidesMatch(client.clientValue, server.serverValue) return new DslProperty(client.clientValue, server.serverValue) } DslProperty value(ServerDslProperty server, ClientDslProperty client) { + assertThatSidesMatch(client.clientValue, server.serverValue) return new DslProperty(client.clientValue, server.serverValue) } @@ -77,4 +79,16 @@ class Common { ServerDslProperty server(Object serverValue) { return new ServerDslProperty(serverValue) } + + void assertThatSidesMatch(Pattern firstSide, Object secondSide) { + assert secondSide ==~ firstSide + } + + void assertThatSidesMatch(Object firstSide, Pattern secondSide) { + assert secondSide ==~ firstSide + } + + void assertThatSidesMatch(Object firstSide, Object secondSide) { + // do nothing + } } diff --git a/build.gradle b/build.gradle index 28d6b6d0a2..783681eebd 100644 --- a/build.gradle +++ b/build.gradle @@ -47,6 +47,9 @@ subprojects { repositories { mavenLocal() mavenCentral() + maven { + url "https://jitpack.io" + } } //Dependencies in all subprojects - http://solidsoft.wordpress.com/2014/11/13/gradle-tricks-display-dependencies-for-all-subprojects-in-multi-project-build/ @@ -98,6 +101,7 @@ project(':accurest-converters') { compile project(':accurest-core') compile 'org.apache.commons:commons-lang3:3.3.2' compile 'commons-io:commons-io:[2.4,)' + compile 'com.github.marcingrzejszczak:xeger:20130128' testCompile 'com.github.tomakehurst:wiremock:1.53' } } From 613b2d800ddb627f19ac63f93813f50f06bb20ce Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 May 2015 12:43:19 +0200 Subject: [PATCH 129/719] [#5] Added missing file --- .../io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 4ff7fa09f5..b813ee11ef 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 @@ -239,7 +239,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { GroovyDsl groovyDsl = GroovyDsl.make { request { url $( - client(~/\/^[0-9]{2}$/), + client(~/^\/[0-9]{2}$/), server('/12') ) } @@ -247,7 +247,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { expect: new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { - "urlPattern":"/^[0-9]{2}$" + "urlPattern":"^/[0-9]{2}$" } ''') } From 7e7e3ff003c3da920ca24765f8d653cdbc0e91b7 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 May 2015 16:14:46 +0200 Subject: [PATCH 130/719] [#49] Fixed missing conversion of request body --- .../dsl/WiremockRequestStubStrategy.groovy | 8 ++- .../dsl/WiremockResponseStubStrategy.groovy | 12 ++-- .../accurest/dsl/internal/Body.groovy | 34 +++++++++-- .../accurest/util/JsonConverter.groovy | 38 ++++++++++++ .../accurest/util/StubMappingConverter.groovy | 53 ----------------- .../builder/SpockMethodBuilderSpec.groovy | 59 +++++++++++++++++++ 6 files changed, 139 insertions(+), 65 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/JsonConverter.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/StubMappingConverter.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 36f7ec1ab5..97a7e942ba 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -3,6 +3,7 @@ import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientRequest import io.codearte.accurest.dsl.internal.Request +import io.codearte.accurest.util.JsonConverter import java.util.regex.Pattern @@ -38,9 +39,8 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return [:] } if (containsRegex(body)) { - return [bodyPatterns: [[matches: parseBody(body)]]] + return [bodyPatterns: [[matches: parseBody(JsonConverter.transformValues(body, { it.toString() }))]]] } - return [bodyPatterns: [[equalTo: parseBody(body)]]] } @@ -49,4 +49,8 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return (bodyString =~ /\^.*\$/).find() } + boolean containsRegex(Map map) { + return map.values().any { it instanceof Pattern } + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy index e0b7556547..b517150236 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -21,12 +21,12 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { private Map buildResponseContent(ClientResponse response) { return ([status : response?.status?.clientValue, - headers: buildClientResponseHeadersSection(response.headers) - ] << appendBody(response)).findAll { it.value } + 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)] : [:] - } + 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/codearte/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy index 5e8d46ed98..da602b5ebc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy @@ -3,12 +3,19 @@ package io.codearte.accurest.dsl.internal import groovy.json.JsonSlurper import groovy.transform.EqualsAndHashCode import groovy.transform.ToString +import io.codearte.accurest.util.JsonConverter import org.codehaus.groovy.runtime.GStringImpl +import java.util.regex.Matcher +import java.util.regex.Pattern + @ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) class Body extends DslProperty { + private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') + private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' + Body(Map body) { super(extractValue(body, {it.clientValue}), extractValue(body, {it.serverValue})) } @@ -36,9 +43,28 @@ class Body extends DslProperty { } private static Object extractValue(GString bodyAsValue, Closure valueProvider) { - GString clientGString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) - Object[] clientValues = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[] - return new JsonSlurper().parseText(new GStringImpl(clientValues, clientGString.strings).toString()) + GString gString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) + Object[] values = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[] + Object[] valuesWithRegexpsAsTransformedStrings = values.collect { + it instanceof Pattern ? String.format(JSON_VALUE_PATTERN_FOR_REGEX, it.toString()) : it + } as Object[] + def parsedJson = new JsonSlurper().parseText(new GStringImpl(valuesWithRegexpsAsTransformedStrings, gString.strings)) + return convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) } - + + private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) { + JsonConverter.transformValues(parsedJson, { Object value -> + if (value instanceof String) { + String string = (String) value + Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string) + if (matcher.matches()) { + String pattern = matcher[0][1] + return Pattern.compile(pattern) + } + return value + } + return value + }) + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonConverter.groovy new file mode 100644 index 0000000000..208a3aefa3 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonConverter.groovy @@ -0,0 +1,38 @@ +package io.codearte.accurest.util + +import groovy.json.JsonSlurper +/** + * @author Marcin Grzejszczak + */ +class JsonConverter { + + private static Map convert(Map map, Closure closure) { + return map.collectEntries { + key, value -> + [key, transformValues(value, closure)] + } + } + + static def transformValues(def value, Closure closure) { + if (value instanceof String && value) { + try { + def json = new JsonSlurper().parseText(value) + if (json instanceof Map) { + return convert(json, closure) + } + } catch (Exception ignore) { + return closure(value) + } + } else if (value instanceof Map) { + return convert(value as Map, closure) + } else if (value instanceof List) { + return value.collect({ transformValues(it, closure) }) + } + try { + return closure(value) + } catch (Exception ignore) { + return value + } + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/StubMappingConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/StubMappingConverter.groovy deleted file mode 100644 index f1ce59959f..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/StubMappingConverter.groovy +++ /dev/null @@ -1,53 +0,0 @@ -package io.codearte.accurest.util - -import groovy.json.JsonException -import groovy.json.JsonSlurper - -import java.util.regex.Pattern - -/** - * @author Marcin Grzejszczak - */ -class StubMappingConverter { - - private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile(/^\$\{(.*):(.*)\}$/) - public static final int SERVER_SIDE_GROUP = 2 - - static Map toStubMappingOnServerSide(File stubMapping) { - def json = new JsonSlurper().parse(stubMapping) - return convertPlaceholders(json as Map, { String value -> - getGroupFromMatchingPattern(value) - }) - } - - private static Map convertPlaceholders(Map map, Closure closure) { - return map.collectEntries { - key, value -> - [key, transformValue(value, closure)] - } - } - - static def transformValue(def value, Closure closure) { - if (value instanceof String && value) { - try { - def json = new JsonSlurper().parseText(value) - if (json instanceof Map) { - return convertPlaceholders(json, closure) - } - } catch (JsonException ignore) { - return closure(value) - } - } else if (value instanceof Map) { - return convertPlaceholders(value as Map, closure) - } else if (value instanceof List) { - return value.collect({ transformValue(it, closure) }) - } - - return value - } - - private static Object getGroupFromMatchingPattern(String value) { - return value.matches(PLACEHOLDER_PATTERN) ? PLACEHOLDER_PATTERN.matcher(value)[0][SERVER_SIDE_GROUP] : value - } - -} 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 index c68a96a1e6..39f2b4762f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -110,4 +110,63 @@ class SpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("responseBody.property1 == \"a\"") blockBuilder.toString().contains("responseBody.property2.property3 == \"b\"") } + + def "should generate regex assertions for map objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: "a", + property2: value( + client(''), + server(regex('\\\\d{3}')) + ) + ) + headers { + header('Content-Type': 'application/json') + + } + + } + } + 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 ==~ java.util.regex.Pattern.compile('\\\\d{3}')") + } + + def "should generate regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( """{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + headers { + header('Content-Type': 'application/json') + + } + + } + } + 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + } + } From f84f11611b88c23f087b8fce1e7ad18adca0cae9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 May 2015 16:20:42 +0200 Subject: [PATCH 131/719] [#49] Surrounded with different quotes --- .../accurest/wiremock/WiremockToDslConverter.groovy | 4 ++-- .../io/codearte/accurest/dsl/internal/Body.groovy | 12 ++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy index 76570ee2b2..00d4d3786e 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 @@ -36,8 +36,8 @@ class WiremockToDslConverter { } """ : "" } - ${bodyPatterns?.equalTo?.every { it } ? "body('''${bodyPatterns.equalTo[0]}''')" : ''} - ${bodyPatterns?.equalToJson?.every { it } ? "body('''${bodyPatterns.equalToJson[0]}''')" : ''} + ${bodyPatterns?.equalTo?.every { it } ? "body(\"\"\"${bodyPatterns.equalTo[0]}\"\"\")" : ''} + ${bodyPatterns?.equalToJson?.every { it } ? "body(\"\"\"${bodyPatterns.equalToJson[0]}\"\"\")" : ''} ${bodyPatterns?.matches?.every { it } ? "body \$(client(regex('${escapeJava(bodyPatterns.matches[0])}')), server(''))" : ""} } response { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy index da602b5ebc..315135d939 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy @@ -42,6 +42,18 @@ class Body extends DslProperty { super(bodyAsValue.clientValue, bodyAsValue.serverValue) } + /** + * Due to the fact that we allow users to have a body with GString and different values inside + * we need to be prepared that they pass regexps around both on client and server side. + * + * In order to preserve the original JSON structure we need to convert the passed Regex patterns + * to a temporary string, then convert all to a legitimate JSON structure and then finally + * convert it back from string to a pattern. + * + * @param bodyAsValue - GString with passed values + * @param valueProvider - provider of values either for server or client side + * @return JSON structure with replaced client / server side parts + */ private static Object extractValue(GString bodyAsValue, Closure valueProvider) { GString gString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) Object[] values = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[] From 9b9bca31614afba8cf4c97c1a9340579e5292bfc Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 12 May 2015 23:14:28 +0200 Subject: [PATCH 132/719] Release version: 0.6.1 [ci skip] From f6721b0ca646ffed0beb7997d5f47390a49da6c1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 May 2015 23:36:43 +0200 Subject: [PATCH 133/719] Bundled Xeger together with the application --- .../main/groovy/nl/flotsam/xeger/Xeger.java | 114 ++++++++++++++++++ .../groovy/nl/flotsam/xeger/XegerTest.java | 64 ++++++++++ .../nl/flotsam/xeger/XegerUtilsTest.java | 39 ++++++ build.gradle | 6 +- 4 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java create mode 100644 accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java create mode 100644 accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java diff --git a/accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java b/accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java new file mode 100644 index 0000000000..8fd7d28628 --- /dev/null +++ b/accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java @@ -0,0 +1,114 @@ +/** + * Copyright 2009 Wilfred Springer + * Copyright 2012 Jason Pell + * Copyright 2013 Antonio García-Domínguez + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.flotsam.xeger; + +import dk.brics.automaton.Automaton; +import dk.brics.automaton.RegExp; +import dk.brics.automaton.State; +import dk.brics.automaton.Transition; + +import java.util.List; +import java.util.Random; + +/** + * An object that will generate text from a regular expression. In a way, it's the opposite of a regular expression + * matcher: an instance of this class will produce text that is guaranteed to match the regular expression passed in. + */ +public class Xeger { + + private final Automaton automaton; + private Random random; + + /** + * Constructs a new instance, accepting the regular expression and the randomizer. + * + * @param regex The regular expression. (Not null.) + * @param random The object that will randomize the way the String is generated. (Not null.) + * @throws IllegalArgumentException If the regular expression is invalid. + */ + public Xeger(String regex, Random random) { + assert regex != null; + assert random != null; + this.automaton = new RegExp(regex).toAutomaton(); + this.random = random; + } + + /** + * As {@link nl.flotsam.xeger.Xeger#Xeger(String, java.util.Random)}, creating a {@link java.util.Random} instance + * implicityly. + * + * @param regex as string + */ + public Xeger(String regex) { + this(regex, new Random()); + } + + /** + * Generates a random String that is guaranteed to match the regular expression passed to the constructor. + * @return generated regexp + */ + public String generate() { + StringBuilder builder = new StringBuilder(); + generate(builder, automaton.getInitialState()); + return builder.toString(); + } + + private void generate(StringBuilder builder, State state) { + List transitions = state.getSortedTransitions(false); + if (transitions.size() == 0) { + assert state.isAccept(); + return; + } + int nroptions = state.isAccept() ? transitions.size() : transitions.size() - 1; + int option = Xeger.getRandomInt(0, nroptions, random); + if (state.isAccept() && option == 0) { // 0 is considered stop + return; + } + // Moving on to next transition + Transition transition = transitions.get(option - (state.isAccept() ? 1 : 0)); + appendChoice(builder, transition); + generate(builder, transition.getDest()); + } + + private void appendChoice(StringBuilder builder, Transition transition) { + char c = (char) Xeger.getRandomInt(transition.getMin(), transition.getMax(), random); + builder.append(c); + } + + public Random getRandom() { + return random; + } + + public void setRandom(Random random) { + this.random = random; + } + + /** + * Generates a random number within the given bounds. + * + * @param min The minimum number (inclusive). + * @param max The maximum number (inclusive). + * @param random The object used as the randomizer. + * @return A random number in the given range. + */ + static int getRandomInt(int min, int max, Random random) { + // Use random.nextInt as it guarantees a uniform distribution + int maxForRandom=max-min+1; + return random.nextInt(maxForRandom) + min; + } +} \ No newline at end of file diff --git a/accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java b/accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java new file mode 100644 index 0000000000..f60e4bf5db --- /dev/null +++ b/accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java @@ -0,0 +1,64 @@ +/** + * Copyright 2009 Wilfred Springer + * Copyright 2012 Jason Pell + * Copyright 2013 Antonio García-Domínguez + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.flotsam.xeger; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class XegerTest { + + @Test + public void shouldGenerateTextCorrectly() { + String regex = "[ab]{4,6}c"; + Xeger generator = new Xeger(regex); + for (int i = 0; i < 100; i++) { + String text = generator.generate(); + assertTrue(text.matches(regex)); + } + } + + @Test + public void testRepeatableRegex() { + for (int x = 0; x < 1000; x++) { + Xeger generator = new Xeger("[ab]{4,6}c", new Random(1000)); + Xeger generator2 = new Xeger("[ab]{4,6}c", new Random(1000)); + + List firstRegexList = generateRegex(generator, 100); + List secondRegexList = generateRegex(generator2, 100); + + for (int i = 0; i < firstRegexList.size(); i++) { + assertEquals("Index mismatch: " + i, firstRegexList.get(i), + secondRegexList.get(i)); + } + } + } + + private List generateRegex(Xeger generator, int count) { + List regexList = new ArrayList(); + for (int i = 0; i < count; i++) { + regexList.add(generator.generate()); + } + return regexList; + } +} \ No newline at end of file diff --git a/accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java b/accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java new file mode 100644 index 0000000000..ccabfeb54d --- /dev/null +++ b/accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java @@ -0,0 +1,39 @@ +/** + * Copyright 2009 Wilfred Springer + * Copyright 2012 Jason Pell + * Copyright 2013 Antonio García-Domínguez + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package nl.flotsam.xeger; + +import org.hamcrest.Matchers; +import org.junit.Test; + +import java.util.Random; + +import static org.junit.Assert.assertThat; + +public class XegerUtilsTest { + + @Test + public void shouldGenerateRandomNumberCorrectly() { + Random random = new Random(); + for (int i = 0; i < 100; i++) { + int number = Xeger.getRandomInt(3, 7, random); + assertThat(number, Matchers.greaterThanOrEqualTo(3)); + assertThat(number, Matchers.lessThanOrEqualTo(7)); + } + } + +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 783681eebd..8ada1b5a2a 100644 --- a/build.gradle +++ b/build.gradle @@ -47,9 +47,6 @@ subprojects { repositories { mavenLocal() mavenCentral() - maven { - url "https://jitpack.io" - } } //Dependencies in all subprojects - http://solidsoft.wordpress.com/2014/11/13/gradle-tricks-display-dependencies-for-all-subprojects-in-multi-project-build/ @@ -101,8 +98,9 @@ project(':accurest-converters') { compile project(':accurest-core') compile 'org.apache.commons:commons-lang3:3.3.2' compile 'commons-io:commons-io:[2.4,)' - compile 'com.github.marcingrzejszczak:xeger:20130128' + compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger testCompile 'com.github.tomakehurst:wiremock:1.53' + testCompile 'org.hamcrest:hamcrest-all:1.3' } } From 1142b68123eac6346e7adf2f22f2539441281db6 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 May 2015 23:53:32 +0200 Subject: [PATCH 134/719] Added missing Javadoc entry about bundling reason --- .../src/main/groovy/nl/flotsam/xeger/Xeger.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java b/accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java index 8fd7d28628..9bd42a674a 100644 --- a/accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java +++ b/accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java @@ -14,6 +14,10 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * + * The class is bundled together with our code because it has not been + * released to any central repository. + * */ package nl.flotsam.xeger; From 3be6c8e889c4e509240b94edf05a7dc7eece76e5 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 13 May 2015 00:04:34 +0200 Subject: [PATCH 135/719] Release version: 0.6.2 [ci skip] From ad2c8b23e389754998207545fc7c9d610c8e1528 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 14 May 2015 00:35:00 +0200 Subject: [PATCH 136/719] WIP on the Wiremock stubs fix with bodyPattern matches --- .../dsl/WiremockRequestStubStrategy.groovy | 4 +- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 63 ++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 97a7e942ba..36ba00ed72 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -39,7 +39,9 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return [:] } if (containsRegex(body)) { - return [bodyPatterns: [[matches: parseBody(JsonConverter.transformValues(body, { it.toString() }))]]] + return [bodyPatterns: [[matches: parseBody(JsonConverter.transformValues(body, { + it instanceof Pattern ? it.toString() : it + }))]]] } return [bodyPatterns: [[equalTo: parseBody(body)]]] } 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 b813ee11ef..fddf781fd3 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 @@ -148,7 +148,6 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(wiremockStub) } - def 'should convert groovy dsl stub with regexp Body as String to wiremock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { @@ -201,6 +200,68 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(wiremockStub) } + def 'should convert groovy dsl stub with a regexp and an integer in request body'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "\\\\{\\"clientPesel\\":\\"[0-9]{10}\\",\\"loanAmount\\":123.123\\\\}" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\\"fraudCheckStatus\\":\\"OK\\",\\"rejectionReason\\":null}" + } +} +''') + and: + stubMappingIsValidWiremockStub(wiremockStub) + } + def "should generate stub with GET"() { given: From 6e6dda3994b9ddabb4b1c960dcc1c6f6b5c9d8eb Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 14 May 2015 16:58:05 +0200 Subject: [PATCH 137/719] Added tests, added additional checks (for regexps), added presentation examples --- .../dsl/WiremockRequestStubStrategy.groovy | 25 ++- .../internal/JsonStructureConverter.groovy | 32 ++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 2 +- .../codearte/accurest/dsl/WiremockSpec.groovy | 7 +- .../plugin/PresentationExampleSpec.groovy | 21 +++ .../presentationExample/build.gradle | 94 ++++++++++ .../shouldMarkClientAsFraud.groovy | 27 +++ .../shouldMarkClientAsNotFraud.groovy | 28 +++ .../frauddetection/Application.java | 17 ++ .../FraudDetectionController.java | 39 +++++ .../frauddetection/model/FraudCheck.java | 29 ++++ .../model/FraudCheckResult.java | 32 ++++ .../model/FraudCheckStatus.java | 5 + .../src/main/resources/application.yml | 1 + .../com/blogspot/toomuchcoding/MvcSpec.groovy | 15 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 50514 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .../presentationExample/gradlew | 164 ++++++++++++++++++ .../presentationExample/gradlew.bat | 90 ++++++++++ .../loanApplicationService/mappings/.gitkeep | 0 .../frauddetection/Application.java | 17 ++ .../LoanApplicationService.java | 62 +++++++ .../frauddetection/model/Client.java | 14 ++ .../model/FraudCheckStatus.java | 5 + .../model/FraudServiceRequest.java | 34 ++++ .../model/FraudServiceResponse.java | 27 +++ .../frauddetection/model/LoanApplication.java | 36 ++++ .../model/LoanApplicationResult.java | 32 ++++ .../model/LoanApplicationStatus.java | 5 + .../src/main/resources/application.yml | 1 + .../LoanApplicationServiceSpec.groovy | 50 ++++++ .../shouldMarkClientAsFraud.json | 23 +++ .../shouldMarkClientAsNotFraud.json | 23 +++ .../presentationExample/settings.gradle | 2 + build.gradle | 1 + 35 files changed, 960 insertions(+), 6 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy create mode 100755 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/PresentationExampleSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/build.gradle create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/resources/application.yml create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradle/wrapper/gradle-wrapper.jar create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradle/wrapper/gradle-wrapper.properties create mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew.bat create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/mappings/.gitkeep create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/resources/application.yml create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/settings.gradle diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 36ba00ed72..d6854255d9 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -3,10 +3,12 @@ import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientRequest import io.codearte.accurest.dsl.internal.Request -import io.codearte.accurest.util.JsonConverter import java.util.regex.Pattern +import static io.codearte.accurest.dsl.internal.JsonStructureConverter.TEMPORARY_PATTERN_HOLDER +import static io.codearte.accurest.dsl.internal.JsonStructureConverter.convertJsonStructureToObjectUnderstandingStructure + @TypeChecked @PackageScope class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { @@ -39,13 +41,28 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return [:] } if (containsRegex(body)) { - return [bodyPatterns: [[matches: parseBody(JsonConverter.transformValues(body, { - it instanceof Pattern ? it.toString() : it - }))]]] + return [bodyPatterns: [[matches: parseBody(convertJsonStructureToObjectUnderstandingStructure(body, + { it instanceof Pattern }, + { String json -> json.collect { + switch(it) { + case ('{'): return '\\{' + case ('}'): return '\\}' + default: return it + } + } .join('') + }, + { LinkedList list, String json -> + return json.replaceAll(TEMPORARY_PATTERN_HOLDER, { String a, String[] b -> list.pop() }) + } + ))]]] } return [bodyPatterns: [[equalTo: parseBody(body)]]] } + protected String parseBody(Object body) { + return body + } + boolean containsRegex(Object bodyObject) { String bodyString = bodyObject as String return (bodyString =~ /\^.*\$/).find() diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy new file mode 100644 index 0000000000..f5860bfaad --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy @@ -0,0 +1,32 @@ +package io.codearte.accurest.dsl.internal + +import groovy.json.JsonOutput +import groovy.transform.CompileStatic +import io.codearte.accurest.util.JsonConverter + +import java.util.regex.Pattern + +@CompileStatic +class JsonStructureConverter { + + public static final String TEMPORARY_PLACEHOLDER = '###PLACEHOLDER###' + public static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile(TEMPORARY_PLACEHOLDER) + + static Object convertJsonStructureToObjectUnderstandingStructure(Object parsedJson, + Closure retrievePlaceholders, + Closure performAdditionalLogicOnSerializedJson, + Closure convertSerializedJsonToSth) { + LinkedList queue = new LinkedList<>() + def transformedJson = JsonConverter.transformValues(parsedJson, { + if(retrievePlaceholders(it)) { + queue.push(it) + return TEMPORARY_PLACEHOLDER + } + return it + }) + String jsonAsString = JsonOutput.toJson(transformedJson) + String transformedJsonAsString = performAdditionalLogicOnSerializedJson(jsonAsString) + return convertSerializedJsonToSth(queue, transformedJsonAsString) + } + +} 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 fddf781fd3..f5b61625e3 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 @@ -183,7 +183,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { "urlPattern": "/[0-9]{2}", "bodyPatterns": [ { - "matches":"{\\"personalId\\":\\"^[0-9]{11}$\\"}" + "matches":"\\\\{\\"personalId\\":\\"^[0-9]{11}$\\"\\\\}" } ] }, diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy index 2a6237d89d..796e603c11 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy @@ -3,10 +3,15 @@ package io.codearte.accurest.dsl import com.github.tomakehurst.wiremock.stubbing.StubMapping import spock.lang.Specification +import java.util.regex.Pattern + class WiremockSpec extends Specification { void stubMappingIsValidWiremockStub(String mappingDefinition) { - StubMapping.buildFrom(mappingDefinition) + StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) + stubMapping.request.bodyPatterns.findAll { it.matches }.every { + Pattern.compile(it.matches) + } } } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/PresentationExampleSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/PresentationExampleSpec.groovy new file mode 100755 index 0000000000..3cc7845074 --- /dev/null +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/PresentationExampleSpec.groovy @@ -0,0 +1,21 @@ +package io.codearte.accurest.plugin + +import nebula.test.IntegrationSpec +import spock.lang.Stepwise + +@Stepwise +class PresentationExampleSpec extends IntegrationSpec { + + void setup() { + copyResources("functionalTest/presentationExample", "") + runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it + } + + def "should pass basic flow"() { + given: + assert fileExists('build.gradle') + expect: + runTasksSuccessfully('check') + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/build.gradle new file mode 100644 index 0000000000..9bf00d6c55 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/build.gradle @@ -0,0 +1,94 @@ +buildscript { + repositories { + mavenCentral() + mavenLocal() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE") + classpath 'io.codearte.accurest:accurest-gradle-plugin:0.6.2' + } +} + +ext { + spockVersion = '0.7-groovy-2.0' + restAssuredVersion = '2.4.0' + + accurestStubsBaseDirectory = 'src/test/resources/stubs' +} + +subprojects { + apply plugin: 'groovy' + + + repositories { + mavenCentral() + mavenLocal() + } + + dependencies { + testCompile "org.codehaus.groovy:groovy-all:2.3.7" + testCompile "org.spockframework:spock-core:$spockVersion" + testCompile("junit:junit:4.12") + testCompile('com.github.tomakehurst:wiremock:1.52') { + exclude group: 'org.mortbay.jetty', module: 'servlet-api' + } + } +} + +configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { + apply plugin: 'spring-boot' + apply plugin: 'accurest' + + ext { + wiremockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") + wiremockStubsOutputDir = new File(wiremockStubsOutputDirRoot, 'mappings/') + } + + accurest { + targetFramework = 'Spock' + testMode = 'MockMvc' + baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' + contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") + generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") + stubsOutputDir = wiremockStubsOutputDir + } + + jar { + version = '0.0.1' + } + + dependencies { + compile("org.springframework.boot:spring-boot-starter-web") { + exclude module: "spring-boot-starter-tomcat" + } + compile("org.springframework.boot:spring-boot-starter-jetty") + compile("org.springframework.boot:spring-boot-starter-actuator") + + testRuntime "org.spockframework:spock-spring:$spockVersion" + testCompile "org.springframework:spring-test" + testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" + testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" + } + + task cleanup(type: Delete) { + delete 'src/test/resources/mappings', 'src/test/resources/stubs' + } + + clean.dependsOn('cleanup') + +} + +configure(project(':fraudDetectionService')) { + test.dependsOn('generateWiremockClientStubs') +} + +configure(project(':loanApplicationService')) { + + task copyCollaboratorStubs(type: Copy) { + File fraudBuildDir = project(':fraudDetectionService').buildDir + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) + into "src/test/resources/" + } + + generateAccurest.dependsOn('copyCollaboratorStubs') +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy new file mode 100644 index 0000000000..a47dff32e4 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy @@ -0,0 +1,27 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy new file mode 100644 index 0000000000..fa8cd88ade --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy @@ -0,0 +1,28 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java new file mode 100644 index 0000000000..5a1a60244e --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -0,0 +1,17 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java new file mode 100644 index 0000000000..e264462cce --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java @@ -0,0 +1,39 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheck; +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckResult; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.math.BigDecimal; + +import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.FRAUD; +import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.OK; +import static org.springframework.web.bind.annotation.RequestMethod.PUT; + +@RestController +public class FraudDetectionController { + + private static final String FRAUD_SERVICE_JSON_VERSION_1 = "application/vnd.fraud.v1+json"; + private static final String NO_REASON = null; + private static final String AMOUNT_TOO_HIGH = "Amount too high"; + private static final BigDecimal MAX_AMOUNT = new BigDecimal("5000"); + + @RequestMapping( + value = "/fraudcheck", + method = PUT, + consumes = FRAUD_SERVICE_JSON_VERSION_1, + produces = FRAUD_SERVICE_JSON_VERSION_1) + public FraudCheckResult fraudCheck(@RequestBody FraudCheck fraudCheck) { + if (amountGreaterThanThreshold(fraudCheck)) { + return new FraudCheckResult(FRAUD, AMOUNT_TOO_HIGH); + } + return new FraudCheckResult(OK, NO_REASON); + } + + private boolean amountGreaterThanThreshold(FraudCheck fraudCheck) { + return MAX_AMOUNT.compareTo(fraudCheck.getLoanAmount()) < 0; + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java new file mode 100644 index 0000000000..77471aee19 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java @@ -0,0 +1,29 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class FraudCheck { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudCheck() { + } + + public String getClientPesel() { + return clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java new file mode 100644 index 0000000000..28efc573f5 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java @@ -0,0 +1,32 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class FraudCheckResult { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudCheckResult() { + } + + public FraudCheckResult(FraudCheckStatus fraudCheckStatus, String rejectionReason) { + this.fraudCheckStatus = fraudCheckStatus; + this.rejectionReason = rejectionReason; + } + + public FraudCheckStatus getFraudCheckStatus() { + return fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b87c365d51 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/resources/application.yml b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/resources/application.yml new file mode 100644 index 0000000000..a30a91f034 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/resources/application.yml @@ -0,0 +1 @@ +server.port=8085 \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy new file mode 100644 index 0000000000..bcb6ef1579 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy @@ -0,0 +1,15 @@ +package com.blogspot.toomuchcoding + +import com.blogspot.toomuchcoding.frauddetection.FraudDetectionController +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import spock.lang.Specification + +class MvcSpec extends Specification { + def setup() { + RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) + } + + void assertThatRejectionReasonIsNull(def rejectionReason) { + assert !rejectionReason + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradle/wrapper/gradle-wrapper.jar b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..667288ad6c2b3b87c990ece1267e56f0bcbf3622 GIT binary patch literal 50514 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +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"` + + # 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 "$@" diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew.bat b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew.bat new file mode 100644 index 0000000000..8a0b282aa6 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew.bat @@ -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 Windowz 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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/mappings/.gitkeep b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/mappings/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java new file mode 100644 index 0000000000..5a1a60244e --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -0,0 +1,17 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java new file mode 100644 index 0000000000..82476a3a46 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java @@ -0,0 +1,62 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus; +import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceRequest; +import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceResponse; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class LoanApplicationService { + + private static final String FRAUD_SERVICE_JSON_VERSION_1 = + "application/vnd.fraud.v1+json"; + + private final RestTemplate restTemplate; + + public LoanApplicationService() { + this.restTemplate = new RestTemplate(); + } + + public LoanApplicationResult loanApplication(LoanApplication loanApplication) { + FraudServiceRequest request = + new FraudServiceRequest(loanApplication); + + FraudServiceResponse response = + sendRequestToFraudDetectionService(request); + + return buildResponseFromFraudResult(response); + } + + private FraudServiceResponse sendRequestToFraudDetectionService( + FraudServiceRequest request) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1); + + ResponseEntity response = + restTemplate.exchange("http://localhost:8080/fraudcheck", HttpMethod.PUT, + new HttpEntity<>(request, httpHeaders), + FraudServiceResponse.class); + + return response.getBody(); + } + + private LoanApplicationResult buildResponseFromFraudResult(FraudServiceResponse response) { + LoanApplicationStatus applicationStatus = null; + if (FraudCheckStatus.OK == response.getFraudCheckStatus()) { + applicationStatus = LoanApplicationStatus.LOAN_APPLIED; + } else if (FraudCheckStatus.FRAUD == response.getFraudCheckStatus()) { + applicationStatus = LoanApplicationStatus.LOAN_APPLICATION_REJECTED; + } + + return new LoanApplicationResult(applicationStatus, response.getRejectionReason()); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java new file mode 100644 index 0000000000..5e91273eda --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java @@ -0,0 +1,14 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class Client { + + private String pesel; + + public String getPesel() { + return pesel; + } + + public void setPesel(String pesel) { + this.pesel = pesel; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b87c365d51 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java new file mode 100644 index 0000000000..ac595998bc --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java @@ -0,0 +1,34 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class FraudServiceRequest { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudServiceRequest() { + } + + public FraudServiceRequest(LoanApplication loanApplication) { + this.clientPesel = loanApplication.getClient().getPesel(); + this.loanAmount = loanApplication.getAmount(); + } + + public String getClientPesel() { + return clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java new file mode 100644 index 0000000000..9f3353ecbf --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java @@ -0,0 +1,27 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class FraudServiceResponse { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudServiceResponse() { + } + + public FraudCheckStatus getFraudCheckStatus() { + return fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java new file mode 100644 index 0000000000..816087988b --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java @@ -0,0 +1,36 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class LoanApplication { + + private Client client; + + private BigDecimal amount; + + private String loanApplicationId; + + public Client getClient() { + return client; + } + + public void setClient(Client client) { + this.client = client; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + public String getLoanApplicationId() { + return loanApplicationId; + } + + public void setLoanApplicationId(String loanApplicationId) { + this.loanApplicationId = loanApplicationId; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java new file mode 100644 index 0000000000..523f4f2ea3 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java @@ -0,0 +1,32 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class LoanApplicationResult { + + private LoanApplicationStatus loanApplicationStatus; + + private String rejectionReason; + + public LoanApplicationResult() { + } + + public LoanApplicationResult(LoanApplicationStatus loanApplicationStatus, String rejectionReason) { + this.loanApplicationStatus = loanApplicationStatus; + this.rejectionReason = rejectionReason; + } + + public LoanApplicationStatus getLoanApplicationStatus() { + return loanApplicationStatus; + } + + public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) { + this.loanApplicationStatus = loanApplicationStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java new file mode 100644 index 0000000000..7f7f86e0ea --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum LoanApplicationStatus { + LOAN_APPLIED, LOAN_APPLICATION_REJECTED +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/resources/application.yml b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/resources/application.yml new file mode 100644 index 0000000000..e86bbd0e0f --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/resources/application.yml @@ -0,0 +1 @@ +server.port=8090 \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy new file mode 100644 index 0000000000..58d17673ce --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy @@ -0,0 +1,50 @@ +package com.blogspot.toomuchcoding + +import com.blogspot.toomuchcoding.frauddetection.Application +import com.blogspot.toomuchcoding.frauddetection.LoanApplicationService +import com.blogspot.toomuchcoding.frauddetection.model.Client +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus +import com.github.tomakehurst.wiremock.junit.WireMockClassRule +import org.junit.ClassRule +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.test.context.ContextConfiguration +import spock.lang.Shared +import spock.lang.Specification + +@ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) +class LoanApplicationServiceSpec extends Specification { + + @ClassRule + @Shared + WireMockClassRule wireMockRule = new WireMockClassRule() + + @Autowired + LoanApplicationService sut + + def 'should successfully apply for loan'() { + given: + LoanApplication application = + new LoanApplication(client: new Client(pesel: '1234567890'), amount: 123.123) + when: + LoanApplicationResult loanApplication = sut.loanApplication(application) + then: + loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED + loanApplication.rejectionReason == null + } + + def 'should be rejected due to abnormal loan amount'() { + given: + LoanApplication application = + new LoanApplication(client: new Client(pesel: '1234567890'), amount: 99_999) + when: + LoanApplicationResult loanApplication = sut.loanApplication(application) + then: + loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLICATION_REJECTED + loanApplication.rejectionReason == 'Amount too high' + } + + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json new file mode 100644 index 0000000000..610b4ae1b1 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"99999\"}" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json new file mode 100644 index 0000000000..af5792092c --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"123.123\"}" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/settings.gradle new file mode 100644 index 0000000000..6a42a6c7ce --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/settings.gradle @@ -0,0 +1,2 @@ +include ':fraudDetectionService' +include ':loanApplicationService' diff --git a/build.gradle b/build.gradle index 783681eebd..dc8fb0a86a 100644 --- a/build.gradle +++ b/build.gradle @@ -90,6 +90,7 @@ project(':accurest-core') { compile 'org.slf4j:slf4j-api:[1.6.0,)' compile 'org.codehaus.plexus:plexus-utils:3.0.21' compile 'commons-io:commons-io:2.4' + compile 'org.apache.commons:commons-lang3:3.4' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile 'com.github.tomakehurst:wiremock:1.53' From 74dc41384ee00eadd0d40445d63824c704b486a4 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 15 May 2015 16:06:47 +0200 Subject: [PATCH 138/719] Changed test project name --- ...nExampleSpec.groovy => SampleProjectSpec.groovy} | 4 ++-- .../build.gradle | 0 .../shouldMarkClientAsFraud.groovy | 0 .../shouldMarkClientAsNotFraud.groovy | 0 .../toomuchcoding/frauddetection/Application.java | 0 .../frauddetection/FraudDetectionController.java | 0 .../frauddetection/model/FraudCheck.java | 0 .../frauddetection/model/FraudCheckResult.java | 0 .../frauddetection/model/FraudCheckStatus.java | 0 .../src/main/resources/application.yml | 0 .../com/blogspot/toomuchcoding/MvcSpec.groovy | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../{presentationExample => sampleProject}/gradlew | 0 .../gradlew.bat | 0 .../loanApplicationService/mappings/.gitkeep | 0 .../toomuchcoding/frauddetection/Application.java | 0 .../frauddetection/LoanApplicationService.java | 0 .../toomuchcoding/frauddetection/model/Client.java | 0 .../frauddetection/model/FraudCheckStatus.java | 0 .../frauddetection/model/FraudServiceRequest.java | 0 .../frauddetection/model/FraudServiceResponse.java | 0 .../frauddetection/model/LoanApplication.java | 0 .../frauddetection/model/LoanApplicationResult.java | 0 .../frauddetection/model/LoanApplicationStatus.java | 0 .../src/main/resources/application.yml | 0 .../toomuchcoding/LoanApplicationServiceSpec.groovy | 0 .../shouldMarkClientAsFraud.json | 0 .../shouldMarkClientAsNotFraud.json | 0 .../settings.gradle | 0 30 files changed, 2 insertions(+), 2 deletions(-) rename accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/{PresentationExampleSpec.groovy => SampleProjectSpec.groovy} (76%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/build.gradle (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/src/main/resources/application.yml (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/gradle/wrapper/gradle-wrapper.jar (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/gradle/wrapper/gradle-wrapper.properties (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/gradlew (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/gradlew.bat (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/mappings/.gitkeep (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/main/resources/application.yml (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json (100%) rename accurest-gradle-plugin/src/test/resources/functionalTest/{presentationExample => sampleProject}/settings.gradle (100%) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/PresentationExampleSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy similarity index 76% rename from accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/PresentationExampleSpec.groovy rename to accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index 3cc7845074..e32b8810f4 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/PresentationExampleSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -4,10 +4,10 @@ import nebula.test.IntegrationSpec import spock.lang.Stepwise @Stepwise -class PresentationExampleSpec extends IntegrationSpec { +class SampleProjectSpec extends IntegrationSpec { void setup() { - copyResources("functionalTest/presentationExample", "") + copyResources("functionalTest/sampleProject", "") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/build.gradle rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/resources/application.yml b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/main/resources/application.yml rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradle/wrapper/gradle-wrapper.jar b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradle/wrapper/gradle-wrapper.jar rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradle/wrapper/gradle-wrapper.properties rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew.bat b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/gradlew.bat rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/mappings/.gitkeep b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/mappings/.gitkeep rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/resources/application.yml b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/main/resources/application.yml rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/presentationExample/settings.gradle rename to accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle From 7bd9e48f153aa2130c091978485ab69825528886 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 16 May 2015 12:44:23 +0200 Subject: [PATCH 139/719] Ranging dependencies versions --- build.gradle | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index 57f2a9270a..d44130214f 100644 --- a/build.gradle +++ b/build.gradle @@ -55,7 +55,7 @@ subprojects { dependencies { compile localGroovy() - testCompile('org.spockframework:spock-core:0.7-groovy-2.0') { + testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { exclude(group: 'org.codehaus.groovy') } } @@ -85,9 +85,9 @@ subprojects { project(':accurest-core') { dependencies { compile 'org.slf4j:slf4j-api:[1.6.0,)' - compile 'org.codehaus.plexus:plexus-utils:3.0.21' - compile 'commons-io:commons-io:2.4' - compile 'org.apache.commons:commons-lang3:3.4' + compile 'org.codehaus.plexus:plexus-utils:[3.0.0,)' + compile 'commons-io:commons-io:[2.0,)' + compile 'org.apache.commons:commons-lang3:[3.0,)' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile 'com.github.tomakehurst:wiremock:1.53' @@ -97,8 +97,8 @@ project(':accurest-core') { project(':accurest-converters') { dependencies { compile project(':accurest-core') - compile 'org.apache.commons:commons-lang3:3.3.2' - compile 'commons-io:commons-io:[2.4,)' + compile 'org.apache.commons:commons-lang3:[3.0,)' + compile 'commons-io:commons-io:[2.0,)' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger testCompile 'com.github.tomakehurst:wiremock:1.53' testCompile 'org.hamcrest:hamcrest-all:1.3' @@ -111,7 +111,7 @@ project(':accurest-gradle-plugin') { compile project(':accurest-converters') compile gradleApi() - testCompile('com.netflix.nebula:nebula-test:2.2.0') { + testCompile('com.netflix.nebula:nebula-test:2.2.1') { exclude(group: 'org.spockframework') } } From f5605d75131966f782920dae40850f8dfb18c1bf Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 16 May 2015 12:45:34 +0200 Subject: [PATCH 140/719] Release version: 0.6.3 [ci skip] From 078ba57f23ce8a2a9f1a76fc2708e29ab7ea7fc2 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 16 May 2015 12:58:45 +0200 Subject: [PATCH 141/719] Update to Gradle 2.4 --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index d44130214f..8000423e6c 100644 --- a/build.gradle +++ b/build.gradle @@ -131,5 +131,5 @@ project(':accurest-gradle-plugin') { } task wrapper(type: Wrapper) { - gradleVersion = '2.2.1' + gradleVersion = '2.4' } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index a0889f9ef7..8c1b9c3b9f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Jan 25 20:45:35 CET 2015 +#Sat May 16 12:50:16 CEST 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-bin.zip From 194d4a034a36871a69b3bb8e3c66386e4682c6a5 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Fri, 5 Jun 2015 12:49:55 +0200 Subject: [PATCH 142/719] Implemented queryParameters matching for urlPattern and urlPath --- .../dsl/WiremockRequestStubStrategy.groovy | 44 ++++++- .../dsl/internal/MatchingStrategy.groovy | 34 +++++ .../dsl/internal/QueryParameter.groovy | 29 +++++ .../dsl/internal/QueryParameters.groovy | 45 +++++++ .../accurest/dsl/internal/Request.groovy | 36 +++++- .../codearte/accurest/dsl/internal/Url.groovy | 20 ++- .../accurest/dsl/internal/UrlPath.groovy | 20 +++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 118 ++++++++++++++++++ 8 files changed, 337 insertions(+), 9 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index d6854255d9..aa0b0f6bbc 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -2,6 +2,9 @@ package io.codearte.accurest.dsl import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientRequest +import io.codearte.accurest.dsl.internal.MatchingStrategy +import io.codearte.accurest.dsl.internal.QueryParameter +import io.codearte.accurest.dsl.internal.QueryParameters import io.codearte.accurest.dsl.internal.Request import java.util.regex.Pattern @@ -27,12 +30,47 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map buildRequestContent(ClientRequest request) { return ([method : request?.method?.clientValue, headers : buildClientRequestHeadersSection(request.headers) - ] << appendUrl(request) << appendBody(request)).findAll { it.value } + ] << appendUrl(request) << appendQueryParameters(request) << appendBody(request)).findAll { it.value } } private Map appendUrl(ClientRequest clientRequest) { - Object url = clientRequest?.url?.clientValue - return url instanceof Pattern ? [urlPattern: ((Pattern)url).pattern()] : [url: url] + def urlPath = clientRequest?.urlPath?.clientValue + if (urlPath) { + return [urlPath: urlPath] + } + def url = clientRequest?.url?.clientValue + return url instanceof Pattern ? [urlPattern: url.pattern()] : [url: url] + } + + private Map appendQueryParameters(ClientRequest clientRequest) { + def queryParameters = clientRequest?.urlPath?.queryParameters ?: clientRequest?.url?.queryParameters + return queryParameters && !queryParameters.parameters.isEmpty() ? + [queryParameters: buildUrlPathQueryParameters(queryParameters)] : [:] + } + + private Map buildUrlPathQueryParameters(QueryParameters queryParameters) { + return queryParameters.parameters.collectEntries { QueryParameter param -> + parseQueryParameter(param.name, param.clientValue) + } + } + + protected Map parseQueryParameter(String name, MatchingStrategy matchingStrategy) { + return buildQueryParameter(name, matchingStrategy.clientValue, matchingStrategy.type) + } + + protected Map parseQueryParameter(String name, Object value) { + return buildQueryParameter(name, value, MatchingStrategy.Type.EQUAL_TO) + } + + protected Map parseQueryParameter(String name, Pattern pattern) { + return buildQueryParameter(name, pattern.pattern(), MatchingStrategy.Type.MATCHING) + } + + private Map buildQueryParameter(String name, Object value, MatchingStrategy.Type type) { + if (value instanceof Pattern) { + value = value.pattern() + } + return [(name): [(type.name) : value]] } private Map appendBody(ClientRequest clientRequest) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy new file mode 100644 index 0000000000..2be3567482 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy @@ -0,0 +1,34 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString; + +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@CompileStatic +public class MatchingStrategy extends DslProperty { + + Type type + + MatchingStrategy(Object value, Type type) { + super(value) + this.type = type + } + + MatchingStrategy(DslProperty value, Type type) { + super(value.clientValue, value.serverValue) + this.type = type + } + + enum Type { + EQUAL_TO("equalTo"), CONTAINS("contains"), MATCHING("matches"), NOT_MATCHING("doesNotMatch") + + final String name + + Type(name) { + this.name = name + } + } + +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy new file mode 100644 index 0000000000..2e5a606c29 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy @@ -0,0 +1,29 @@ +package io.codearte.accurest.dsl.internal; + +import groovy.transform.CompileStatic; +import groovy.transform.EqualsAndHashCode; +import groovy.transform.ToString; + +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@CompileStatic +public class QueryParameter extends DslProperty { + + String name + + QueryParameter(String name, DslProperty dslProperty) { + super(dslProperty.clientValue, dslProperty.serverValue) + this.name = name + } + + QueryParameter(String name, MatchingStrategy matchingStrategy) { + super(matchingStrategy) + this.name = name + } + + QueryParameter(String name, Object value) { + super(value) + this.name = name + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy new file mode 100644 index 0000000000..c233681652 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy @@ -0,0 +1,45 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString +import groovy.transform.TypeChecked + +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@TypeChecked +public class QueryParameters { + + List parameters = [] + + public void parameter(Map singleParameter) { + Map.Entry first = singleParameter.entrySet().first() + parameters << new QueryParameter(first?.key, first?.value) + } + + public void parameter(String parameterName, Object parameterValue) { + parameters << new QueryParameter(parameterName, parameterValue) + } + + def equalTo(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO) + } + + def containing(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.CONTAINS) + } + + def matching(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.MATCHING) + } + + def notMatching(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.NOT_MATCHING) + } + + void collect(Closure closure) { + parameters?.each { + parameter -> closure(parameter) + } + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 50bd42910c..dab8f873f2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -11,6 +11,7 @@ class Request extends Common { DslProperty method Url url + UrlPath urlPath Headers headers Body body @@ -20,6 +21,7 @@ class Request extends Common { Request(Request request) { this.method = request.method this.url = request.url + this.urlPath = request.urlPath this.headers = request.headers this.body = request.body } @@ -32,7 +34,7 @@ class Request extends Common { this.method = toDslProperty(method) } - void url(String url) { + void url(Object url) { this.url = new Url(url) } @@ -40,6 +42,38 @@ class Request extends Common { this.url = new Url(url) } + void url(Object url, @DelegatesTo(UrlPath) Closure closure) { + this.url = new Url(url) + closure.delegate = this.url + closure() + } + + void url(DslProperty url, @DelegatesTo(UrlPath) Closure closure) { + this.url = new Url(url) + closure.delegate = this.url + closure() + } + + void urlPath(String path) { + this.urlPath = new UrlPath(path) + } + + void urlPath(DslProperty path) { + this.urlPath = new UrlPath(path) + } + + void urlPath(String path, @DelegatesTo(UrlPath) Closure closure) { + this.urlPath = new UrlPath(path) + closure.delegate = urlPath + closure() + } + + void urlPath(DslProperty path, @DelegatesTo(UrlPath) Closure closure) { + this.urlPath = new UrlPath(path) + closure.delegate = urlPath + closure() + } + void headers(@DelegatesTo(Headers) Closure closure) { this.headers = new Headers() closure.delegate = headers diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy index da91b4a248..42a26eb26c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy @@ -1,18 +1,28 @@ package io.codearte.accurest.dsl.internal +import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) +@CompileStatic class Url extends DslProperty { - Url(DslProperty bodyAsValue) { - super(bodyAsValue.clientValue, bodyAsValue.serverValue) + QueryParameters queryParameters + + Url(DslProperty prop) { + super(prop.clientValue, prop.serverValue) } - Url(String bodyAsValue) { - super(bodyAsValue) + Url(Object url) { + super(url) } - + + void queryParameters(@DelegatesTo(QueryParameters) Closure closure) { + this.queryParameters = new QueryParameters() + closure.delegate = queryParameters + closure() + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy new file mode 100644 index 0000000000..ee1d3eed98 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy @@ -0,0 +1,20 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic; +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString; + +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +@CompileStatic +class UrlPath extends Url { + + UrlPath(String path) { + super(path) + } + + UrlPath(DslProperty path) { + super(path) + } + +} 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 f5b61625e3..ba6211223d 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,4 +1,6 @@ package io.codearte.accurest.dsl + +import groovy.json.JsonBuilder import groovy.json.JsonSlurper class WiremockGroovyDslSpec extends WiremockSpec { @@ -313,6 +315,110 @@ class WiremockGroovyDslSpec extends WiremockSpec { ''') } + def "should generate request with urlPath and queryParameters for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPath($(client("users"), server("items"))) { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(containing("10"))) + parameter 'offset': containing("10") + parameter 'filter': "email" + parameter 'sort': ~/^[0-9]{10}$/ + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server(containing("10"))) + parameter 'age': notMatching("^\\w*\$") + parameter 'name': matching("Denis.*") + } + } + } + response { + status 200 + } + } + when: + def json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "urlPath":"users", + "queryParameters": { + "offset": { + "contains": "10" + }, + "limit": { + "equalTo": "20" + }, + "filter": { + "equalTo": "email" + }, + "sort": { + "matches": "^[0-9]{10}$" + }, + "search": { + "doesNotMatch": "^/[0-9]{2}$" + }, + "age": { + "doesNotMatch": "^\\\\w*$" + }, + "name": { + "matches": "Denis.*" + } + } + }, + "response": { + "status": 200, + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def "should generate request with url and queryParameters for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url(regex(/users\/[0-9]*/)) { + queryParameters { + parameter 'age': notMatching("^\\w*\$") + parameter 'name': matching("Denis.*") + } + } + } + response { + status 200 + } + } + when: + def json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "urlPattern": "users/[0-9]*", + "queryParameters": { + "age": { + "doesNotMatch": "^\\\\w*$" + }, + "name": { + "matches": "Denis.*" + } + } + }, + "response": { + "status": 200, + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + def "should generate stub with some headers section for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make { @@ -347,4 +453,16 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') } + + def toJsonString(value) { + new JsonBuilder(value).toPrettyString() + } + + def parseJson(json) { + new JsonSlurper().parseText(json) + } + + def toWiremockClientJsonStub(groovyDsl) { + new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + } } From 1eb035189e3915e1ba9c84be58e3213584884a62 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Fri, 5 Jun 2015 12:56:58 +0200 Subject: [PATCH 143/719] Add more tests --- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 60 ++++++++++++++++++- 1 file changed, 59 insertions(+), 1 deletion(-) 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 ba6211223d..6e3843e146 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 @@ -343,7 +343,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { { "request": { "method": "GET", - "urlPath":"users", + "urlPath": "users", "queryParameters": { "offset": { "contains": "10" @@ -377,6 +377,64 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(json) } + def "should generate request with urlPath for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPath $(client("boxes"), server("items")) + } + response { + status 200 + } + } + when: + def json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "urlPath": "boxes" + }, + "response": { + "status": 200, + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def "should generate simple request with urlPath for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPath "boxes" + } + response { + status 200 + } + } + when: + def json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "urlPath": "boxes" + }, + "response": { + "status": 200, + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + def "should generate request with url and queryParameters for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make { From cd226a009dec20f7d630ce4e4307bb385c50a29b Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Mon, 8 Jun 2015 13:29:21 +0200 Subject: [PATCH 144/719] PR code review comments --- .../dsl/WiremockRequestStubStrategy.groovy | 23 ++++++++++--------- .../dsl/internal/MatchingStrategy.groovy | 2 +- .../dsl/internal/QueryParameter.groovy | 2 +- .../dsl/internal/QueryParameters.groovy | 20 ++++++---------- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 6 ++--- 5 files changed, 24 insertions(+), 29 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index aa0b0f6bbc..298cc1b2ec 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -34,42 +34,43 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { } private Map appendUrl(ClientRequest clientRequest) { - def urlPath = clientRequest?.urlPath?.clientValue + Object urlPath = clientRequest?.urlPath?.clientValue if (urlPath) { return [urlPath: urlPath] } - def url = clientRequest?.url?.clientValue + Object url = clientRequest?.url?.clientValue return url instanceof Pattern ? [urlPattern: url.pattern()] : [url: url] } private Map appendQueryParameters(ClientRequest clientRequest) { - def queryParameters = clientRequest?.urlPath?.queryParameters ?: clientRequest?.url?.queryParameters + QueryParameters queryParameters = clientRequest?.urlPath?.queryParameters ?: clientRequest?.url?.queryParameters return queryParameters && !queryParameters.parameters.isEmpty() ? [queryParameters: buildUrlPathQueryParameters(queryParameters)] : [:] } - private Map buildUrlPathQueryParameters(QueryParameters queryParameters) { + private Map buildUrlPathQueryParameters(QueryParameters queryParameters) { return queryParameters.parameters.collectEntries { QueryParameter param -> parseQueryParameter(param.name, param.clientValue) } } - protected Map parseQueryParameter(String name, MatchingStrategy matchingStrategy) { + protected Map parseQueryParameter(String name, MatchingStrategy matchingStrategy) { return buildQueryParameter(name, matchingStrategy.clientValue, matchingStrategy.type) } - protected Map parseQueryParameter(String name, Object value) { + protected Map parseQueryParameter(String name, Object value) { return buildQueryParameter(name, value, MatchingStrategy.Type.EQUAL_TO) } - protected Map parseQueryParameter(String name, Pattern pattern) { + protected Map parseQueryParameter(String name, Pattern pattern) { return buildQueryParameter(name, pattern.pattern(), MatchingStrategy.Type.MATCHING) } - private Map buildQueryParameter(String name, Object value, MatchingStrategy.Type type) { - if (value instanceof Pattern) { - value = value.pattern() - } + private Map buildQueryParameter(String name, Pattern pattern, MatchingStrategy.Type type) { + return buildQueryParameter(name, pattern.pattern(), type) + } + + private Map buildQueryParameter(String name, Object value, MatchingStrategy.Type type) { return [(name): [(type.name) : value]] } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy index 2be3567482..c385bb1939 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy @@ -7,7 +7,7 @@ import groovy.transform.ToString; @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) @CompileStatic -public class MatchingStrategy extends DslProperty { +class MatchingStrategy extends DslProperty { Type type diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy index 2e5a606c29..78d8e34009 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy @@ -7,7 +7,7 @@ import groovy.transform.ToString; @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) @CompileStatic -public class QueryParameter extends DslProperty { +class QueryParameter extends DslProperty { String name diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy index c233681652..eedaf5654b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy @@ -7,39 +7,33 @@ import groovy.transform.TypeChecked @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) @TypeChecked -public class QueryParameters { +class QueryParameters { List parameters = [] - public void parameter(Map singleParameter) { + void parameter(Map singleParameter) { Map.Entry first = singleParameter.entrySet().first() parameters << new QueryParameter(first?.key, first?.value) } - public void parameter(String parameterName, Object parameterValue) { + void parameter(String parameterName, Object parameterValue) { parameters << new QueryParameter(parameterName, parameterValue) } - def equalTo(Object value) { + MatchingStrategy equalTo(Object value) { return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO) } - def containing(Object value) { + MatchingStrategy containing(Object value) { return new MatchingStrategy(value, MatchingStrategy.Type.CONTAINS) } - def matching(Object value) { + MatchingStrategy matching(Object value) { return new MatchingStrategy(value, MatchingStrategy.Type.MATCHING) } - def notMatching(Object value) { + MatchingStrategy notMatching(Object value) { return new MatchingStrategy(value, MatchingStrategy.Type.NOT_MATCHING) } - void collect(Closure closure) { - parameters?.each { - parameter -> closure(parameter) - } - } - } 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 6e3843e146..de857e0efc 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 @@ -512,15 +512,15 @@ class WiremockGroovyDslSpec extends WiremockSpec { ''') } - def toJsonString(value) { + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } - def parseJson(json) { + Object parseJson(json) { new JsonSlurper().parseText(json) } - def toWiremockClientJsonStub(groovyDsl) { + String toWiremockClientJsonStub(groovyDsl) { new WiremockStubStrategy(groovyDsl).toWiremockClientStub() } } From 2420ea7ad713fe3c7f92b85a4503888352824fb6 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Tue, 9 Jun 2015 13:20:00 +0200 Subject: [PATCH 145/719] Spock generation for url path --- .../builder/SpockMethodBodyBuilder.groovy | 116 ++++++++++++------ .../builder/SpockMethodBuilderSpec.groovy | 38 ++++++ 2 files changed, 116 insertions(+), 38 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 532e429952..41734b0a3a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -5,6 +5,11 @@ import groovy.transform.PackageScope 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.MatchingStrategy +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.UrlPath import java.util.regex.Pattern @@ -20,46 +25,81 @@ class SpockMethodBodyBuilder { } void appendTo(BlockBuilder blockBuilder) { - blockBuilder.startBlock() - blockBuilder.addLine('given:').startBlock() - blockBuilder.addLine('def request = given()') - blockBuilder.indent() - stubDefinition.request.headers?.collect { Header header -> - blockBuilder.addLine(".header('${header.name}', '${header.serverValue}')") - } - if (stubDefinition.request.body) { - String matches = new JsonOutput().toJson(stubDefinition.request.body.serverValue) - blockBuilder.addLine(".body('$matches')") - } - - blockBuilder.unindent().endBlock().addEmptyLine() - - blockBuilder.addLine('when:').startBlock() - blockBuilder.addLine('def response = given().spec(request)') - blockBuilder.indent() - blockBuilder.addLine(".${stubDefinition.request.method.serverValue.toLowerCase()}(\"$stubDefinition.request.url.serverValue\")") - blockBuilder.unindent().endBlock().addEmptyLine() - - blockBuilder.addLine('then:').startBlock() - blockBuilder.addLine("response.statusCode == $stubDefinition.response.status.serverValue") - - stubDefinition.response.headers?.collect { Header header -> - blockBuilder.addLine("response.header('$header.name') == '$header.serverValue'") - } - if (stubDefinition.response.body) { - blockBuilder.endBlock() - blockBuilder.addLine('and:').startBlock() - blockBuilder.addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') - def responseBody = stubDefinition.response.body.serverValue - if (responseBody instanceof List) { - processArrayElements(responseBody, "", blockBuilder) - } else { - processMapElement(responseBody, blockBuilder, "") + Request request = stubDefinition.request + Response response = stubDefinition.response + blockBuilder.with { + startBlock() + addLine('given:').startBlock() + addLine('def request = given()') + indent() + request.headers?.collect { Header header -> + addLine(".header('${header.name}', '${header.serverValue}')") + } + if (request.body) { + String matches = new JsonOutput().toJson(request.body.serverValue) + addLine(".body('$matches')") } - } - blockBuilder.endBlock() - blockBuilder.endBlock() + unindent().endBlock().addEmptyLine() + + addLine('when:').startBlock() + addLine('def response = given().spec(request)') + indent() + + String url = buildUrl(request) + String method = request.method.serverValue.toLowerCase() + + blockBuilder.addLine(/.${method}("$url")/) + unindent().endBlock().addEmptyLine() + + addLine('then:').startBlock() + addLine("response.statusCode == $response.status.serverValue") + + response.headers?.collect { Header header -> + addLine("response.header('$header.name') == '$header.serverValue'") + } + if (response.body) { + endBlock() + addLine('and:').startBlock() + addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') + def responseBody = response.body.serverValue + if (responseBody instanceof List) { + processArrayElements(responseBody, "", blockBuilder) + } else { + processMapElement(responseBody, blockBuilder, "") + } + } + endBlock() + + endBlock() + } + } + + private String buildUrl(Request request) { + if (request.url) + return request.url.serverValue; + if (request.urlPath) + return buildUrlFromUrlPath(request.urlPath) + throw new IllegalStateException("URL is not set!") + } + + private String buildUrlFromUrlPath(UrlPath urlPath) { + String params = urlPath.queryParameters.parameters.inject([]) { result, param -> + result << "${param.name}=${URLEncoder.encode(resolveParamValue(param).toString(), "UTF8")}" + }.join('&') + return "$urlPath.serverValue?$params" + } + + private String resolveParamValue(QueryParameter param) { + resolveParamValue(param.serverValue) + } + + private String resolveParamValue(Object value) { + value.toString() + } + + private String resolveParamValue(MatchingStrategy matchingStrategy) { + matchingStrategy.serverValue.toString() } private void processBodyElement(BlockBuilder blockBuilder, String rootProperty, def element) { 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 index 0bde0a9ea3..ce1d00fa71 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -169,4 +169,42 @@ class SpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") } + def "should generate a call with an url path and query parameters"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov")') + spockTest.contains('responseBody.property1 == "a"') + spockTest.contains('responseBody.property2 == "b"') + } + } From c0580dfe7a8db3facb73a71474575dd6e638075c Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Tue, 9 Jun 2015 17:40:04 +0200 Subject: [PATCH 146/719] Add server values validation --- .../dsl/internal/QueryParameter.groovy | 7 +- .../codearte/accurest/dsl/internal/Url.groovy | 4 + .../accurest/util/ValidateUtils.groovy | 39 +++++++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 80 ++++++++++++++++--- 4 files changed, 120 insertions(+), 10 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy index 78d8e34009..042da081f2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy @@ -2,7 +2,9 @@ package io.codearte.accurest.dsl.internal; import groovy.transform.CompileStatic; import groovy.transform.EqualsAndHashCode; -import groovy.transform.ToString; +import groovy.transform.ToString + +import static io.codearte.accurest.util.ValidateUtils.validateServerValueIsAvailable; @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) @@ -13,16 +15,19 @@ class QueryParameter extends DslProperty { QueryParameter(String name, DslProperty dslProperty) { super(dslProperty.clientValue, dslProperty.serverValue) + validateServerValueIsAvailable(dslProperty.serverValue, "Query parameter '$name'") this.name = name } QueryParameter(String name, MatchingStrategy matchingStrategy) { super(matchingStrategy) + validateServerValueIsAvailable(matchingStrategy, "Query parameter '$name'") this.name = name } QueryParameter(String name, Object value) { super(value) + validateServerValueIsAvailable(value, "Query parameter '$name'") this.name = name } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy index 42a26eb26c..09eae6d094 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy @@ -4,6 +4,8 @@ import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString +import static io.codearte.accurest.util.ValidateUtils.validateServerValueIsAvailable + @ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) @CompileStatic @@ -13,10 +15,12 @@ class Url extends DslProperty { Url(DslProperty prop) { super(prop.clientValue, prop.serverValue) + validateServerValueIsAvailable(prop.serverValue, "Url") } Url(Object url) { super(url) + validateServerValueIsAvailable(url, "Url") } void queryParameters(@DelegatesTo(QueryParameters) Closure closure) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy new file mode 100644 index 0000000000..9c07eaa3e4 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy @@ -0,0 +1,39 @@ +package io.codearte.accurest.util + +import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.dsl.internal.MatchingStrategy + +import java.util.regex.Pattern + +class ValidateUtils { + + static Object validateServerValueIsAvailable(Object value) { + validateServerValueIsAvailable(value, "Server value") + return value + } + + static Object validateServerValueIsAvailable(Object value, String msg) { + validateServerValue(value, msg) + return value + } + + static void validateServerValue(Pattern pattern, String msg) { + throw new IllegalStateException("$msg can't be a pattern") + } + + static void validateServerValue(MatchingStrategy matchingStrategy, String msg) { + if (matchingStrategy.type != MatchingStrategy.Type.EQUAL_TO) { + throw new IllegalStateException("$msg can't be of matching type: $matchingStrategy.type") + } + validateServerValue(matchingStrategy.serverValue, msg) + } + + static void validateServerValue(DslProperty value, String msg) { + validateServerValue(value.serverValue, msg) + } + + static void validateServerValue(Object value, String msg) { + // OK + } + +} 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 de857e0efc..e5e33d9e04 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 @@ -322,13 +322,13 @@ class WiremockGroovyDslSpec extends WiremockSpec { method 'GET' urlPath($(client("users"), server("items"))) { queryParameters { - parameter 'limit': $(client(equalTo("20")), server(containing("10"))) - parameter 'offset': containing("10") + parameter 'limit': $(client(equalTo("20")), server("10")) + parameter 'offset': $(client(containing("10")), server("10")) parameter 'filter': "email" - parameter 'sort': ~/^[0-9]{10}$/ - parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server(containing("10"))) - parameter 'age': notMatching("^\\w*\$") - parameter 'name': matching("Denis.*") + parameter 'sort': $(client(~/^[0-9]{10}$/), server("1234567890")) + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("10")) + parameter 'age': $(client(notMatching("^\\w*\$")), server(10)) + parameter 'name': $(client(matching("Denis.*")), server("Denis")) } } } @@ -435,9 +435,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(json) } - def "should generate request with url and queryParameters for client side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { + def "should not allow regexp in url for server value"() { + when: + GroovyDsl.make { request { method 'GET' url(regex(/users\/[0-9]*/)) { @@ -451,6 +451,68 @@ class WiremockGroovyDslSpec extends WiremockSpec { status 200 } } + then: + def e = thrown(IllegalStateException) + e.message.contains "Url can't be a pattern" + } + + def "should not allow regexp in query parameter for server value"() { + when: + GroovyDsl.make { + request { + method 'GET' + url("abc") { + queryParameters { + parameter 'age': $(client(notMatching("^\\w*\$")), server(regex(".*"))) + } + } + } + response { + status 200 + } + } + then: + def e = thrown(IllegalStateException) + e.message.contains "Query parameter 'age' can't be a pattern" + } + + def "should not allow query parameter unresolvable for a server value"() { + when: + GroovyDsl.make { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'age': notMatching("^\\w*\$") + parameter 'name': matching("Denis.*") + } + } + } + response { + status 200 + } + } + then: + def e = thrown(IllegalStateException) + e.message.contains "Query parameter 'age' can't be of matching type: NOT_MATCHING" + } + + def "should generate request with url and queryParameters for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url($(client(regex(/users\/[0-9]*/)), server("users/123"))) { + queryParameters { + parameter 'age': $(client(notMatching("^\\w*\$")), server(10)) + parameter 'name': $(client(matching("Denis.*")), server("Denis")) + } + } + } + response { + status 200 + } + } when: def json = toWiremockClientJsonStub(groovyDsl) then: From 86efa5f242c10c6c24eaa91f6309ea15d123af05 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Wed, 10 Jun 2015 10:53:11 +0200 Subject: [PATCH 147/719] Code review changes --- .../accurest/util/ValidateUtils.groovy | 6 +- .../builder/SpockMethodBuilderSpec.groovy | 56 +++++++++---------- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 6 +- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy index 9c07eaa3e4..eac7bce25c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy @@ -1,10 +1,12 @@ package io.codearte.accurest.util +import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.MatchingStrategy import java.util.regex.Pattern +@TypeChecked class ValidateUtils { static Object validateServerValueIsAvailable(Object value) { @@ -18,12 +20,12 @@ class ValidateUtils { } static void validateServerValue(Pattern pattern, String msg) { - throw new IllegalStateException("$msg can't be a pattern") + throw new IllegalStateException("$msg can't be a pattern for the server side") } static void validateServerValue(MatchingStrategy matchingStrategy, String msg) { if (matchingStrategy.type != MatchingStrategy.Type.EQUAL_TO) { - throw new IllegalStateException("$msg can't be of matching type: $matchingStrategy.type") + throw new IllegalStateException("$msg can't be of a matching type: $matchingStrategy.type for the server side") } validateServerValue(matchingStrategy.serverValue, msg) } 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 index ce1d00fa71..0aff49357f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -171,40 +171,40 @@ class SpockMethodBuilderSpec extends Specification { def "should generate a call with an url path and query parameters"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'GET' - urlPath('/users') { - queryParameters { - parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) - parameter 'offset': $(client(containing("20")), server(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) - parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) - parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + } } } - } - response { - status 200 - body """ - { - "property1": "a", - "property2": "b" + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ } - """ } - } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() then: - spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov")') - spockTest.contains('responseBody.property1 == "a"') - spockTest.contains('responseBody.property2 == "b"') + spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov")') + spockTest.contains('responseBody.property1 == "a"') + spockTest.contains('responseBody.property2 == "b"') } } 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 e5e33d9e04..7d8e5f1d49 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 @@ -453,7 +453,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } then: def e = thrown(IllegalStateException) - e.message.contains "Url can't be a pattern" + e.message.contains "Url can't be a pattern for the server side" } def "should not allow regexp in query parameter for server value"() { @@ -473,7 +473,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } then: def e = thrown(IllegalStateException) - e.message.contains "Query parameter 'age' can't be a pattern" + e.message.contains "Query parameter 'age' can't be a pattern for the server side" } def "should not allow query parameter unresolvable for a server value"() { @@ -494,7 +494,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } then: def e = thrown(IllegalStateException) - e.message.contains "Query parameter 'age' can't be of matching type: NOT_MATCHING" + e.message.contains "Query parameter 'age' can't be of a matching type: NOT_MATCHING for the server side" } def "should generate request with url and queryParameters for client side"() { From d45eb5ccc475dcf8a4328c6033328f3cebb5a18d Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Wed, 10 Jun 2015 22:44:38 +0200 Subject: [PATCH 148/719] Release version: 0.6.4 [ci skip] From 58b47fd6b4da6641503e34fac41840f22084ad89 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Thu, 11 Jun 2015 13:13:15 +0200 Subject: [PATCH 149/719] Implement selecting compare method by content type --- .../dsl/WiremockRequestStubStrategy.groovy | 15 +++- .../accurest/dsl/internal/Body.groovy | 51 +++++++++-- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 90 +++++++++++++++++++ 3 files changed, 149 insertions(+), 7 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 298cc1b2ec..3390b6456b 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.dsl import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientRequest +import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.MatchingStrategy import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.QueryParameters @@ -95,7 +96,19 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { } ))]]] } - return [bodyPatterns: [[equalTo: parseBody(body)]]] + + return [bodyPatterns: [[(getCompareType()): parseBody(body)]]] + } + + private String getCompareType() { + Header contentType = request.headers?.entries.find { it.name == "Content-Type" } + if (contentType && contentType.clientValue.toString().endsWith("json")) { + return "equalToJson" + } + if (contentType && contentType.clientValue.toString().endsWith("xml")) { + return "equalToXml" + } + return "equalTo" } protected String parseBody(Object body) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy index 315135d939..c68380f0f2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.dsl.internal +import groovy.json.JsonException import groovy.json.JsonSlurper import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @@ -9,6 +10,8 @@ import org.codehaus.groovy.runtime.GStringImpl import java.util.regex.Matcher import java.util.regex.Pattern +import static org.apache.commons.lang3.StringEscapeUtils.escapeXml11 + @ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) class Body extends DslProperty { @@ -55,15 +58,51 @@ class Body extends DslProperty { * @return JSON structure with replaced client / server side parts */ private static Object extractValue(GString bodyAsValue, Closure valueProvider) { - GString gString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) - Object[] values = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[] - Object[] valuesWithRegexpsAsTransformedStrings = values.collect { - it instanceof Pattern ? String.format(JSON_VALUE_PATTERN_FOR_REGEX, it.toString()) : it - } as Object[] - def parsedJson = new JsonSlurper().parseText(new GStringImpl(valuesWithRegexpsAsTransformedStrings, gString.strings)) + try { + return extractValueForJSON(bodyAsValue, valueProvider) + } catch(JsonException e) { + // Not a JSON format + return extractValueForXML(bodyAsValue, valueProvider) + } + return bodyAsValue + } + + private static Object extractValueForJSON(GString bodyAsValue, Closure valueProvider) { + GString transformedString = new GStringImpl( + bodyAsValue.values.collect { transformJSONStringValue(it, valueProvider) } as Object[], + bodyAsValue.strings.clone() + ) + def parsedJson = new JsonSlurper().parseText(transformedString) return convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) } + private static GStringImpl extractValueForXML(GString bodyAsValue, Closure valueProvider) { + return new GStringImpl( + bodyAsValue.values.collect { transformXMLStringValue(it, valueProvider) } as Object[], + bodyAsValue.strings.clone() + ) + } + + private static String transformJSONStringValue(Object obj, Closure valueProvider) { + return obj.toString() + } + + private static String transformJSONStringValue(DslProperty dslProperty, Closure valueProvider) { + return transformJSONStringValue(valueProvider(dslProperty), valueProvider) + } + + private static String transformJSONStringValue(Pattern pattern, Closure valueProvider) { + return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern()) + } + + private static String transformXMLStringValue(Object obj, Closure valueProvider) { + return escapeXml11(obj.toString()) + } + + private static String transformXMLStringValue(DslProperty dslProperty, Closure valueProvider) { + return transformXMLStringValue(valueProvider(dslProperty), valueProvider) + } + private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) { JsonConverter.transformValues(parsedJson, { Object value -> if (value instanceof String) { 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 7d8e5f1d49..4674441a09 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 @@ -150,6 +150,96 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(wiremockStub) } + def 'should use equalToJson when content type ends with json'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + headers { + header "Content-Type", "customtype/json" + } + body """ + { + "name": "Jan" + } + """ + } + response { + status 200 + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users", + "headers": { + "Content-Type": { + "equalTo": "customtype/json" + } + }, + "bodyPatterns": [ + { + "equalToJson":"{\\"name\\":\\"Jan\\"}" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def 'should use equalToXml when content type ends with xml'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + headers { + header "Content-Type", "customtype/xml" + } + body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + } + response { + status 200 + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users", + "headers": { + "Content-Type": { + "equalTo": "customtype/xml" + } + }, + "bodyPatterns": [ + { + "equalToXml":"Jozo<test>" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + def 'should convert groovy dsl stub with regexp Body as String to wiremock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From a5502b35e27dffdf814b3e364a57023bc314ef75 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Thu, 11 Jun 2015 13:37:14 +0200 Subject: [PATCH 150/719] Implement selecting compare method by content type --- .../dsl/WiremockRequestStubStrategy.groovy | 55 ++++++++----------- .../accurest/dsl/internal/Body.groovy | 8 +++ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 3390b6456b..31eb05300a 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -2,7 +2,6 @@ package io.codearte.accurest.dsl import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientRequest -import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.MatchingStrategy import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.QueryParameters @@ -80,32 +79,35 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { if (body == null) { return [:] } - if (containsRegex(body)) { - return [bodyPatterns: [[matches: parseBody(convertJsonStructureToObjectUnderstandingStructure(body, - { it instanceof Pattern }, - { String json -> json.collect { - switch(it) { - case ('{'): return '\\{' - case ('}'): return '\\}' - default: return it - } - } .join('') - }, - { LinkedList list, String json -> - return json.replaceAll(TEMPORARY_PATTERN_HOLDER, { String a, String[] b -> list.pop() }) - } - ))]]] + if (clientRequest.body?.containsPattern) { + return [bodyPatterns: [[matches: escapeBodyForJson(body)]]] } - - return [bodyPatterns: [[(getCompareType()): parseBody(body)]]] + return [bodyPatterns: [[(getMatchType()): parseBody(body)]]] } - private String getCompareType() { - Header contentType = request.headers?.entries.find { it.name == "Content-Type" } - if (contentType && contentType.clientValue.toString().endsWith("json")) { + private Object escapeBodyForJson(Object body) { + return parseBody(convertJsonStructureToObjectUnderstandingStructure(body, + { it instanceof Pattern }, + { String json -> json.collect { + switch(it) { + case ('{'): return '\\{' + case ('}'): return '\\}' + default: return it + } + } .join('') + }, + { LinkedList list, String json -> + return json.replaceAll(TEMPORARY_PATTERN_HOLDER, { String a, String[] b -> list.pop() }) + } + )) + } + + private String getMatchType() { + String content = request.headers?.entries.find { it.name == "Content-Type" } ?.clientValue?.toString() + if (content?.endsWith("json")) { return "equalToJson" } - if (contentType && contentType.clientValue.toString().endsWith("xml")) { + if (content?.endsWith("xml")) { return "equalToXml" } return "equalTo" @@ -115,13 +117,4 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return body } - boolean containsRegex(Object bodyObject) { - String bodyString = bodyObject as String - return (bodyString =~ /\^.*\$/).find() - } - - boolean containsRegex(Map map) { - return map.values().any { it instanceof Pattern } - } - } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy index c68380f0f2..78813a74a8 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy @@ -19,6 +19,8 @@ class Body extends DslProperty { private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' + boolean containsPattern + Body(Map body) { super(extractValue(body, {it.clientValue}), extractValue(body, {it.serverValue})) } @@ -39,12 +41,18 @@ class Body extends DslProperty { Body(GString bodyAsValue) { super(extractValue(bodyAsValue, {it.clientValue}), extractValue(bodyAsValue, {it.serverValue})) + containsPattern = containsPattern(bodyAsValue) } Body(DslProperty bodyAsValue) { super(bodyAsValue.clientValue, bodyAsValue.serverValue) } + private boolean containsPattern(GString bodyAsValue) { + return bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } + .find { it instanceof Pattern } + } + /** * Due to the fact that we allow users to have a body with GString and different values inside * we need to be prepared that they pass regexps around both on client and server side. From b5e1799468d40bf65b43f028726a7ab9990f0dbf Mon Sep 17 00:00:00 2001 From: "Jozef.Najman" Date: Thu, 11 Jun 2015 15:27:20 +0200 Subject: [PATCH 151/719] Fixed generating stubs from regex - one matcher for one regex --- .../dsl/WiremockRequestStubStrategy.groovy | 28 ++--- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 113 ++++++++++++++---- .../codearte/accurest/dsl/WiremockSpec.groovy | 2 +- 3 files changed, 103 insertions(+), 40 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 31eb05300a..3c726f66d2 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -80,26 +80,24 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return [:] } if (clientRequest.body?.containsPattern) { - return [bodyPatterns: [[matches: escapeBodyForJson(body)]]] + return [bodyPatterns: parseMatchesBody(body)] } return [bodyPatterns: [[(getMatchType()): parseBody(body)]]] } - private Object escapeBodyForJson(Object body) { - return parseBody(convertJsonStructureToObjectUnderstandingStructure(body, - { it instanceof Pattern }, - { String json -> json.collect { - switch(it) { - case ('{'): return '\\{' - case ('}'): return '\\}' - default: return it - } - } .join('') - }, - { LinkedList list, String json -> - return json.replaceAll(TEMPORARY_PATTERN_HOLDER, { String a, String[] b -> list.pop() }) + private Object parseMatchesBody(def responseBodyObject) { + def regexList = new ArrayList<>() + responseBodyObject.each { k, v -> + if (v instanceof List) { + v.each { + regexList.addAll(parseMatchesBody((Map)it)) } - )) + } else { + String regex = ".*${k}\":.?\"${v}\".*" + regexList.add([matches: regex]); + } + } + return regexList } private String getMatchType() { 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 4674441a09..452cc758ed 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 @@ -161,7 +161,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } body """ { - "name": "Jan" + "name": "${value(client('Jan'), server('Honza'))}" } """ } @@ -270,22 +270,20 @@ class WiremockGroovyDslSpec extends WiremockSpec { then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}", - "bodyPatterns": [ - { - "matches":"\\\\{\\"personalId\\":\\"^[0-9]{11}$\\"\\\\}" - } - ] - }, - "response": { - "status": 200, - "body": "{\\"name\\":\\"Jan\\"}", - "headers": { - "Content-Type": "text/plain" - } - } + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}", + "bodyPatterns": [ + {"matches": ".*personalId\\":.?\\"^[0-9]{11}$\\".*"} + ] + }, + "response": { + "status": 200, + "body": "{\\"name\\":\\"Jan\\"}", + "headers": { + "Content-Type": "text/plain" + } + } } ''') and: @@ -336,9 +334,8 @@ class WiremockGroovyDslSpec extends WiremockSpec { }, "url": "/fraudcheck", "bodyPatterns": [ - { - "matches": "\\\\{\\"clientPesel\\":\\"[0-9]{10}\\",\\"loanAmount\\":123.123\\\\}" - } + {"matches": ".*clientPesel\\":.?\\"[0-9]{10}\\".*"}, + {"matches": ".*loanAmount\\":.?\\"123.123\\".*"} ] }, "response": { @@ -658,10 +655,78 @@ class WiremockGroovyDslSpec extends WiremockSpec { }, "X-Custom-Header": { "matches": "^.*2134.*$" - } - } - } - ''') + } + } + } + ''') + } + + def 'should convert groovy dsl stub with rich tree Body as String to wiremock stub for the client side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + url $(client(~/\/[0-9]{2}/), server('/12')) + body """\ + { + "personalId": "${value(client(regex('[0-9]{11}')), server('57593728525'))}", + "firstName": "${value(client(regex('.*')), server('Bruce'))}", + "lastName": "${value(client(regex('.*')), server('Lee'))}", + "birthDate": "${value(client(regex('[0-9]{4}-[0-9]{2}-[0-9]{2}')), server('1985-12-12'))}", + "errors": [ + { + "propertyName": "${value(client(regex('[0-9]{2}')), server('04'))}", + "providerValue": "Test" + }, + { + "propertyName": "${value(client(regex('[0-9]{2}')), server('08'))}", + "providerValue": "Test" + } + ] + } + """ + } + response { + status 200 + body("""\ + { + "name": "Jan" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}", + "bodyPatterns": [ + {"matches": ".*birthDate\\":.?\\"[0-9]{4}-[0-9]{2}-[0-9]{2}\\".*"}, + {"matches": ".*propertyName\\":.?\\"[0-9]{2}\\".*"}, + {"matches": ".*providerValue\\":.?\\"Test\\".*"}, + {"matches": ".*propertyName\\":.?\\"[0-9]{2}\\".*"}, + {"matches": ".*providerValue\\":.?\\"Test\\".*"}, + {"matches": ".*firstName\\":.?\\".*\\".*"}, + {"matches": ".*lastName\\":.?\\".*\\".*"}, + {"matches": ".*personalId\\":.?\\"[0-9]{11}\\".*"} + ] + }, + "response": { + "status": 200, + "body": "{\\"name\\":\\"Jan\\"}", + "headers": { + "Content-Type": "text/plain" + } + } + } + ''') } String toJsonString(value) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy index 796e603c11..ab1133c9ae 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy @@ -5,7 +5,7 @@ import spock.lang.Specification import java.util.regex.Pattern -class WiremockSpec extends Specification { +abstract class WiremockSpec extends Specification { void stubMappingIsValidWiremockStub(String mappingDefinition) { StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) From 254a67cdb58b0285d6d41fa1156bacf422fe5aac Mon Sep 17 00:00:00 2001 From: "Jozef.Najman" Date: Thu, 11 Jun 2015 17:14:12 +0200 Subject: [PATCH 152/719] Reverted generating stubs from regex - one matcher for one regex --- .../dsl/WiremockRequestStubStrategy.groovy | 28 +++-- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 113 ++++-------------- 2 files changed, 39 insertions(+), 102 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 3c726f66d2..31eb05300a 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -80,24 +80,26 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return [:] } if (clientRequest.body?.containsPattern) { - return [bodyPatterns: parseMatchesBody(body)] + return [bodyPatterns: [[matches: escapeBodyForJson(body)]]] } return [bodyPatterns: [[(getMatchType()): parseBody(body)]]] } - private Object parseMatchesBody(def responseBodyObject) { - def regexList = new ArrayList<>() - responseBodyObject.each { k, v -> - if (v instanceof List) { - v.each { - regexList.addAll(parseMatchesBody((Map)it)) + private Object escapeBodyForJson(Object body) { + return parseBody(convertJsonStructureToObjectUnderstandingStructure(body, + { it instanceof Pattern }, + { String json -> json.collect { + switch(it) { + case ('{'): return '\\{' + case ('}'): return '\\}' + default: return it + } + } .join('') + }, + { LinkedList list, String json -> + return json.replaceAll(TEMPORARY_PATTERN_HOLDER, { String a, String[] b -> list.pop() }) } - } else { - String regex = ".*${k}\":.?\"${v}\".*" - regexList.add([matches: regex]); - } - } - return regexList + )) } private String getMatchType() { 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 452cc758ed..4674441a09 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 @@ -161,7 +161,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } body """ { - "name": "${value(client('Jan'), server('Honza'))}" + "name": "Jan" } """ } @@ -270,20 +270,22 @@ class WiremockGroovyDslSpec extends WiremockSpec { then: new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' { - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}", - "bodyPatterns": [ - {"matches": ".*personalId\\":.?\\"^[0-9]{11}$\\".*"} - ] - }, - "response": { - "status": 200, - "body": "{\\"name\\":\\"Jan\\"}", - "headers": { - "Content-Type": "text/plain" - } - } + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}", + "bodyPatterns": [ + { + "matches":"\\\\{\\"personalId\\":\\"^[0-9]{11}$\\"\\\\}" + } + ] + }, + "response": { + "status": 200, + "body": "{\\"name\\":\\"Jan\\"}", + "headers": { + "Content-Type": "text/plain" + } + } } ''') and: @@ -334,8 +336,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { }, "url": "/fraudcheck", "bodyPatterns": [ - {"matches": ".*clientPesel\\":.?\\"[0-9]{10}\\".*"}, - {"matches": ".*loanAmount\\":.?\\"123.123\\".*"} + { + "matches": "\\\\{\\"clientPesel\\":\\"[0-9]{10}\\",\\"loanAmount\\":123.123\\\\}" + } ] }, "response": { @@ -655,78 +658,10 @@ class WiremockGroovyDslSpec extends WiremockSpec { }, "X-Custom-Header": { "matches": "^.*2134.*$" - } - } - } - ''') - } - - def 'should convert groovy dsl stub with rich tree Body as String to wiremock stub for the client side'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - url $(client(~/\/[0-9]{2}/), server('/12')) - body """\ - { - "personalId": "${value(client(regex('[0-9]{11}')), server('57593728525'))}", - "firstName": "${value(client(regex('.*')), server('Bruce'))}", - "lastName": "${value(client(regex('.*')), server('Lee'))}", - "birthDate": "${value(client(regex('[0-9]{4}-[0-9]{2}-[0-9]{2}')), server('1985-12-12'))}", - "errors": [ - { - "propertyName": "${value(client(regex('[0-9]{2}')), server('04'))}", - "providerValue": "Test" - }, - { - "propertyName": "${value(client(regex('[0-9]{2}')), server('08'))}", - "providerValue": "Test" - } - ] - } - """ - } - response { - status 200 - body("""\ - { - "name": "Jan" - } - """ - ) - headers { - header 'Content-Type': 'text/plain' - } - } - } - when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() - then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' - { - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}", - "bodyPatterns": [ - {"matches": ".*birthDate\\":.?\\"[0-9]{4}-[0-9]{2}-[0-9]{2}\\".*"}, - {"matches": ".*propertyName\\":.?\\"[0-9]{2}\\".*"}, - {"matches": ".*providerValue\\":.?\\"Test\\".*"}, - {"matches": ".*propertyName\\":.?\\"[0-9]{2}\\".*"}, - {"matches": ".*providerValue\\":.?\\"Test\\".*"}, - {"matches": ".*firstName\\":.?\\".*\\".*"}, - {"matches": ".*lastName\\":.?\\".*\\".*"}, - {"matches": ".*personalId\\":.?\\"[0-9]{11}\\".*"} - ] - }, - "response": { - "status": 200, - "body": "{\\"name\\":\\"Jan\\"}", - "headers": { - "Content-Type": "text/plain" - } - } - } - ''') + } + } + } + ''') } String toJsonString(value) { From 72b00f6ac86b508709d45612cc3fb32e46ce3996 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 12 Jun 2015 13:40:54 +0200 Subject: [PATCH 153/719] [#79] Fixed the bug with exception with a json and map --- .../builder/SpockMethodBodyBuilder.groovy | 24 ++++++++------- .../builder/SpockMethodBuilderSpec.groovy | 30 +++++++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 41734b0a3a..3d44123212 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.builder import groovy.json.JsonOutput import groovy.transform.PackageScope 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 @@ -12,7 +13,6 @@ import io.codearte.accurest.dsl.internal.Response import io.codearte.accurest.dsl.internal.UrlPath import java.util.regex.Pattern - /** * @author Jakub Kubrynski */ @@ -102,9 +102,7 @@ class SpockMethodBodyBuilder { matchingStrategy.serverValue.toString() } - private void processBodyElement(BlockBuilder blockBuilder, String rootProperty, def element) { - def value = element.value - String property = rootProperty + "." + element.key + private void processBodyElement(BlockBuilder blockBuilder, String property, def value) { if (value instanceof String) { if (value.startsWith('$')) { value = value.substring(1).replaceAll('\\$value', "responseBody$property") @@ -114,10 +112,14 @@ class SpockMethodBodyBuilder { } } else if (value instanceof Map) { processMapElement(value, blockBuilder, property) + }else if (value instanceof Map.Entry) { + processEntryElement(blockBuilder, property, value) } else if (value instanceof List) { processArrayElements(value, property, blockBuilder) } else if (value instanceof Pattern) { blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") + } else if (value instanceof DslProperty) { + processBodyElement(blockBuilder, property, value.serverValue) } else if (value instanceof ExecutionProperty) { ExecutionProperty exec = (ExecutionProperty) value blockBuilder.addLine("${exec.insertValue("responseBody$property")}") @@ -127,18 +129,20 @@ class SpockMethodBodyBuilder { } private void processMapElement(def value, BlockBuilder blockBuilder, String property) { - value.each { entry -> processBodyElement(blockBuilder, property, entry) } + value.each { entry -> processEntryElement(blockBuilder, property, entry) } + } + + private def processEntryElement(BlockBuilder blockBuilder, String property, def entry) { + return processBodyElement(blockBuilder, property + "." + entry.key, entry.value) } private void processArrayElements(List responseBody, String property, BlockBuilder blockBuilder) { responseBody.eachWithIndex { listElement, listIndex -> - listElement.each { - entry -> processBodyElement(blockBuilder, property + "[$listIndex]", entry) + listElement.each { entry -> + String prop = "$property[$listIndex]" ?: '' + processBodyElement(blockBuilder, prop, entry) } } } - private void processClosure(Closure value, BlockBuilder blockBuilder, String property) { - blockBuilder.addLine() - } } 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 index 0aff49357f..a2d03358a2 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl +import spock.lang.Issue import spock.lang.Specification /** @@ -32,6 +33,35 @@ class SpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("responseBody.property2 == \"b\"") } + @Issue("#79") + def "should generate assertions for simple response body constructed from map"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body ( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + 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[0].a == \"sth\"") + blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") + } + def "should generate assertions for array in response body"() { given: GroovyDsl contractDsl = GroovyDsl.make { From 1cabe971e477963dd8eba1331ab94c2a1d79c458 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 12 Jun 2015 14:57:25 +0200 Subject: [PATCH 154/719] [#79] Fixed the way wiremock stubs are built --- .../dsl/BaseWiremockStubStrategy.groovy | 10 +++- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 48 +++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) 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 index 77866f1437..32bc831f1b 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -3,8 +3,10 @@ import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.transform.TypeChecked import groovy.xml.XmlUtil +import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.Headers +import io.codearte.accurest.util.JsonConverter import java.util.regex.Pattern @@ -12,6 +14,11 @@ import static groovy.json.StringEscapeUtils.escapeJava @TypeChecked abstract class BaseWiremockStubStrategy { + + private static Closure transform = { + it instanceof DslProperty ? JsonConverter.transformValues(it.clientValue, transform) : it + } + protected Map buildClientRequestHeadersSection(Headers headers) { if (!headers) { return null @@ -62,6 +69,7 @@ abstract class BaseWiremockStubStrategy { } protected String parseBody(Map body) { - return JsonOutput.toJson(body) + def transformedMap = JsonConverter.transformValues(body, transform) + return JsonOutput.toJson(transformedMap) } } 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 7d8e5f1d49..c8767551b4 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 @@ -2,6 +2,7 @@ package io.codearte.accurest.dsl import groovy.json.JsonBuilder import groovy.json.JsonSlurper +import spock.lang.Issue class WiremockGroovyDslSpec extends WiremockSpec { @@ -53,6 +54,53 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(wiremockStub) } + @Issue("#79") + def 'should convert groovy dsl stub to wiremock stub for the client side with a body containing a map'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url '/ingredients' + headers { + header 'Content-Type': 'application/vnd.pl.devoxx.aggregatr.v1+json' + } + } + response { + status 200 + body( + ingredients: [ + [type: 'MALT', quantity: 100], + [type: 'WATER', quantity: 200], + [type: 'HOP', quantity: 300], + [type: 'YIEST', quantity: 400] + ] + ) + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "GET", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.pl.devoxx.aggregatr.v1+json" + } + }, + "url": "/ingredients" + }, + "response": { + "status": 200, + "body": "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}" + } +} +''') + and: + stubMappingIsValidWiremockStub(wiremockStub) + } + def 'should convert groovy dsl stub with Body as String to wiremock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From a0c6f7959c7391230c74cc8acc4cb3ee43fda69b Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Fri, 12 Jun 2015 15:20:16 +0200 Subject: [PATCH 155/719] Revert "Implement selecting compare method by content type" This reverts commit a5502b35e27dffdf814b3e364a57023bc314ef75. --- .../dsl/WiremockRequestStubStrategy.groovy | 55 +++++++++++-------- .../accurest/dsl/internal/Body.groovy | 8 --- 2 files changed, 31 insertions(+), 32 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 31eb05300a..3390b6456b 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.dsl import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientRequest +import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.MatchingStrategy import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.QueryParameters @@ -79,35 +80,32 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { if (body == null) { return [:] } - if (clientRequest.body?.containsPattern) { - return [bodyPatterns: [[matches: escapeBodyForJson(body)]]] - } - return [bodyPatterns: [[(getMatchType()): parseBody(body)]]] - } - - private Object escapeBodyForJson(Object body) { - return parseBody(convertJsonStructureToObjectUnderstandingStructure(body, - { it instanceof Pattern }, - { String json -> json.collect { - switch(it) { - case ('{'): return '\\{' - case ('}'): return '\\}' - default: return it + if (containsRegex(body)) { + return [bodyPatterns: [[matches: parseBody(convertJsonStructureToObjectUnderstandingStructure(body, + { it instanceof Pattern }, + { String json -> json.collect { + switch(it) { + case ('{'): return '\\{' + case ('}'): return '\\}' + default: return it + } + } .join('') + }, + { LinkedList list, String json -> + return json.replaceAll(TEMPORARY_PATTERN_HOLDER, { String a, String[] b -> list.pop() }) } - } .join('') - }, - { LinkedList list, String json -> - return json.replaceAll(TEMPORARY_PATTERN_HOLDER, { String a, String[] b -> list.pop() }) - } - )) + ))]]] + } + + return [bodyPatterns: [[(getCompareType()): parseBody(body)]]] } - private String getMatchType() { - String content = request.headers?.entries.find { it.name == "Content-Type" } ?.clientValue?.toString() - if (content?.endsWith("json")) { + private String getCompareType() { + Header contentType = request.headers?.entries.find { it.name == "Content-Type" } + if (contentType && contentType.clientValue.toString().endsWith("json")) { return "equalToJson" } - if (content?.endsWith("xml")) { + if (contentType && contentType.clientValue.toString().endsWith("xml")) { return "equalToXml" } return "equalTo" @@ -117,4 +115,13 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return body } + boolean containsRegex(Object bodyObject) { + String bodyString = bodyObject as String + return (bodyString =~ /\^.*\$/).find() + } + + boolean containsRegex(Map map) { + return map.values().any { it instanceof Pattern } + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy index 78813a74a8..c68380f0f2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy @@ -19,8 +19,6 @@ class Body extends DslProperty { private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' - boolean containsPattern - Body(Map body) { super(extractValue(body, {it.clientValue}), extractValue(body, {it.serverValue})) } @@ -41,18 +39,12 @@ class Body extends DslProperty { Body(GString bodyAsValue) { super(extractValue(bodyAsValue, {it.clientValue}), extractValue(bodyAsValue, {it.serverValue})) - containsPattern = containsPattern(bodyAsValue) } Body(DslProperty bodyAsValue) { super(bodyAsValue.clientValue, bodyAsValue.serverValue) } - private boolean containsPattern(GString bodyAsValue) { - return bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } - .find { it instanceof Pattern } - } - /** * Due to the fact that we allow users to have a body with GString and different values inside * we need to be prepared that they pass regexps around both on client and server side. From 080aae6060be1202d92deabdddf11baf97a1b3a3 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Fri, 12 Jun 2015 15:20:49 +0200 Subject: [PATCH 156/719] Revert "Implement selecting compare method by content type" This reverts commit 58b47fd6b4da6641503e34fac41840f22084ad89. --- .../dsl/WiremockRequestStubStrategy.groovy | 15 +--- .../accurest/dsl/internal/Body.groovy | 51 ++--------- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 90 ------------------- 3 files changed, 7 insertions(+), 149 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 3390b6456b..298cc1b2ec 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -2,7 +2,6 @@ package io.codearte.accurest.dsl import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientRequest -import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.MatchingStrategy import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.QueryParameters @@ -96,19 +95,7 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { } ))]]] } - - return [bodyPatterns: [[(getCompareType()): parseBody(body)]]] - } - - private String getCompareType() { - Header contentType = request.headers?.entries.find { it.name == "Content-Type" } - if (contentType && contentType.clientValue.toString().endsWith("json")) { - return "equalToJson" - } - if (contentType && contentType.clientValue.toString().endsWith("xml")) { - return "equalToXml" - } - return "equalTo" + return [bodyPatterns: [[equalTo: parseBody(body)]]] } protected String parseBody(Object body) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy index c68380f0f2..315135d939 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy @@ -1,6 +1,5 @@ package io.codearte.accurest.dsl.internal -import groovy.json.JsonException import groovy.json.JsonSlurper import groovy.transform.EqualsAndHashCode import groovy.transform.ToString @@ -10,8 +9,6 @@ import org.codehaus.groovy.runtime.GStringImpl import java.util.regex.Matcher import java.util.regex.Pattern -import static org.apache.commons.lang3.StringEscapeUtils.escapeXml11 - @ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) class Body extends DslProperty { @@ -58,51 +55,15 @@ class Body extends DslProperty { * @return JSON structure with replaced client / server side parts */ private static Object extractValue(GString bodyAsValue, Closure valueProvider) { - try { - return extractValueForJSON(bodyAsValue, valueProvider) - } catch(JsonException e) { - // Not a JSON format - return extractValueForXML(bodyAsValue, valueProvider) - } - return bodyAsValue - } - - private static Object extractValueForJSON(GString bodyAsValue, Closure valueProvider) { - GString transformedString = new GStringImpl( - bodyAsValue.values.collect { transformJSONStringValue(it, valueProvider) } as Object[], - bodyAsValue.strings.clone() - ) - def parsedJson = new JsonSlurper().parseText(transformedString) + GString gString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) + Object[] values = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[] + Object[] valuesWithRegexpsAsTransformedStrings = values.collect { + it instanceof Pattern ? String.format(JSON_VALUE_PATTERN_FOR_REGEX, it.toString()) : it + } as Object[] + def parsedJson = new JsonSlurper().parseText(new GStringImpl(valuesWithRegexpsAsTransformedStrings, gString.strings)) return convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) } - private static GStringImpl extractValueForXML(GString bodyAsValue, Closure valueProvider) { - return new GStringImpl( - bodyAsValue.values.collect { transformXMLStringValue(it, valueProvider) } as Object[], - bodyAsValue.strings.clone() - ) - } - - private static String transformJSONStringValue(Object obj, Closure valueProvider) { - return obj.toString() - } - - private static String transformJSONStringValue(DslProperty dslProperty, Closure valueProvider) { - return transformJSONStringValue(valueProvider(dslProperty), valueProvider) - } - - private static String transformJSONStringValue(Pattern pattern, Closure valueProvider) { - return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern()) - } - - private static String transformXMLStringValue(Object obj, Closure valueProvider) { - return escapeXml11(obj.toString()) - } - - private static String transformXMLStringValue(DslProperty dslProperty, Closure valueProvider) { - return transformXMLStringValue(valueProvider(dslProperty), valueProvider) - } - private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) { JsonConverter.transformValues(parsedJson, { Object value -> if (value instanceof String) { 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 4674441a09..7d8e5f1d49 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 @@ -150,96 +150,6 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(wiremockStub) } - def 'should use equalToJson when content type ends with json'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method 'GET' - url "/users" - headers { - header "Content-Type", "customtype/json" - } - body """ - { - "name": "Jan" - } - """ - } - response { - status 200 - } - } - when: - String json = toWiremockClientJsonStub(groovyDsl) - then: - parseJson(json) == parseJson(''' - { - "request": { - "method": "GET", - "url": "/users", - "headers": { - "Content-Type": { - "equalTo": "customtype/json" - } - }, - "bodyPatterns": [ - { - "equalToJson":"{\\"name\\":\\"Jan\\"}" - } - ] - }, - "response": { - "status": 200 - } - } - ''') - and: - stubMappingIsValidWiremockStub(json) - } - - def 'should use equalToXml when content type ends with xml'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method 'GET' - url "/users" - headers { - header "Content-Type", "customtype/xml" - } - body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" - } - response { - status 200 - } - } - when: - String json = toWiremockClientJsonStub(groovyDsl) - then: - parseJson(json) == parseJson(''' - { - "request": { - "method": "GET", - "url": "/users", - "headers": { - "Content-Type": { - "equalTo": "customtype/xml" - } - }, - "bodyPatterns": [ - { - "equalToXml":"Jozo<test>" - } - ] - }, - "response": { - "status": 200 - } - } - ''') - and: - stubMappingIsValidWiremockStub(json) - } - def 'should convert groovy dsl stub with regexp Body as String to wiremock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From b2887e9588ca82826c05a111bcf3ad9a6f1928f5 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Fri, 12 Jun 2015 15:23:02 +0200 Subject: [PATCH 157/719] Revert changes --- .../test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy index ab1133c9ae..796e603c11 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy @@ -5,7 +5,7 @@ import spock.lang.Specification import java.util.regex.Pattern -abstract class WiremockSpec extends Specification { +class WiremockSpec extends Specification { void stubMappingIsValidWiremockStub(String mappingDefinition) { StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) From 1cca744b56cf8a786969704d063369d1162dffbd Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Fri, 12 Jun 2015 15:25:46 +0200 Subject: [PATCH 158/719] Fix windows bug --- .../src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy index 4817cc4816..a15bd1b5dc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy @@ -40,6 +40,6 @@ class NamesUtil { } static String packageToDirectory(String packageName) { - return packageName.replaceAll('\\.', File.separator) + return packageName.replace('.' as char, File.separatorChar) } } From 118b63c2a036440dd3c2f02823f0cbd0cd6c8b3b Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Fri, 12 Jun 2015 11:47:15 +0200 Subject: [PATCH 159/719] Body matching by content type and client-side XML support --- .../DslToWiremockClientConverterSpec.groovy | 2 +- .../builder/SpockMethodBodyBuilder.groovy | 34 +- .../dsl/BaseWiremockStubStrategy.groovy | 70 ++- .../dsl/WiremockRequestStubStrategy.groovy | 94 ++- .../dsl/WiremockResponseStubStrategy.groovy | 15 +- .../accurest/dsl/internal/Body.groovy | 55 +- .../dsl/internal/MatchingStrategy.groovy | 45 +- .../dsl/internal/QueryParameters.groovy | 16 - .../accurest/dsl/internal/Request.groovy | 50 ++ .../codearte/accurest/util/ContentType.groovy | 5 + .../accurest/util/ContentUtils.groovy | 192 ++++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 557 +++++++++++++++--- .../codearte/accurest/dsl/WiremockSpec.groovy | 2 +- .../plugin/BasicFunctionalSpec.groovy | 2 +- 14 files changed, 897 insertions(+), 242 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy 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 2f20546014..edf11a256f 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 @@ -85,7 +85,7 @@ class DslToWiremockClientConverterSpec extends Specification { "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\\"}]" } + { "equalToJson": "[{\\"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": { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 3d44123212..544abb98b1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -11,8 +11,14 @@ 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.UrlPath +import io.codearte.accurest.util.ContentType import java.util.regex.Pattern + +import static io.codearte.accurest.util.ContentUtils.extractValue +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent + /** * @author Jakub Kubrynski */ @@ -36,7 +42,11 @@ class SpockMethodBodyBuilder { addLine(".header('${header.name}', '${header.serverValue}')") } if (request.body) { - String matches = new JsonOutput().toJson(request.body.serverValue) + Object bodyValue = request.body.serverValue + if (bodyValue instanceof GString) { + bodyValue = extractValue(bodyValue, {DslProperty dslProperty -> dslProperty.serverValue}) + } + String matches = new JsonOutput().toJson(bodyValue) addLine(".body('$matches')") } @@ -61,12 +71,24 @@ class SpockMethodBodyBuilder { if (response.body) { endBlock() addLine('and:').startBlock() - addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') def responseBody = response.body.serverValue - if (responseBody instanceof List) { - processArrayElements(responseBody, "", blockBuilder) - } else { - processMapElement(responseBody, blockBuilder, "") + ContentType contentType = recognizeContentTypeFromHeader(response.headers) + if (contentType == ContentType.UNKNOWN) { + contentType = recognizeContentTypeFromContent(responseBody) + } + if (responseBody instanceof GString) { + responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) + } + if (contentType == ContentType.JSON) { + addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') + if (responseBody instanceof List) { + processArrayElements(responseBody, "", blockBuilder) + } else { + processMapElement(responseBody, blockBuilder, "") + } + } else if (contentType == ContentType.XML) { + addLine('def responseBody = new XmlSlurper().parseText(response.body.asString())') + // TODO xml validation } } endBlock() 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 index 32bc831f1b..a5c100341b 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -1,22 +1,22 @@ package io.codearte.accurest.dsl -import groovy.json.JsonOutput -import groovy.json.JsonSlurper + +import groovy.json.JsonBuilder import groovy.transform.TypeChecked -import groovy.xml.XmlUtil import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.Headers -import io.codearte.accurest.util.JsonConverter +import io.codearte.accurest.util.ContentType import java.util.regex.Pattern -import static groovy.json.StringEscapeUtils.escapeJava +import static io.codearte.accurest.util.ContentUtils.extractValue +import static io.codearte.accurest.util.JsonConverter.transformValues @TypeChecked abstract class BaseWiremockStubStrategy { private static Closure transform = { - it instanceof DslProperty ? JsonConverter.transformValues(it.clientValue, transform) : it + it instanceof DslProperty ? transformValues(it.clientValue, transform) : it } protected Map buildClientRequestHeadersSection(Headers headers) { @@ -33,43 +33,49 @@ abstract class BaseWiremockStubStrategy { return null } return headers.entries.collectEntries { Header entry -> - [(entry.name) : entry.clientValue] + [(entry.name): entry.clientValue] } } protected Map parseHeader(String entryKey, Object entry) { - return [(entryKey): [equalTo : entry]] + return [(entryKey): [equalTo: entry]] } protected Map parseHeader(String entryKey, String entry) { - return [(entryKey): [equalTo : entry]] + return [(entryKey): [equalTo: entry]] } protected Map parseHeader(String entryKey, Pattern entry) { - return [(entryKey): [matches : entry.pattern()]] + 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) - } - } - } + public String parseBody(Object value, ContentType contentType) { + return parseBody(value.toString(), contentType) + } - protected String parseBody(List body) { - return JsonOutput.toJson(body) - } + public String parseBody(Map map, ContentType contentType) { + def transformedMap = transformValues(map, transform) + return parseBody(toJson(transformedMap), contentType) + } - protected String parseBody(Map body) { - def transformedMap = JsonConverter.transformValues(body, transform) - return JsonOutput.toJson(transformedMap) - } -} + public String parseBody(List list, ContentType contentType) { + return parseBody(toJson(list), contentType) + } + + public String parseBody(GString value, ContentType contentType) { + Object processedValue = extractValue(value, contentType, { DslProperty dslProperty -> dslProperty.clientValue }) + if (processedValue instanceof GString) { + return parseBody(processedValue.toString(), contentType) + } + return parseBody(processedValue, contentType) + } + + public String parseBody(String value, ContentType contentType) { + return value + } + + private static toJson(Object value) { + return new JsonBuilder(value).toString() + } + +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index 298cc1b2ec..f9bc9bdc23 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,16 +1,23 @@ package io.codearte.accurest.dsl + import groovy.transform.PackageScope import groovy.transform.TypeChecked +import io.codearte.accurest.dsl.internal.Body import io.codearte.accurest.dsl.internal.ClientRequest +import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.MatchingStrategy import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.QueryParameters import io.codearte.accurest.dsl.internal.Request +import io.codearte.accurest.util.ContentType import java.util.regex.Pattern -import static io.codearte.accurest.dsl.internal.JsonStructureConverter.TEMPORARY_PATTERN_HOLDER -import static io.codearte.accurest.dsl.internal.JsonStructureConverter.convertJsonStructureToObjectUnderstandingStructure +import static io.codearte.accurest.util.ContentUtils.extractValue +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader +import static io.codearte.accurest.util.ContentUtils.getEqualsTypeFromContentType +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromMatchingStrategy @TypeChecked @PackageScope @@ -29,7 +36,7 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private Map buildRequestContent(ClientRequest request) { return ([method : request?.method?.clientValue, - headers : buildClientRequestHeadersSection(request.headers) + headers : buildClientRequestHeadersSection(request.headers) ] << appendUrl(request) << appendQueryParameters(request) << appendBody(request)).findAll { it.value } } @@ -75,40 +82,69 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { } private Map appendBody(ClientRequest clientRequest) { - Object body = clientRequest?.body?.clientValue - if (body == null) { - return [:] + return clientRequest.body? appendBody(clientRequest.body) : [:] + } + + private Map appendBody(Body body) { + return [bodyPatterns: (appendBodyPatterns(body.clientValue))] + } + + private List> appendBodyPatterns(MatchingStrategy matchingStrategy) { + return [appendBodyPattern(matchingStrategy)] + } + + private List> appendBodyPatterns(List matchingStrategies) { + return matchingStrategies.collect { appendBodyPattern(it) } + } + + private List> appendBodyPatterns(GString gString) { + if (containsPattern(gString)) { + Object value = extractValue(gString, { DslProperty dslProperty -> dslProperty.clientValue }) + return appendBodyPatterns(extractReqexpMatching(value)) } - if (containsRegex(body)) { - return [bodyPatterns: [[matches: parseBody(convertJsonStructureToObjectUnderstandingStructure(body, - { it instanceof Pattern }, - { String json -> json.collect { - switch(it) { - case ('{'): return '\\{' - case ('}'): return '\\}' - default: return it - } - } .join('') - }, - { LinkedList list, String json -> - return json.replaceAll(TEMPORARY_PATTERN_HOLDER, { String a, String[] b -> list.pop() }) - } - ))]]] + return appendBodyPatterns(new MatchingStrategy(gString, getEqualsTypeFromContentTypeHeader())) + } + + private List> appendBodyPatterns(Object bodyValue) { + return appendBodyPatterns(new MatchingStrategy(bodyValue, MatchingStrategy.Type.EQUAL_TO)) + } + + private Map appendBodyPattern(MatchingStrategy matchingStrategy) { + MatchingStrategy.Type type = matchingStrategy.type + Object value= matchingStrategy.clientValue + ContentType contentType = recognizeContentTypeFromMatchingStrategy(type) + if (contentType == ContentType.UNKNOWN && type == MatchingStrategy.Type.EQUAL_TO) { + contentType = recognizeContentTypeFromContent(value) + type = getEqualsTypeFromContentType(contentType) } - return [bodyPatterns: [[equalTo: parseBody(body)]]] + Map result = [(type.name): parseBody(value, contentType)] + if (type == MatchingStrategy.Type.EQUAL_TO_JSON && matchingStrategy.jsonCompareMode) { + return result << [jsonCompareMode : (matchingStrategy.jsonCompareMode.toString())] + } + return result } - protected String parseBody(Object body) { - return body + private boolean containsPattern(GString bodyAsValue) { + return bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } + .find { it instanceof Pattern } } - boolean containsRegex(Object bodyObject) { - String bodyString = bodyObject as String - return (bodyString =~ /\^.*\$/).find() + private List extractReqexpMatching(Object responseBodyObject) { + def matchingStrategies = new ArrayList() + responseBodyObject.each { k, v -> + if (v instanceof List) { + v.each { + matchingStrategies.addAll(extractReqexpMatching((Map)it)) + } + } else { + matchingStrategies.add(new MatchingStrategy(/.*${k}":.?"?${v}"?.*/, MatchingStrategy.Type.MATCHING)) + } + } + return matchingStrategies } - boolean containsRegex(Map map) { - return map.values().any { it instanceof Pattern } + private MatchingStrategy.Type getEqualsTypeFromContentTypeHeader() { + return getEqualsTypeFromContentType(recognizeContentTypeFromHeader(request.headers)) } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy index b517150236..a17dad9420 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy @@ -2,16 +2,23 @@ package io.codearte.accurest.dsl import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.ClientResponse +import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.dsl.internal.Response +import io.codearte.accurest.util.ContentType + +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader @TypeChecked @PackageScope class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { + private final Request request private final Response response WiremockResponseStubStrategy(GroovyDsl groovyDsl) { this.response = groovyDsl.response + this.request = groovyDsl.request } @PackageScope @@ -27,6 +34,12 @@ class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { private Map appendBody(ClientResponse response) { Object body = response?.body?.clientValue - return body != null ? [body: parseBody(body)] : [:] + ContentType contentType = recognizeContentTypeFromHeader(response.headers) + if (contentType == ContentType.UNKNOWN) { + contentType = recognizeContentTypeFromContent(body) + } + return body != null ? [body: parseBody(body, contentType)] : [:] } + + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy index 315135d939..df799d87f8 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy @@ -1,23 +1,16 @@ package io.codearte.accurest.dsl.internal -import groovy.json.JsonSlurper +import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -import io.codearte.accurest.util.JsonConverter -import org.codehaus.groovy.runtime.GStringImpl - -import java.util.regex.Matcher -import java.util.regex.Pattern @ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) +@CompileStatic class Body extends DslProperty { - private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') - private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' - Body(Map body) { - super(extractValue(body, {it.clientValue}), extractValue(body, {it.serverValue})) + super(extractValue(body, { DslProperty p -> p.clientValue}), extractValue(body, {DslProperty p -> p.serverValue})) } private static Map extractValue(Map body, Closure valueProvider) { @@ -26,8 +19,8 @@ class Body extends DslProperty { } as Map } - Body(List bodyAsList) { - super(bodyAsList.collect { it.clientValue }, bodyAsList.collect { it.serverValue }) + Body(List bodyAsList) { + super(bodyAsList.collect { DslProperty p -> p.clientValue }, bodyAsList.collect { DslProperty p -> p.serverValue }) } Body(Object bodyAsValue) { @@ -35,48 +28,16 @@ class Body extends DslProperty { } Body(GString bodyAsValue) { - super(extractValue(bodyAsValue, {it.clientValue}), extractValue(bodyAsValue, {it.serverValue})) + super(bodyAsValue, bodyAsValue) } Body(DslProperty bodyAsValue) { super(bodyAsValue.clientValue, bodyAsValue.serverValue) } - /** - * Due to the fact that we allow users to have a body with GString and different values inside - * we need to be prepared that they pass regexps around both on client and server side. - * - * In order to preserve the original JSON structure we need to convert the passed Regex patterns - * to a temporary string, then convert all to a legitimate JSON structure and then finally - * convert it back from string to a pattern. - * - * @param bodyAsValue - GString with passed values - * @param valueProvider - provider of values either for server or client side - * @return JSON structure with replaced client / server side parts - */ - private static Object extractValue(GString bodyAsValue, Closure valueProvider) { - GString gString = new GStringImpl(bodyAsValue.values.clone(), bodyAsValue.strings.clone()) - Object[] values = bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as Object[] - Object[] valuesWithRegexpsAsTransformedStrings = values.collect { - it instanceof Pattern ? String.format(JSON_VALUE_PATTERN_FOR_REGEX, it.toString()) : it - } as Object[] - def parsedJson = new JsonSlurper().parseText(new GStringImpl(valuesWithRegexpsAsTransformedStrings, gString.strings)) - return convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) + Body(MatchingStrategy matchingStrategy) { + super(matchingStrategy, matchingStrategy) } - private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) { - JsonConverter.transformValues(parsedJson, { Object value -> - if (value instanceof String) { - String string = (String) value - Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string) - if (matcher.matches()) { - String pattern = matcher[0][1] - return Pattern.compile(pattern) - } - return value - } - return value - }) - } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy index c385bb1939..e9093dc9aa 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy @@ -9,26 +9,39 @@ import groovy.transform.ToString; @CompileStatic class MatchingStrategy extends DslProperty { - Type type + Type type + JSONCompareMode jsonCompareMode - MatchingStrategy(Object value, Type type) { - super(value) - this.type = type - } + MatchingStrategy(Object value, Type type) { + this(value, type, null) + } - MatchingStrategy(DslProperty value, Type type) { - super(value.clientValue, value.serverValue) - this.type = type - } + MatchingStrategy(Object value, Type type, JSONCompareMode jsonCompareMode) { + super(value) + this.type = type + this.jsonCompareMode = jsonCompareMode + } - enum Type { - EQUAL_TO("equalTo"), CONTAINS("contains"), MATCHING("matches"), NOT_MATCHING("doesNotMatch") + MatchingStrategy(DslProperty value, Type type) { + this(value, type, null) + } - final String name + MatchingStrategy(DslProperty value, Type type, JSONCompareMode jsonCompareMode) { + super(value.clientValue, value.serverValue) + this.type = type + this.jsonCompareMode = jsonCompareMode + } - Type(name) { - this.name = name - } - } + enum Type { + + EQUAL_TO("equalTo"), CONTAINS("contains"), MATCHING("matches"), NOT_MATCHING("doesNotMatch"), + EQUAL_TO_JSON("equalToJson"), EQUAL_TO_XML("equalToXml") + + final String name + + Type(name) { + this.name = name + } + } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy index eedaf5654b..0a5d6233f2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy @@ -20,20 +20,4 @@ class QueryParameters { parameters << new QueryParameter(parameterName, parameterValue) } - MatchingStrategy equalTo(Object value) { - return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO) - } - - MatchingStrategy containing(Object value) { - return new MatchingStrategy(value, MatchingStrategy.Type.CONTAINS) - } - - MatchingStrategy matching(Object value) { - return new MatchingStrategy(value, MatchingStrategy.Type.MATCHING) - } - - MatchingStrategy notMatching(Object value) { - return new MatchingStrategy(value, MatchingStrategy.Type.NOT_MATCHING) - } - } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index dab8f873f2..67b9dde09f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -3,6 +3,7 @@ import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked +import groovy.xml.MarkupBuilder @TypeChecked @EqualsAndHashCode @@ -88,6 +89,10 @@ class Request extends Common { this.body = new Body(convertObjectsToDslProperties(body)) } + void body(DslProperty dslProperty) { + this.body = new Body(dslProperty) + } + void body(Object bodyAsValue) { this.body = new Body(bodyAsValue) } @@ -95,6 +100,51 @@ class Request extends Common { Body getBody() { return body } + + MatchingStrategy equalTo(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO) + } + + MatchingStrategy containing(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.CONTAINS) + } + + MatchingStrategy matching(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.MATCHING) + } + + MatchingStrategy notMatching(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.NOT_MATCHING) + } + + MatchingStrategy equalToXml(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_XML) + } + + MatchingStrategy equalToJson(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON) + } + + MatchingStrategy equalToJson(Object value, JSONCompareMode jsonCompareMode) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON) + } + + MatchingStrategy equalToJsonStrictly(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON, JSONCompareMode.STRICT) + } + + MatchingStrategy equalToJsonLeniently(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON, JSONCompareMode.LENIENT) + } + + MatchingStrategy equalToJsonNonExtensibly(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON, JSONCompareMode.NON_EXTENSIBLE) + } + + MatchingStrategy equalToJsonWithStrictOrder(Object value) { + return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON, JSONCompareMode.STRICT_ORDER) + } + } @CompileStatic diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy new file mode 100644 index 0000000000..142c93a945 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy @@ -0,0 +1,5 @@ +package io.codearte.accurest.util + +enum ContentType { + JSON, XML, UNKNOWN +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy new file mode 100644 index 0000000000..1a187595b9 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -0,0 +1,192 @@ +package io.codearte.accurest.util +import groovy.json.JsonException +import groovy.json.JsonSlurper +import groovy.transform.TypeChecked +import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.dsl.internal.Headers +import io.codearte.accurest.dsl.internal.MatchingStrategy +import org.codehaus.groovy.runtime.GStringImpl + +import java.util.regex.Matcher +import java.util.regex.Pattern + +import static org.apache.commons.lang3.StringEscapeUtils.escapeJson +import static org.apache.commons.lang3.StringEscapeUtils.escapeXml11 + +@TypeChecked +class ContentUtils { + + private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') + private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' + + /** + * Due to the fact that we allow users to have a body with GString and different values inside + * we need to be prepared that they pass regexps around both on client and server side. + * + * In order to preserve the original JSON structure we need to convert the passed Regex patterns + * to a temporary string, then convert all to a legitimate JSON structure and then finally + * convert it back from string to a pattern. + * + * @param bodyAsValue - GString with passed values + * @param valueProvider - provider of values either for server or client side + * @return JSON structure with replaced client / server side parts + */ + public static Object extractValue(GString bodyAsValue, ContentType contentType, Closure valueProvider) { + if (contentType == ContentType.JSON) { + return extractValueForJSON(bodyAsValue, valueProvider) + } + if (contentType == ContentType.XML) { + return extractValueForXML(bodyAsValue, valueProvider) + } + // else Brute force :( + try { + return extractValueForJSON(bodyAsValue, valueProvider) + } catch(JsonException e) { + // Not a JSON format + return extractValueForXML(bodyAsValue, valueProvider) + } + return bodyAsValue + } + + public static Object extractValue(GString bodyAsValue, Closure valueProvider) { + return extractValue(bodyAsValue, ContentType.UNKNOWN, valueProvider) + } + + private static Object extractValueForJSON(GString bodyAsValue, Closure valueProvider) { + GString transformedString = new GStringImpl( + bodyAsValue.values.collect { transformJSONStringValue(it, valueProvider) } as String[], + bodyAsValue.strings.clone() as String[] + ) + def parsedJson = new JsonSlurper().parseText(transformedString.toString()) + return convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) + } + + private static GStringImpl extractValueForXML(GString bodyAsValue, Closure valueProvider) { + return new GStringImpl( + bodyAsValue.values.collect { transformXMLStringValue(it, valueProvider) } as String[], + bodyAsValue.strings.clone() as String[] + ) + } + + private static String transformJSONStringValue(Object obj, Closure valueProvider) { + return obj.toString() + } + + private static String transformJSONStringValue(DslProperty dslProperty, Closure valueProvider) { + return transformJSONStringValue(valueProvider(dslProperty), valueProvider) + } + + private static String transformJSONStringValue(Pattern pattern, Closure valueProvider) { + return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern()) + } + + private static String transformXMLStringValue(Object obj, Closure valueProvider) { + return escapeXml11(obj.toString()) + } + + private static String transformXMLStringValue(DslProperty dslProperty, Closure valueProvider) { + return transformXMLStringValue(valueProvider(dslProperty), valueProvider) + } + + private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) { + JsonConverter.transformValues(parsedJson, { Object value -> + if (value instanceof String) { + String string = (String) value + Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string) + if (matcher.matches()) { + List val = matcher[0] as List + String pattern = val[1] + return Pattern.compile(pattern) + } + return value + } + return value + }) + } + + public static ContentType recognizeContentTypeFromHeader(Headers headers) { + String content = headers?.entries.find { it.name == "Content-Type" } ?.clientValue?.toString() + if (content?.endsWith("json")) { + return ContentType.JSON + } + if (content?.endsWith("xml")) { + return ContentType.XML + } + return ContentType.UNKNOWN + } + + public static MatchingStrategy.Type getEqualsTypeFromContentType(ContentType contentType) { + switch (contentType) { + case ContentType.JSON: + return MatchingStrategy.Type.EQUAL_TO_JSON + case ContentType.XML: + return MatchingStrategy.Type.EQUAL_TO_XML + } + return MatchingStrategy.Type.EQUAL_TO + } + + public static ContentType recognizeContentTypeFromContent(GString gstring) { + if (isJsonType(gstring)) { + return ContentType.JSON + } + if (isXmlType(gstring)) { + return ContentType.XML + } + return ContentType.UNKNOWN + } + + public static ContentType recognizeContentTypeFromContent(Map jsonMap) { + return ContentType.JSON + } + + public static ContentType recognizeContentTypeFromContent(List jsonList) { + return ContentType.JSON + } + + public static ContentType recognizeContentTypeFromContent(Object gstring) { + return ContentType.UNKNOWN + } + + public static boolean isJsonType(GString gstring) { + GString stringWithoutValues = new GStringImpl( + gstring.values.collect({ + it instanceof String || it instanceof GString ? it.toString() : escapeJson(it.toString()) + }) as Object[], + gstring.strings.clone() as String[] + ) + try { + new JsonSlurper().parseText(stringWithoutValues.toString()) + return true + } catch (JsonException e) { + // Not JSON + } + return false + } + + public static boolean isXmlType(GString gstring) { + GString stringWithoutValues = new GStringImpl( + gstring.values.collect({ + it instanceof String || it instanceof GString ? it.toString() : escapeXml11(it.toString()) + }) as Object[], + gstring.strings.clone() as String[] + ) + try { + new XmlSlurper().parseText(stringWithoutValues.toString()) + return true + } catch (Exception e) { + // Not XML + } + return false + } + + public static ContentType recognizeContentTypeFromMatchingStrategy(MatchingStrategy.Type type) { + switch (type) { + case MatchingStrategy.Type.EQUAL_TO_XML: + return ContentType.XML + case MatchingStrategy.Type.EQUAL_TO_JSON: + return ContentType.JSON + } + return ContentType.UNKNOWN + } + +} 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 c8767551b4..5f6cb74fab 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 @@ -181,7 +181,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { "urlPattern": "/[0-9]{2}", "bodyPatterns": [ { - "equalTo":"{\\"name\\":\\"Jan\\"}" + "equalToJson":"{\\"name\\":\\"Jan\\"}" } ] }, @@ -198,6 +198,314 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(wiremockStub) } + def 'should use equalToJson when body match is defined as map'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + url $(client(~/\/[0-9]{2}/), server('/12')) + body( + id: value( + client('123'), + server({ regex('[0-9]+') }) + ), + surname: $( + client('Kowalsky'), + server('Lewandowski') + ), + name: 'Jan', + created: $(client('2014-02-02 12:23:43'), server({ currentDate(it) })) + ) + } + response { + status 200 + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}", + "bodyPatterns": [ + { + "equalToJson": "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}" + } + ] + }, + "response": { + "status": 200, + } + } + ''') + and: + stubMappingIsValidWiremockStub(wiremockStub) + } + + def 'should use equalToJson when content type ends with json'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + headers { + header "Content-Type", "customtype/json" + } + body """ + { + "name": "Jan" + } + """ + } + response { + status 200 + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users", + "headers": { + "Content-Type": { + "equalTo": "customtype/json" + } + }, + "bodyPatterns": [ + { + "equalToJson":"{\\"name\\":\\"Jan\\"}" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def 'should use equalToXml when content type ends with xml'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + headers { + header "Content-Type", "customtype/xml" + } + body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + } + response { + status 200 + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users", + "headers": { + "Content-Type": { + "equalTo": "customtype/xml" + } + }, + "bodyPatterns": [ + { + "equalToXml":"Jozo<test>" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def 'should use equalToXml when content type is parsable xml'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + } + response { + status 200 + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users", + "bodyPatterns": [ + { + "equalToXml":"Jozo<test>" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def 'should support xml as a response body'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + } + response { + status 200 + body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users" + }, + "response": { + "status": 200, + "body":"Jozo<test>" + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def 'should use equalToJson compare mode'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + body equalToJsonWithStrictOrder('''{"name":"Jan"}''') + } + response { + status 200 + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users", + "bodyPatterns": [ + { + "equalToJson":"{\\"name\\":\\"Jan\\"}", + "jsonCompareMode":"STRICT_ORDER" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def 'should use equalToJson'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + body equalToJson('''{"name":"Jan"}''') + } + response { + status 200 + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users", + "bodyPatterns": [ + { + "equalToJson":"{\\"name\\":\\"Jan\\"}" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + + def 'should use equalToXml'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url "/users" + body equalToXml("""${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""") + } + response { + status 200 + } + } + when: + String json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "url": "/users", + "bodyPatterns": [ + { + "equalToXml":"Jozo<test>" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWiremockStub(json) + } + def 'should convert groovy dsl stub with regexp Body as String to wiremock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { @@ -232,9 +540,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { "method": "GET", "urlPattern": "/[0-9]{2}", "bodyPatterns": [ - { - "matches":"\\\\{\\"personalId\\":\\"^[0-9]{11}$\\"\\\\}" - } + {"matches": ".*personalId\\":.?\\"?^[0-9]{11}$\\"?.*"} ] }, "response": { @@ -294,9 +600,8 @@ class WiremockGroovyDslSpec extends WiremockSpec { }, "url": "/fraudcheck", "bodyPatterns": [ - { - "matches": "\\\\{\\"clientPesel\\":\\"[0-9]{10}\\",\\"loanAmount\\":123.123\\\\}" - } + {"matches": ".*clientPesel\\":.?\\"?[0-9]{10}\\"?.*"}, + {"matches": ".*loanAmount\\":.?\\"?123.123\\"?.*"} ] }, "response": { @@ -427,78 +732,78 @@ class WiremockGroovyDslSpec extends WiremockSpec { def "should generate request with urlPath for client side"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method 'GET' - urlPath $(client("boxes"), server("items")) - } - response { - status 200 - } - } - when: - def json = toWiremockClientJsonStub(groovyDsl) - then: - parseJson(json) == parseJson(''' - { - "request": { - "method": "GET", - "urlPath": "boxes" - }, - "response": { - "status": 200, + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPath $(client("boxes"), server("items")) + } + response { + status 200 } } - ''') + when: + def json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "urlPath": "boxes" + }, + "response": { + "status": 200, + } + } + ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWiremockStub(json) } def "should generate simple request with urlPath for client side"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method 'GET' - urlPath "boxes" - } - response { - status 200 - } - } - when: - def json = toWiremockClientJsonStub(groovyDsl) - then: - parseJson(json) == parseJson(''' - { - "request": { - "method": "GET", - "urlPath": "boxes" - }, - "response": { - "status": 200, + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPath "boxes" + } + response { + status 200 } } - ''') + when: + def json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "urlPath": "boxes" + }, + "response": { + "status": 200, + } + } + ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWiremockStub(json) } def "should not allow regexp in url for server value"() { when: - GroovyDsl.make { - request { - method 'GET' - url(regex(/users\/[0-9]*/)) { - queryParameters { - parameter 'age': notMatching("^\\w*\$") - parameter 'name': matching("Denis.*") + GroovyDsl.make { + request { + method 'GET' + url(regex(/users\/[0-9]*/)) { + queryParameters { + parameter 'age': notMatching("^\\w*\$") + parameter 'name': matching("Denis.*") + } } } + response { + status 200 + } } - response { - status 200 - } - } then: def e = thrown(IllegalStateException) e.message.contains "Url can't be a pattern for the server side" @@ -547,44 +852,44 @@ class WiremockGroovyDslSpec extends WiremockSpec { def "should generate request with url and queryParameters for client side"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method 'GET' - url($(client(regex(/users\/[0-9]*/)), server("users/123"))) { - queryParameters { - parameter 'age': $(client(notMatching("^\\w*\$")), server(10)) - parameter 'name': $(client(matching("Denis.*")), server("Denis")) + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + url($(client(regex(/users\/[0-9]*/)), server("users/123"))) { + queryParameters { + parameter 'age': $(client(notMatching("^\\w*\$")), server(10)) + parameter 'name': $(client(matching("Denis.*")), server("Denis")) + } } } + response { + status 200 + } } - response { - status 200 - } - } when: - def json = toWiremockClientJsonStub(groovyDsl) + def json = toWiremockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' - { - "request": { - "method": "GET", - "urlPattern": "users/[0-9]*", - "queryParameters": { - "age": { - "doesNotMatch": "^\\\\w*$" - }, - "name": { - "matches": "Denis.*" - } + parseJson(json) == parseJson(''' + { + "request": { + "method": "GET", + "urlPattern": "users/[0-9]*", + "queryParameters": { + "age": { + "doesNotMatch": "^\\\\w*$" + }, + "name": { + "matches": "Denis.*" + } + } + }, + "response": { + "status": 200, } - }, - "response": { - "status": 200, } - } - ''') + ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWiremockStub(json) } def "should generate stub with some headers section for client side"() { @@ -622,6 +927,74 @@ class WiremockGroovyDslSpec extends WiremockSpec { ''') } + def 'should convert groovy dsl stub with rich tree Body as String to wiremock stub for the client side'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('GET') + url $(client(~/\/[0-9]{2}/), server('/12')) + body """\ + { + "personalId": "${value(client(regex('[0-9]{11}')), server('57593728525'))}", + "firstName": "${value(client(regex('.*')), server('Bruce'))}", + "lastName": "${value(client(regex('.*')), server('Lee'))}", + "birthDate": "${value(client(regex('[0-9]{4}-[0-9]{2}-[0-9]{2}')), server('1985-12-12'))}", + "errors": [ + { + "propertyName": "${value(client(regex('[0-9]{2}')), server('04'))}", + "providerValue": "Test" + }, + { + "propertyName": "${value(client(regex('[0-9]{2}')), server('08'))}", + "providerValue": "Test" + } + ] + } + """ + } + response { + status 200 + body("""\ + { + "name": "Jan" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + { + "request": { + "method": "GET", + "urlPattern": "/[0-9]{2}", + "bodyPatterns": [ + {"matches": ".*birthDate\\":.?\\"?[0-9]{4}-[0-9]{2}-[0-9]{2}\\"?.*"}, + {"matches": ".*propertyName\\":.?\\"?[0-9]{2}\\"?.*"}, + {"matches": ".*providerValue\\":.?\\"?Test\\"?.*"}, + {"matches": ".*propertyName\\":.?\\"?[0-9]{2}\\"?.*"}, + {"matches": ".*providerValue\\":.?\\"?Test\\"?.*"}, + {"matches": ".*firstName\\":.?\\"?.*\\"?.*"}, + {"matches": ".*lastName\\":.?\\"?.*\\"?.*"}, + {"matches": ".*personalId\\":.?\\"?[0-9]{11}\\"?.*"} + ] + }, + "response": { + "status": 200, + "body": "{\\"name\\":\\"Jan\\"}", + "headers": { + "Content-Type": "text/plain" + } + } + } + ''') + } + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy index 796e603c11..ab1133c9ae 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy @@ -5,7 +5,7 @@ import spock.lang.Specification import java.util.regex.Pattern -class WiremockSpec extends Specification { +abstract class WiremockSpec extends Specification { void stubMappingIsValidWiremockStub(String mappingDefinition) { StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) 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 e2ee36959d..96cabca538 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 @@ -52,7 +52,7 @@ class BasicFunctionalSpec extends IntegrationSpec { }, "url": "/api/12", "bodyPatterns": [ - { "equalTo": "[{\\"text\\":\\"Gonna see you at Warsaw\\"}]" } + { "equalToJson": "[{\\"text\\":\\"Gonna see you at Warsaw\\"}]" } ] }, "response": { From 69e5020e3514dee6ee3a32ba79f5e20d8894c1f2 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 15 Jun 2015 16:45:52 +0200 Subject: [PATCH 160/719] [#82] Fixed wrong request creation when having list in a map --- .../builder/SpockMethodBodyBuilder.groovy | 15 ++++++++--- .../accurest/util/ContentUtils.groovy | 13 ++++++++-- .../builder/SpockMethodBuilderSpec.groovy | 26 +++++++++++++++++-- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 544abb98b1..d569204b10 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -12,6 +12,7 @@ import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.dsl.internal.Response import io.codearte.accurest.dsl.internal.UrlPath import io.codearte.accurest.util.ContentType +import io.codearte.accurest.util.JsonConverter import java.util.regex.Pattern @@ -42,10 +43,7 @@ class SpockMethodBodyBuilder { addLine(".header('${header.name}', '${header.serverValue}')") } if (request.body) { - Object bodyValue = request.body.serverValue - if (bodyValue instanceof GString) { - bodyValue = extractValue(bodyValue, {DslProperty dslProperty -> dslProperty.serverValue}) - } + Object bodyValue = extractServerValueFromBody(request.body.serverValue) String matches = new JsonOutput().toJson(bodyValue) addLine(".body('$matches')") } @@ -97,6 +95,15 @@ class SpockMethodBodyBuilder { } } + private Object extractServerValueFromBody(bodyValue) { + if (bodyValue instanceof GString) { + bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) + } else { + bodyValue = JsonConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) + } + return bodyValue + } + private String buildUrl(Request request) { if (request.url) return request.url.serverValue; diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 1a187595b9..6cab8d76fd 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.util import groovy.json.JsonException import groovy.json.JsonSlurper import groovy.transform.TypeChecked +import groovy.util.logging.Slf4j import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.Headers import io.codearte.accurest.dsl.internal.MatchingStrategy @@ -14,6 +15,7 @@ import static org.apache.commons.lang3.StringEscapeUtils.escapeJson import static org.apache.commons.lang3.StringEscapeUtils.escapeXml11 @TypeChecked +@Slf4j class ContentUtils { private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') @@ -40,12 +42,19 @@ class ContentUtils { } // else Brute force :( try { + log.debug("No content type provided so trying to parse as JSON") return extractValueForJSON(bodyAsValue, valueProvider) } catch(JsonException e) { // Not a JSON format - return extractValueForXML(bodyAsValue, valueProvider) + log.debug("Failed to parse as JSON - trying to parse as XML", e) + try { + return extractValueForXML(bodyAsValue, valueProvider) + } catch (Exception exception) { + log.debug("No content type provided and failed to parse as XML - returning the value back to the user", exception) + return bodyAsValue + } } - return bodyAsValue + } public static Object extractValue(GString bodyAsValue, Closure valueProvider) { 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 index a2d03358a2..d8bfefcf5e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -34,7 +34,7 @@ class SpockMethodBuilderSpec extends Specification { } @Issue("#79") - def "should generate assertions for simple response body constructed from map"() { + def "should generate assertions for simple response body constructed from map with a list"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -62,6 +62,29 @@ class SpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") } + @Issue("#82") + def "should generate proper request when body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body ( + items: ['HOP'] + ) + } + response { + status 200 + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(".body('{\"items\":[\"HOP\"]}')") + } + def "should generate assertions for array in response body"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -236,5 +259,4 @@ class SpockMethodBuilderSpec extends Specification { spockTest.contains('responseBody.property1 == "a"') spockTest.contains('responseBody.property2 == "b"') } - } From 67f9e76d7df8c5f08a739bcf769c41cf4e6167cb Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Mon, 15 Jun 2015 17:36:19 +0200 Subject: [PATCH 161/719] Remove Json matching --- .../accurest/dsl/internal/Request.groovy | 20 ----------- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 36 ------------------- 2 files changed, 56 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 67b9dde09f..1ed604d4fb 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -125,26 +125,6 @@ class Request extends Common { return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON) } - MatchingStrategy equalToJson(Object value, JSONCompareMode jsonCompareMode) { - return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON) - } - - MatchingStrategy equalToJsonStrictly(Object value) { - return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON, JSONCompareMode.STRICT) - } - - MatchingStrategy equalToJsonLeniently(Object value) { - return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON, JSONCompareMode.LENIENT) - } - - MatchingStrategy equalToJsonNonExtensibly(Object value) { - return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON, JSONCompareMode.NON_EXTENSIBLE) - } - - MatchingStrategy equalToJsonWithStrictOrder(Object value) { - return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON, JSONCompareMode.STRICT_ORDER) - } - } @CompileStatic 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 5f6cb74fab..c066f4a9cc 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 @@ -400,42 +400,6 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(json) } - def 'should use equalToJson compare mode'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method 'GET' - url "/users" - body equalToJsonWithStrictOrder('''{"name":"Jan"}''') - } - response { - status 200 - } - } - when: - String json = toWiremockClientJsonStub(groovyDsl) - then: - parseJson(json) == parseJson(''' - { - "request": { - "method": "GET", - "url": "/users", - "bodyPatterns": [ - { - "equalToJson":"{\\"name\\":\\"Jan\\"}", - "jsonCompareMode":"STRICT_ORDER" - } - ] - }, - "response": { - "status": 200 - } - } - ''') - and: - stubMappingIsValidWiremockStub(json) - } - def 'should use equalToJson'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From 920d6fa1e6d7063d2192e65a878134eddaef658d Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 16 Jun 2015 14:08:58 +0200 Subject: [PATCH 162/719] Raised the version of gradle-nexus-staging-plugin to 0.5.3. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8000423e6c..2ad0eb7a0c 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { } dependencies { classpath "pl.allegro.tech.build:axion-release-plugin:1.2.2" - classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.1" + classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.3" } } From ce2d4093d03dff399bef4cafa0d810791b7bce2a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 16 Jun 2015 18:51:03 +0200 Subject: [PATCH 163/719] [#86] Fixed issue with Gstring, wiremock and regexp --- .../dsl/WiremockRequestStubStrategy.groovy | 16 +++--- .../accurest/dsl/WiremockGroovyDslSpec.groovy | 49 +++++++++++++++++++ 2 files changed, 59 insertions(+), 6 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index f9bc9bdc23..ea0b6b4a9f 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -131,13 +131,17 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { private List extractReqexpMatching(Object responseBodyObject) { def matchingStrategies = new ArrayList() - responseBodyObject.each { k, v -> - if (v instanceof List) { - v.each { - matchingStrategies.addAll(extractReqexpMatching((Map)it)) + if (responseBodyObject instanceof GString) { + return [new MatchingStrategy(responseBodyObject, MatchingStrategy.Type.MATCHING)] + } else if (responseBodyObject instanceof Map) { + responseBodyObject.each { k, v -> + if (v instanceof List) { + v.each { + matchingStrategies.addAll(extractReqexpMatching((Map)it)) + } + } else { + matchingStrategies.add(new MatchingStrategy(/.*${k}":.?"?${v}"?.*/, MatchingStrategy.Type.MATCHING)) } - } else { - matchingStrategies.add(new MatchingStrategy(/.*${k}":.?"?${v}"?.*/, MatchingStrategy.Type.MATCHING)) } } return matchingStrategies 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 c066f4a9cc..80540ec70d 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 @@ -101,6 +101,55 @@ class WiremockGroovyDslSpec extends WiremockSpec { stubMappingIsValidWiremockStub(wiremockStub) } + @Issue("#86") + def 'should convert groovy dsl stub with GString and regexp'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('POST') + url('/ws/payments') + headers { + header("Content-Type": 'application/x-www-form-urlencoded') + } + body("""paymentType=INCOMING&transferType=BANK&amount=${value(client(regex('[0-9]{3}\\.[0-9]{2}')), server(500.00))}&bookingDate=${value(client(regex('[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])')), server('2015-05-18'))}""") + } + response { + status 204 + body( + paymentId: value(client('4'), server(regex('[1-9][0-9]*'))), + foundExistingPayment: false + ) + } + } + when: + String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + then: + new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' +{ + "request": { + "method": "POST", + "headers": { + "Content-Type": { + "equalTo": "application/x-www-form-urlencoded" + } + }, + "url": "/ws/payments", + "bodyPatterns": [ + { + "matches": "paymentType=INCOMING&transferType=BANK&amount=[0-9]{3}\\\\.[0-9]{2}&bookingDate=[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])" + } + ] + }, + "response": { + "status": 204, + "body": "{\\"paymentId\\":\\"4\\",\\"foundExistingPayment\\":false}" + } +} +''') + and: + stubMappingIsValidWiremockStub(wiremockStub) + } + def 'should convert groovy dsl stub with Body as String to wiremock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From 5e83337ad34bc5f0edc4ca1e04b5791a003ed5a4 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 17 Jun 2015 11:55:44 +0200 Subject: [PATCH 164/719] Release version: 0.6.7 [ci skip] From 3755f530311a414df718451c52f87f505a0400b6 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 18 Jun 2015 12:53:28 +0200 Subject: [PATCH 165/719] Caused by JsonOutput().toJson() Added trimming of additional quotes. --- .../builder/SpockMethodBodyBuilder.groovy | 280 ++++++----- .../builder/SpockMethodBuilderSpec.groovy | 453 +++++++++--------- 2 files changed, 378 insertions(+), 355 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index d569204b10..d42350386b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -3,175 +3,173 @@ package io.codearte.accurest.builder import groovy.json.JsonOutput import groovy.transform.PackageScope 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.QueryParameter -import io.codearte.accurest.dsl.internal.Request -import io.codearte.accurest.dsl.internal.Response -import io.codearte.accurest.dsl.internal.UrlPath +import io.codearte.accurest.dsl.internal.* import io.codearte.accurest.util.ContentType import io.codearte.accurest.util.JsonConverter import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.extractValue -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent +import static io.codearte.accurest.util.ContentUtils.* /** * @author Jakub Kubrynski */ @PackageScope class SpockMethodBodyBuilder { - private final GroovyDsl stubDefinition + private final GroovyDsl stubDefinition - SpockMethodBodyBuilder(GroovyDsl stubDefinition) { - this.stubDefinition = stubDefinition - } + SpockMethodBodyBuilder(GroovyDsl stubDefinition) { + this.stubDefinition = stubDefinition + } - void appendTo(BlockBuilder blockBuilder) { - Request request = stubDefinition.request - Response response = stubDefinition.response - blockBuilder.with { - startBlock() - addLine('given:').startBlock() - addLine('def request = given()') - indent() - request.headers?.collect { Header header -> - addLine(".header('${header.name}', '${header.serverValue}')") - } - if (request.body) { - Object bodyValue = extractServerValueFromBody(request.body.serverValue) - String matches = new JsonOutput().toJson(bodyValue) - addLine(".body('$matches')") - } + void appendTo(BlockBuilder blockBuilder) { + Request request = stubDefinition.request + Response response = stubDefinition.response + blockBuilder.with { + startBlock() + addLine('given:').startBlock() + addLine('def request = given()') + indent() + request.headers?.collect { Header header -> + addLine(".header('${header.name}', '${header.serverValue}')") + } + if (request.body) { + Object bodyValue = extractServerValueFromBody(request.body.serverValue) + String matches = trimRepeatedQuotes(new JsonOutput().toJson(bodyValue)) + addLine(".body('$matches')") + } - unindent().endBlock().addEmptyLine() + unindent().endBlock().addEmptyLine() - addLine('when:').startBlock() - addLine('def response = given().spec(request)') - indent() + addLine('when:').startBlock() + addLine('def response = given().spec(request)') + indent() - String url = buildUrl(request) - String method = request.method.serverValue.toLowerCase() + String url = buildUrl(request) + String method = request.method.serverValue.toLowerCase() - blockBuilder.addLine(/.${method}("$url")/) - unindent().endBlock().addEmptyLine() + blockBuilder.addLine(/.${method}("$url")/) + unindent().endBlock().addEmptyLine() - addLine('then:').startBlock() - addLine("response.statusCode == $response.status.serverValue") + addLine('then:').startBlock() + addLine("response.statusCode == $response.status.serverValue") - response.headers?.collect { Header header -> - addLine("response.header('$header.name') == '$header.serverValue'") - } - if (response.body) { - endBlock() - addLine('and:').startBlock() - def responseBody = response.body.serverValue - ContentType contentType = recognizeContentTypeFromHeader(response.headers) - if (contentType == ContentType.UNKNOWN) { - contentType = recognizeContentTypeFromContent(responseBody) - } - if (responseBody instanceof GString) { - responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) - } - if (contentType == ContentType.JSON) { - addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') - if (responseBody instanceof List) { - processArrayElements(responseBody, "", blockBuilder) - } else { - processMapElement(responseBody, blockBuilder, "") - } - } else if (contentType == ContentType.XML) { - addLine('def responseBody = new XmlSlurper().parseText(response.body.asString())') - // TODO xml validation - } - } - endBlock() + response.headers?.collect { Header header -> + addLine("response.header('$header.name') == '$header.serverValue'") + } + if (response.body) { + endBlock() + addLine('and:').startBlock() + def responseBody = response.body.serverValue + ContentType contentType = recognizeContentTypeFromHeader(response.headers) + if (contentType == ContentType.UNKNOWN) { + contentType = recognizeContentTypeFromContent(responseBody) + } + if (responseBody instanceof GString) { + responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) + } + if (contentType == ContentType.JSON) { + addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') + if (responseBody instanceof List) { + processArrayElements(responseBody, "", blockBuilder) + } else { + processMapElement(responseBody, blockBuilder, "") + } + } else if (contentType == ContentType.XML) { + addLine('def responseBody = new XmlSlurper().parseText(response.body.asString())') + // TODO xml validation + } + } + endBlock() - endBlock() - } - } + endBlock() + } + } - private Object extractServerValueFromBody(bodyValue) { - if (bodyValue instanceof GString) { - bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) - } else { - bodyValue = JsonConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) - } - return bodyValue - } + static String trimRepeatedQuotes(String toTrim) { + if (toTrim.startsWith('"')) { + return toTrim.replaceAll('"', '') + } + return toTrim + } - private String buildUrl(Request request) { - if (request.url) - return request.url.serverValue; - if (request.urlPath) - return buildUrlFromUrlPath(request.urlPath) - throw new IllegalStateException("URL is not set!") - } + private Object extractServerValueFromBody(bodyValue) { + if (bodyValue instanceof GString) { + bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) + } else { + bodyValue = JsonConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) + } + return bodyValue + } - private String buildUrlFromUrlPath(UrlPath urlPath) { - String params = urlPath.queryParameters.parameters.inject([]) { result, param -> - result << "${param.name}=${URLEncoder.encode(resolveParamValue(param).toString(), "UTF8")}" - }.join('&') - return "$urlPath.serverValue?$params" - } + private String buildUrl(Request request) { + if (request.url) + return request.url.serverValue; + if (request.urlPath) + return buildUrlFromUrlPath(request.urlPath) + throw new IllegalStateException("URL is not set!") + } - private String resolveParamValue(QueryParameter param) { - resolveParamValue(param.serverValue) - } + private String buildUrlFromUrlPath(UrlPath urlPath) { + String params = urlPath.queryParameters.parameters.inject([]) { result, param -> + result << "${param.name}=${URLEncoder.encode(resolveParamValue(param).toString(), "UTF8")}" + }.join('&') + return "$urlPath.serverValue?$params" + } - private String resolveParamValue(Object value) { - value.toString() - } + private String resolveParamValue(QueryParameter param) { + resolveParamValue(param.serverValue) + } - private String resolveParamValue(MatchingStrategy matchingStrategy) { - matchingStrategy.serverValue.toString() - } + private String resolveParamValue(Object value) { + value.toString() + } - private void processBodyElement(BlockBuilder blockBuilder, String property, def value) { - if (value instanceof String) { - if (value.startsWith('$')) { - value = value.substring(1).replaceAll('\\$value', "responseBody$property") - blockBuilder.addLine(value) - } else { - blockBuilder.addLine("responseBody$property == \"${value}\"") - } - } else if (value instanceof Map) { - processMapElement(value, blockBuilder, property) - }else if (value instanceof Map.Entry) { - processEntryElement(blockBuilder, property, value) - } else if (value instanceof List) { - processArrayElements(value, property, blockBuilder) - } else if (value instanceof Pattern) { - blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") - } else if (value instanceof DslProperty) { - processBodyElement(blockBuilder, property, value.serverValue) - } else if (value instanceof ExecutionProperty) { - ExecutionProperty exec = (ExecutionProperty) value - blockBuilder.addLine("${exec.insertValue("responseBody$property")}") - } else { - blockBuilder.addLine("responseBody$property == ${value}") - } - } + private String resolveParamValue(MatchingStrategy matchingStrategy) { + matchingStrategy.serverValue.toString() + } - private void processMapElement(def value, BlockBuilder blockBuilder, String property) { - value.each { entry -> processEntryElement(blockBuilder, property, entry) } - } + private void processBodyElement(BlockBuilder blockBuilder, String property, def value) { + if (value instanceof String) { + if (value.startsWith('$')) { + value = value.substring(1).replaceAll('\\$value', "responseBody$property") + blockBuilder.addLine(value) + } else { + blockBuilder.addLine("responseBody$property == \"${value}\"") + } + } else if (value instanceof Map) { + processMapElement(value, blockBuilder, property) + } else if (value instanceof Map.Entry) { + processEntryElement(blockBuilder, property, value) + } else if (value instanceof List) { + processArrayElements(value, property, blockBuilder) + } else if (value instanceof Pattern) { + blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") + } else if (value instanceof DslProperty) { + processBodyElement(blockBuilder, property, value.serverValue) + } else if (value instanceof ExecutionProperty) { + ExecutionProperty exec = (ExecutionProperty) value + blockBuilder.addLine("${exec.insertValue("responseBody$property")}") + } else { + blockBuilder.addLine("responseBody$property == ${value}") + } + } - private def processEntryElement(BlockBuilder blockBuilder, String property, def entry) { - return processBodyElement(blockBuilder, property + "." + entry.key, entry.value) - } + private void processMapElement(def value, BlockBuilder blockBuilder, String property) { + value.each { entry -> processEntryElement(blockBuilder, property, entry) } + } - private void processArrayElements(List responseBody, String property, BlockBuilder blockBuilder) { - responseBody.eachWithIndex { - listElement, listIndex -> - listElement.each { entry -> - String prop = "$property[$listIndex]" ?: '' - processBodyElement(blockBuilder, prop, entry) - } - } - } + private def processEntryElement(BlockBuilder blockBuilder, String property, def entry) { + return processBodyElement(blockBuilder, property + "." + entry.key, entry.value) + } + + private void processArrayElements(List responseBody, String property, BlockBuilder blockBuilder) { + responseBody.eachWithIndex { + listElement, listIndex -> + listElement.each { entry -> + String prop = "$property[$listIndex]" ?: '' + processBodyElement(blockBuilder, prop, entry) + } + } + } } 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 index d8bfefcf5e..35135dff7b 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -9,254 +9,279 @@ import spock.lang.Specification */ 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 """{ + 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\"") - } + } + } + 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\"") + } - @Issue("#79") - def "should generate assertions for simple response body constructed from map with a list"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body ( - property1: 'a', - property2: [ - [a: 'sth'], - [b: 'sthElse'] - ] - ) - } - } - 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[0].a == \"sth\"") - blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") - } + @Issue("#79") + def "should generate assertions for simple response body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + 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[0].a == \"sth\"") + blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") + } - @Issue("#82") - def "should generate proper request when body constructed from map with a list"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - body ( - items: ['HOP'] - ) - } - response { - status 200 - } - } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains(".body('{\"items\":[\"HOP\"]}')") - } + @Issue("#82") + def "should generate proper request when body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + items: ['HOP'] + ) + } + response { + status 200 + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(".body('{\"items\":[\"HOP\"]}')") + } - def "should generate assertions for array in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body """[ + @Issue("#88") + def "should generate proper request when body constructed from GString"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + "property1=VAL1" + ) + } + response { + status 200 + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(".body('property1=VAL1')") + } + + 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\"") - } + } + } + 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 """{ + 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\"") - } + } + } + 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 '''\ + 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\"") - } + } + } + 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\"") + } - def "should generate regex assertions for map objects in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property1: "a", - property2: value( - client('123'), - server(regex('[0-9]{3}')) - ) - ) - headers { - header('Content-Type': 'application/json') + def "should generate regex assertions for map objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: "a", + property2: value( + client('123'), + server(regex('[0-9]{3}')) + ) + ) + headers { + header('Content-Type': 'application/json') - } + } - } - } - 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") - } + } + } + 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + } - def "should generate regex assertions for string objects in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( """{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") - headers { - header('Content-Type': 'application/json') + def "should generate regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + headers { + header('Content-Type': 'application/json') - } + } - } - } - 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") - } + } + } + 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + } - def "should generate a call with an url path and query parameters"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'GET' - urlPath('/users') { - queryParameters { - parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) - parameter 'offset': $(client(containing("20")), server(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) - parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) - parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) - } - } - } - response { - status 200 - body """ + def "should generate a call with an url path and query parameters"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + } + } + } + response { + status 200 + body """ { "property1": "a", "property2": "b" } """ - } - } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() - then: - spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov")') - spockTest.contains('responseBody.property1 == "a"') - spockTest.contains('responseBody.property2 == "b"') - } + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov")') + spockTest.contains('responseBody.property1 == "a"') + spockTest.contains('responseBody.property2 == "b"') + } + + } From 84520dafa5f79e2cbc3a1eb77024d9bdec7a4477 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 18 Jun 2015 12:56:10 +0200 Subject: [PATCH 166/719] Changed code formatting in modified classes to Codearte style. --- .../builder/SpockMethodBodyBuilder.groovy | 285 ++++++----- .../builder/SpockMethodBuilderSpec.groovy | 472 +++++++++--------- 2 files changed, 383 insertions(+), 374 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index d42350386b..e3c0b1388b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -3,173 +3,182 @@ package io.codearte.accurest.builder import groovy.json.JsonOutput import groovy.transform.PackageScope import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.dsl.internal.* +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.QueryParameter +import io.codearte.accurest.dsl.internal.Request +import io.codearte.accurest.dsl.internal.Response +import io.codearte.accurest.dsl.internal.UrlPath import io.codearte.accurest.util.ContentType import io.codearte.accurest.util.JsonConverter import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.* +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 Jakub Kubrynski */ @PackageScope class SpockMethodBodyBuilder { - private final GroovyDsl stubDefinition + private final GroovyDsl stubDefinition - SpockMethodBodyBuilder(GroovyDsl stubDefinition) { - this.stubDefinition = stubDefinition - } + SpockMethodBodyBuilder(GroovyDsl stubDefinition) { + this.stubDefinition = stubDefinition + } - void appendTo(BlockBuilder blockBuilder) { - Request request = stubDefinition.request - Response response = stubDefinition.response - blockBuilder.with { - startBlock() - addLine('given:').startBlock() - addLine('def request = given()') - indent() - request.headers?.collect { Header header -> - addLine(".header('${header.name}', '${header.serverValue}')") - } - if (request.body) { - Object bodyValue = extractServerValueFromBody(request.body.serverValue) - String matches = trimRepeatedQuotes(new JsonOutput().toJson(bodyValue)) - addLine(".body('$matches')") - } + void appendTo(BlockBuilder blockBuilder) { + Request request = stubDefinition.request + Response response = stubDefinition.response + blockBuilder.with { + startBlock() + addLine('given:').startBlock() + addLine('def request = given()') + indent() + request.headers?.collect { Header header -> + addLine(".header('${header.name}', '${header.serverValue}')") + } + if (request.body) { + Object bodyValue = extractServerValueFromBody(request.body.serverValue) + String matches = trimRepeatedQuotes(new JsonOutput().toJson(bodyValue)) + addLine(".body('$matches')") + } - unindent().endBlock().addEmptyLine() + unindent().endBlock().addEmptyLine() - addLine('when:').startBlock() - addLine('def response = given().spec(request)') - indent() + addLine('when:').startBlock() + addLine('def response = given().spec(request)') + indent() - String url = buildUrl(request) - String method = request.method.serverValue.toLowerCase() + String url = buildUrl(request) + String method = request.method.serverValue.toLowerCase() - blockBuilder.addLine(/.${method}("$url")/) - unindent().endBlock().addEmptyLine() + blockBuilder.addLine(/.${method}("$url")/) + unindent().endBlock().addEmptyLine() - addLine('then:').startBlock() - addLine("response.statusCode == $response.status.serverValue") + addLine('then:').startBlock() + addLine("response.statusCode == $response.status.serverValue") - response.headers?.collect { Header header -> - addLine("response.header('$header.name') == '$header.serverValue'") - } - if (response.body) { - endBlock() - addLine('and:').startBlock() - def responseBody = response.body.serverValue - ContentType contentType = recognizeContentTypeFromHeader(response.headers) - if (contentType == ContentType.UNKNOWN) { - contentType = recognizeContentTypeFromContent(responseBody) - } - if (responseBody instanceof GString) { - responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) - } - if (contentType == ContentType.JSON) { - addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') - if (responseBody instanceof List) { - processArrayElements(responseBody, "", blockBuilder) - } else { - processMapElement(responseBody, blockBuilder, "") - } - } else if (contentType == ContentType.XML) { - addLine('def responseBody = new XmlSlurper().parseText(response.body.asString())') - // TODO xml validation - } - } - endBlock() + response.headers?.collect { Header header -> + addLine("response.header('$header.name') == '$header.serverValue'") + } + if (response.body) { + endBlock() + addLine('and:').startBlock() + def responseBody = response.body.serverValue + ContentType contentType = recognizeContentTypeFromHeader(response.headers) + if (contentType == ContentType.UNKNOWN) { + contentType = recognizeContentTypeFromContent(responseBody) + } + if (responseBody instanceof GString) { + responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) + } + if (contentType == ContentType.JSON) { + addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') + if (responseBody instanceof List) { + processArrayElements(responseBody, "", blockBuilder) + } else { + processMapElement(responseBody, blockBuilder, "") + } + } else if (contentType == ContentType.XML) { + addLine('def responseBody = new XmlSlurper().parseText(response.body.asString())') + // TODO xml validation + } + } + endBlock() - endBlock() - } - } + endBlock() + } + } - static String trimRepeatedQuotes(String toTrim) { - if (toTrim.startsWith('"')) { - return toTrim.replaceAll('"', '') - } - return toTrim - } + static String trimRepeatedQuotes(String toTrim) { + if (toTrim.startsWith('"')) { + return toTrim.replaceAll('"', '') + } + return toTrim + } - private Object extractServerValueFromBody(bodyValue) { - if (bodyValue instanceof GString) { - bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) - } else { - bodyValue = JsonConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) - } - return bodyValue - } + private Object extractServerValueFromBody(bodyValue) { + if (bodyValue instanceof GString) { + bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) + } else { + bodyValue = JsonConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) + } + return bodyValue + } - private String buildUrl(Request request) { - if (request.url) - return request.url.serverValue; - if (request.urlPath) - return buildUrlFromUrlPath(request.urlPath) - throw new IllegalStateException("URL is not set!") - } + private String buildUrl(Request request) { + if (request.url) + return request.url.serverValue; + if (request.urlPath) + return buildUrlFromUrlPath(request.urlPath) + throw new IllegalStateException("URL is not set!") + } - private String buildUrlFromUrlPath(UrlPath urlPath) { - String params = urlPath.queryParameters.parameters.inject([]) { result, param -> - result << "${param.name}=${URLEncoder.encode(resolveParamValue(param).toString(), "UTF8")}" - }.join('&') - return "$urlPath.serverValue?$params" - } + private String buildUrlFromUrlPath(UrlPath urlPath) { + String params = urlPath.queryParameters.parameters.inject([]) { result, param -> + result << "${param.name}=${URLEncoder.encode(resolveParamValue(param).toString(), "UTF8")}" + }.join('&') + return "$urlPath.serverValue?$params" + } - private String resolveParamValue(QueryParameter param) { - resolveParamValue(param.serverValue) - } + private String resolveParamValue(QueryParameter param) { + resolveParamValue(param.serverValue) + } - private String resolveParamValue(Object value) { - value.toString() - } + private String resolveParamValue(Object value) { + value.toString() + } - private String resolveParamValue(MatchingStrategy matchingStrategy) { - matchingStrategy.serverValue.toString() - } + private String resolveParamValue(MatchingStrategy matchingStrategy) { + matchingStrategy.serverValue.toString() + } - private void processBodyElement(BlockBuilder blockBuilder, String property, def value) { - if (value instanceof String) { - if (value.startsWith('$')) { - value = value.substring(1).replaceAll('\\$value', "responseBody$property") - blockBuilder.addLine(value) - } else { - blockBuilder.addLine("responseBody$property == \"${value}\"") - } - } else if (value instanceof Map) { - processMapElement(value, blockBuilder, property) - } else if (value instanceof Map.Entry) { - processEntryElement(blockBuilder, property, value) - } else if (value instanceof List) { - processArrayElements(value, property, blockBuilder) - } else if (value instanceof Pattern) { - blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") - } else if (value instanceof DslProperty) { - processBodyElement(blockBuilder, property, value.serverValue) - } else if (value instanceof ExecutionProperty) { - ExecutionProperty exec = (ExecutionProperty) value - blockBuilder.addLine("${exec.insertValue("responseBody$property")}") - } else { - blockBuilder.addLine("responseBody$property == ${value}") - } - } + private void processBodyElement(BlockBuilder blockBuilder, String property, def value) { + if (value instanceof String) { + if (value.startsWith('$')) { + value = value.substring(1).replaceAll('\\$value', "responseBody$property") + blockBuilder.addLine(value) + } else { + blockBuilder.addLine("responseBody$property == \"${value}\"") + } + } else if (value instanceof Map) { + processMapElement(value, blockBuilder, property) + } else if (value instanceof Map.Entry) { + processEntryElement(blockBuilder, property, value) + } else if (value instanceof List) { + processArrayElements(value, property, blockBuilder) + } else if (value instanceof Pattern) { + blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") + } else if (value instanceof DslProperty) { + processBodyElement(blockBuilder, property, value.serverValue) + } else if (value instanceof ExecutionProperty) { + ExecutionProperty exec = (ExecutionProperty) value + blockBuilder.addLine("${exec.insertValue("responseBody$property")}") + } else { + blockBuilder.addLine("responseBody$property == ${value}") + } + } - private void processMapElement(def value, BlockBuilder blockBuilder, String property) { - value.each { entry -> processEntryElement(blockBuilder, property, entry) } - } + private void processMapElement(def value, BlockBuilder blockBuilder, String property) { + value.each { entry -> processEntryElement(blockBuilder, property, entry) } + } - private def processEntryElement(BlockBuilder blockBuilder, String property, def entry) { - return processBodyElement(blockBuilder, property + "." + entry.key, entry.value) - } + private def processEntryElement(BlockBuilder blockBuilder, String property, def entry) { + return processBodyElement(blockBuilder, property + "." + entry.key, entry.value) + } - private void processArrayElements(List responseBody, String property, BlockBuilder blockBuilder) { - responseBody.eachWithIndex { - listElement, listIndex -> - listElement.each { entry -> - String prop = "$property[$listIndex]" ?: '' - processBodyElement(blockBuilder, prop, entry) - } - } - } + private void processArrayElements(List responseBody, String property, BlockBuilder blockBuilder) { + responseBody.eachWithIndex { + listElement, listIndex -> + listElement.each { entry -> + String prop = "$property[$listIndex]" ?: '' + processBodyElement(blockBuilder, prop, entry) + } + } + } } 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 index 35135dff7b..e9301d0c70 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -9,279 +9,279 @@ import spock.lang.Specification */ 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 """{ + 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\"") - } + } + } + 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\"") + } - @Issue("#79") - def "should generate assertions for simple response body constructed from map with a list"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property1: 'a', - property2: [ - [a: 'sth'], - [b: 'sthElse'] - ] - ) - } - } - 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[0].a == \"sth\"") - blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") - } + @Issue("#79") + def "should generate assertions for simple response body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + 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[0].a == \"sth\"") + blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") + } - @Issue("#82") - def "should generate proper request when body constructed from map with a list"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - body( - items: ['HOP'] - ) - } - response { - status 200 - } - } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains(".body('{\"items\":[\"HOP\"]}')") - } + @Issue("#82") + def "should generate proper request when body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + items: ['HOP'] + ) + } + response { + status 200 + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(".body('{\"items\":[\"HOP\"]}')") + } - @Issue("#88") - def "should generate proper request when body constructed from GString"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - body( - "property1=VAL1" - ) - } - response { - status 200 - } - } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains(".body('property1=VAL1')") - } + @Issue("#88") + def "should generate proper request when body constructed from GString"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + "property1=VAL1" + ) + } + response { + status 200 + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains(".body('property1=VAL1')") + } - def "should generate assertions for array in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body """[ + 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\"") - } + } + } + 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 """{ + 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\"") - } + } + } + 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 '''\ + 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\"") - } + } + } + 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\"") + } - def "should generate regex assertions for map objects in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property1: "a", - property2: value( - client('123'), - server(regex('[0-9]{3}')) - ) - ) - headers { - header('Content-Type': 'application/json') + def "should generate regex assertions for map objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: "a", + property2: value( + client('123'), + server(regex('[0-9]{3}')) + ) + ) + headers { + header('Content-Type': 'application/json') - } + } - } - } - 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") - } + } + } + 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + } - def "should generate regex assertions for string objects in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") - headers { - header('Content-Type': 'application/json') + def "should generate regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + headers { + header('Content-Type': 'application/json') - } + } - } - } - 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") - } + } + } + 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 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + } - def "should generate a call with an url path and query parameters"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'GET' - urlPath('/users') { - queryParameters { - parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) - parameter 'offset': $(client(containing("20")), server(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) - parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) - parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) - } - } - } - response { - status 200 - body """ + def "should generate a call with an url path and query parameters"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + } + } + } + response { + status 200 + body """ { "property1": "a", "property2": "b" } """ - } - } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() - then: - spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov")') - spockTest.contains('responseBody.property1 == "a"') - spockTest.contains('responseBody.property2 == "b"') - } + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov")') + spockTest.contains('responseBody.property1 == "a"') + spockTest.contains('responseBody.property2 == "b"') + } } From e2c956177878f035866a61d8a3dfb82a607463aa Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 18 Jun 2015 13:08:20 +0200 Subject: [PATCH 167/719] Changed method from static to private. --- .../io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index e3c0b1388b..4da97ee58b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -95,7 +95,7 @@ class SpockMethodBodyBuilder { } } - static String trimRepeatedQuotes(String toTrim) { + private String trimRepeatedQuotes(String toTrim) { if (toTrim.startsWith('"')) { return toTrim.replaceAll('"', '') } From f3773169b06b074f179d424c2bfd4650b108510b Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 18 Jun 2015 18:01:36 +0200 Subject: [PATCH 168/719] Removed unnecessary reference call. Changed the required version of apache-commons-lang3 for accurest-core to 3.3 as we use methods that were introduced in 3.3. --- .../plugin/GenerateWiremockClientStubsFromDslTask.groovy | 4 ++-- build.gradle | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy index 6a6f08f692..ab6f6473c1 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy @@ -17,8 +17,8 @@ class GenerateWiremockClientStubsFromDslTask extends ConventionTask { @TaskAction void generate() { - project.logger.info("Accurest Plugin: Invoking GroovyDSL to Wiremock client stubs conversion") - project.logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") + logger.info("Accurest Plugin: Invoking GroovyDSL to Wiremock client stubs conversion") + logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWiremockClientConverter(), getContractsDslDir(), getStubsOutputDir()) diff --git a/build.gradle b/build.gradle index 2ad0eb7a0c..3ae3d0e265 100644 --- a/build.gradle +++ b/build.gradle @@ -87,7 +87,7 @@ project(':accurest-core') { compile 'org.slf4j:slf4j-api:[1.6.0,)' compile 'org.codehaus.plexus:plexus-utils:[3.0.0,)' compile 'commons-io:commons-io:[2.0,)' - compile 'org.apache.commons:commons-lang3:[3.0,)' + compile 'org.apache.commons:commons-lang3:[3.3,)' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile 'com.github.tomakehurst:wiremock:1.53' From f74e86ce5d3f1d6cfa1c4666bfa11a78c9b266db Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 18 Jun 2015 18:44:57 +0200 Subject: [PATCH 169/719] [#86] Fixed the case when an exception is thrown for XML processing --- .../groovy/io/codearte/accurest/util/ContentUtils.groovy | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 6cab8d76fd..59b4d726ee 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -51,12 +51,19 @@ class ContentUtils { return extractValueForXML(bodyAsValue, valueProvider) } catch (Exception exception) { log.debug("No content type provided and failed to parse as XML - returning the value back to the user", exception) - return bodyAsValue + return extractValueForGString(bodyAsValue, valueProvider) } } } + private static GStringImpl extractValueForGString(GString bodyAsValue, Closure valueProvider) { + return new GStringImpl( + bodyAsValue.values.collect { it instanceof DslProperty ? valueProvider(it) : it } as String[], + bodyAsValue.strings.clone() as String[] + ) + } + public static Object extractValue(GString bodyAsValue, Closure valueProvider) { return extractValue(bodyAsValue, ContentType.UNKNOWN, valueProvider) } From 8b44fc046b004d37eff375f70a38c65658ee6d72 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Mon, 22 Jun 2015 18:21:16 +0200 Subject: [PATCH 170/719] Do not escape url values in spock tests --- .../io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy | 2 +- .../io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 4da97ee58b..cc35423d97 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -121,7 +121,7 @@ class SpockMethodBodyBuilder { private String buildUrlFromUrlPath(UrlPath urlPath) { String params = urlPath.queryParameters.parameters.inject([]) { result, param -> - result << "${param.name}=${URLEncoder.encode(resolveParamValue(param).toString(), "UTF8")}" + result << "${param.name}=${resolveParamValue(param).toString()}" }.join('&') return "$urlPath.serverValue?$params" } 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 index e9301d0c70..b38ec458b1 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -259,6 +259,7 @@ class SpockMethodBuilderSpec extends Specification { parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" } } } @@ -278,7 +279,7 @@ class SpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov")') + spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') spockTest.contains('responseBody.property1 == "a"') spockTest.contains('responseBody.property2 == "b"') } From 3778a66a2a61044c4dca9e976e71beb52eae821b Mon Sep 17 00:00:00 2001 From: The Gitter Badger Date: Thu, 25 Jun 2015 07:51:54 +0000 Subject: [PATCH 171/719] Added Gitter badge --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 7cead077d6..9420cca7a0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ Accurate REST ============= +[![Join the chat at https://gitter.im/Codearte/accurest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Codearte/accurest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + [![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 From 3370b2ee3c06af1db780c54428774a054e63e357 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 25 Jun 2015 09:53:39 +0200 Subject: [PATCH 172/719] Fixed the Gitter badge location --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 9420cca7a0..d379b16aa0 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,8 @@ Accurate REST ============= -[![Join the chat at https://gitter.im/Codearte/accurest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Codearte/accurest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - [![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) +[![Join the chat at https://gitter.im/Codearte/accurest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Codearte/accurest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Consumer Driven Contracts verifier for Java From 397617101c68bba0aeb8d0090c1f8502f67da8c3 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Mon, 22 Jun 2015 16:26:41 +0200 Subject: [PATCH 173/719] Generate JSON with full body --- .../dsl/WiremockRequestStubStrategy.groovy | 89 +++++++++++-------- .../accurest/util/RegexpBuilders.groovy | 72 +++++++++++++++ .../accurest/dsl/WiremockGroovyDslSpec.groovy | 73 ++++++++++++--- 3 files changed, 183 insertions(+), 51 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy index ea0b6b4a9f..a98088b672 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy @@ -1,5 +1,4 @@ package io.codearte.accurest.dsl - import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.internal.Body @@ -13,11 +12,12 @@ import io.codearte.accurest.util.ContentType import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.extractValue -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader import static io.codearte.accurest.util.ContentUtils.getEqualsTypeFromContentType import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromMatchingStrategy +import static io.codearte.accurest.util.RegexpBuilders.buildGStringRegexpMatch +import static io.codearte.accurest.util.RegexpBuilders.buildJSONRegexpMatch @TypeChecked @PackageScope @@ -93,58 +93,73 @@ class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { return [appendBodyPattern(matchingStrategy)] } - private List> appendBodyPatterns(List matchingStrategies) { - return matchingStrategies.collect { appendBodyPattern(it) } - } - - private List> appendBodyPatterns(GString gString) { - if (containsPattern(gString)) { - Object value = extractValue(gString, { DslProperty dslProperty -> dslProperty.clientValue }) - return appendBodyPatterns(extractReqexpMatching(value)) - } - return appendBodyPatterns(new MatchingStrategy(gString, getEqualsTypeFromContentTypeHeader())) - } - private List> appendBodyPatterns(Object bodyValue) { - return appendBodyPatterns(new MatchingStrategy(bodyValue, MatchingStrategy.Type.EQUAL_TO)) + return appendBodyPatterns(new MatchingStrategy(bodyValue, getEqualsTypeFromContentTypeHeader())) } private Map appendBodyPattern(MatchingStrategy matchingStrategy) { MatchingStrategy.Type type = matchingStrategy.type - Object value= matchingStrategy.clientValue + Object value = matchingStrategy.clientValue ContentType contentType = recognizeContentTypeFromMatchingStrategy(type) if (contentType == ContentType.UNKNOWN && type == MatchingStrategy.Type.EQUAL_TO) { contentType = recognizeContentTypeFromContent(value) type = getEqualsTypeFromContentType(contentType) } - Map result = [(type.name): parseBody(value, contentType)] - if (type == MatchingStrategy.Type.EQUAL_TO_JSON && matchingStrategy.jsonCompareMode) { + if (containsPattern(value)) { + return appendBodyRegexpMatchPattern(value, contentType) + } + return buildMatchPattern(new MatchingStrategy(parseBody(value, contentType), type)) + } + + private Map appendBodyRegexpMatchPattern(Object value, ContentType contentType) { + switch (contentType) { + case ContentType.JSON: + return buildMatchPattern(new MatchingStrategy(buildJSONRegexpMatch(value), MatchingStrategy.Type.MATCHING)) + case ContentType.UNKNOWN: + return buildMatchPattern(new MatchingStrategy(buildGStringRegexpMatch(value), MatchingStrategy.Type.MATCHING)) + case ContentType.XML: + throw new IllegalStateException("XML pattern matching is not implemented yet") + } + } + + private Map buildMatchPattern(MatchingStrategy matchingStrategy) { + Map result = [(matchingStrategy.type.name): matchingStrategy.clientValue.toString()] + if (matchingStrategy.type == MatchingStrategy.Type.EQUAL_TO_JSON && matchingStrategy.jsonCompareMode) { return result << [jsonCompareMode : (matchingStrategy.jsonCompareMode.toString())] } return result } private boolean containsPattern(GString bodyAsValue) { - return bodyAsValue.values.collect { it instanceof DslProperty ? it.clientValue : it } - .find { it instanceof Pattern } + return containsPattern(bodyAsValue.values) } - private List extractReqexpMatching(Object responseBodyObject) { - def matchingStrategies = new ArrayList() - if (responseBodyObject instanceof GString) { - return [new MatchingStrategy(responseBodyObject, MatchingStrategy.Type.MATCHING)] - } else if (responseBodyObject instanceof Map) { - responseBodyObject.each { k, v -> - if (v instanceof List) { - v.each { - matchingStrategies.addAll(extractReqexpMatching((Map)it)) - } - } else { - matchingStrategies.add(new MatchingStrategy(/.*${k}":.?"?${v}"?.*/, MatchingStrategy.Type.MATCHING)) - } - } - } - return matchingStrategies + private boolean containsPattern(Map map) { + return containsPattern(map.entrySet()) + } + + private boolean containsPattern(Collection collection) { + return collection.collect(this.&containsPattern).inject { a, b -> a || b } + } + + private boolean containsPattern(Object[] objects) { + return containsPattern(objects.toList()) + } + + private boolean containsPattern(Map.Entry entry) { + return containsPattern(entry.value) + } + + private boolean containsPattern(DslProperty dslProperty) { + return containsPattern(dslProperty.clientValue) + } + + private boolean containsPattern(Pattern pattern) { + return true + } + + private boolean containsPattern(Object o) { + return false } private MatchingStrategy.Type getEqualsTypeFromContentTypeHeader() { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy new file mode 100644 index 0000000000..47cb595220 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy @@ -0,0 +1,72 @@ +package io.codearte.accurest.util + +import io.codearte.accurest.dsl.internal.DslProperty +import org.codehaus.groovy.runtime.GStringImpl + +import java.util.regex.Pattern + +import static io.codearte.accurest.util.ContentUtils.extractValue +import static org.apache.commons.lang3.StringEscapeUtils.escapeJson + +public class RegexpBuilders { + + public static String buildGStringRegexpMatch(GString gString) { + new GStringImpl( + gString.values.collect(this.&buildGStringRegexpMatch) as Object[], + gString.strings.collect(this.&escapeSpecialRegexChars) as String[] + ) + } + + public static String buildGStringRegexpMatch(Pattern pattern) { + return pattern.pattern() + } + + public static String buildGStringRegexpMatch(DslProperty dslProperty) { + return buildGStringRegexpMatch(dslProperty.clientValue) + } + + public static String buildGStringRegexpMatch(Object o) { + return escapeSpecialRegexChars(o.toString()) + } + + private final static Pattern SPECIAL_REGEX_CHARS = Pattern.compile('[{}()\\[\\].+*?^$\\\\|]') + + private static String escapeSpecialRegexChars(String str) { + return SPECIAL_REGEX_CHARS.matcher(str).replaceAll('\\\\$0') + } + + private final static String WS = /\s*/ + + public static String buildJSONRegexpMatch(GString gString) { + return buildJSONRegexpMatch(extractValue(gString, ContentType.JSON, { DslProperty dslProperty -> dslProperty.clientValue })) + } + + public static String buildJSONRegexpMatch(Map jsonMap) { + return WS + "\\{" + jsonMap.collect(this.&buildJSONRegexpMatch).join(",") + "\\}" + WS + } + + public static String buildJSONRegexpMatch(List jsonList) { + return WS + "\\[" + jsonList.collect(this.&buildJSONRegexpMatch).join(",") + "\\]" + WS + } + + public static String buildJSONRegexpMatch(Map.Entry entry) { + return buildJSONRegexpMatchString(escapeJson(entry.key)) + ":" + buildJSONRegexpMatch(entry.value) + } + + public static String buildJSONRegexpMatch(Object value) { + return buildJSONRegexpMatchStringOptionalQuotes(escapeJson(value.toString())) + } + + public static String buildJSONRegexpMatch(Pattern pattern) { + return buildJSONRegexpMatchStringOptionalQuotes(pattern.pattern()) + } + + public static String buildJSONRegexpMatchString(String value) { + return WS + '"' + value + '"' + WS + } + + public static String buildJSONRegexpMatchStringOptionalQuotes(String value) { + return WS + '"?' + value + '"?' + WS + } + +} 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 80540ec70d..946e72064c 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 @@ -553,7 +553,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { "method": "GET", "urlPattern": "/[0-9]{2}", "bodyPatterns": [ - {"matches": ".*personalId\\":.?\\"?^[0-9]{11}$\\"?.*"} + {"matches": "\\\\s*\\\\{\\\\s*\\\"personalId\\\"\\\\s*:\\\\s*\\\"?^[0-9]{11}$\\\"?\\\\s*\\\\}\\\\s*"} ] }, "response": { @@ -613,8 +613,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { }, "url": "/fraudcheck", "bodyPatterns": [ - {"matches": ".*clientPesel\\":.?\\"?[0-9]{10}\\"?.*"}, - {"matches": ".*loanAmount\\":.?\\"?123.123\\"?.*"} + {"matches": "\\\\s*\\\\{\\\\s*\\"clientPesel\\"\\\\s*:\\\\s*\\"?[0-9]{10}\\"?\\\\s*,\\\\s*\\"loanAmount\\"\\\\s*:\\\\s*\\"?123.123\\"?\\\\s*\\\\}\\\\s*"} ] }, "response": { @@ -986,17 +985,11 @@ class WiremockGroovyDslSpec extends WiremockSpec { "request": { "method": "GET", "urlPattern": "/[0-9]{2}", - "bodyPatterns": [ - {"matches": ".*birthDate\\":.?\\"?[0-9]{4}-[0-9]{2}-[0-9]{2}\\"?.*"}, - {"matches": ".*propertyName\\":.?\\"?[0-9]{2}\\"?.*"}, - {"matches": ".*providerValue\\":.?\\"?Test\\"?.*"}, - {"matches": ".*propertyName\\":.?\\"?[0-9]{2}\\"?.*"}, - {"matches": ".*providerValue\\":.?\\"?Test\\"?.*"}, - {"matches": ".*firstName\\":.?\\"?.*\\"?.*"}, - {"matches": ".*lastName\\":.?\\"?.*\\"?.*"}, - {"matches": ".*personalId\\":.?\\"?[0-9]{11}\\"?.*"} - ] - }, + "bodyPatterns": [ + { + "matches": "\\\\s*\\\\{\\\\s*\\"birthDate\\"\\\\s*:\\\\s*\\"?[0-9]{4}-[0-9]{2}-[0-9]{2}\\"?\\\\s*,\\\\s*\\"errors\\"\\\\s*:\\\\s*\\\\[\\\\s*\\\\{\\\\s*\\"propertyName\\"\\\\s*:\\\\s*\\"?[0-9]{2}\\"?\\\\s*,\\\\s*\\"providerValue\\"\\\\s*:\\\\s*\\"?Test\\"?\\\\s*\\\\}\\\\s*,\\\\s*\\\\{\\\\s*\\"propertyName\\"\\\\s*:\\\\s*\\"?[0-9]{2}\\"?\\\\s*,\\\\s*\\"providerValue\\"\\\\s*:\\\\s*\\"?Test\\"?\\\\s*\\\\}\\\\s*\\\\]\\\\s*,\\\\s*\\"firstName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"lastName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"personalId\\"\\\\s*:\\\\s*\\"?[0-9]{11}\\"?\\\\s*\\\\}\\\\s*" + } + ] }, "response": { "status": 200, "body": "{\\"name\\":\\"Jan\\"}", @@ -1008,6 +1001,58 @@ class WiremockGroovyDslSpec extends WiremockSpec { ''') } + def 'should use regexp matches when request body match is defined using a map with a pattern'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'POST' + url '/reissue-payment-order' + body( + loanNumber: "999997001", + amount: value(client(regex('[0-9.]+')), server('100.00')), + currency: "DKK", + applicationName: value(client(regex('.*')), server("Auto-Repayments")), + username: value(client(regex('.*')), server("scheduler")), + cardId: 1 + ) + } + response { + status 200 + body ''' + { + "status": "OK" + } + ''' + headers { + header 'Content-Type': 'application/json' + } + } + } + when: + def json = toWiremockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "POST", + "url": "/reissue-payment-order", + "bodyPatterns": [ + { + "matches": "\\\\s*\\\\{\\\\s*\\"loanNumber\\"\\\\s*:\\\\s*\\"?999997001\\"?\\\\s*,\\\\s*\\"amount\\"\\\\s*:\\\\s*\\"?[0-9.]+\\"?\\\\s*,\\\\s*\\"currency\\"\\\\s*:\\\\s*\\"?DKK\\"?\\\\s*,\\\\s*\\"applicationName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"username\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"cardId\\"\\\\s*:\\\\s*\\"?1\\"?\\\\s*\\\\}\\\\s*" + } + ] + }, + "response": { + "status": 200, + "body": "{\\"status\\":\\"OK\\"}", + "headers": { + "Content-Type": "application/json" + } + } + } + ''') + } + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } From 6b2de1b0c00505c3bd2547412dac650d478b1e8d Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Tue, 23 Jun 2015 15:27:53 +0200 Subject: [PATCH 174/719] Added absent matching strategy --- .../builder/SpockMethodBodyBuilder.groovy | 16 +++++- .../dsl/BaseWiremockStubStrategy.groovy | 4 ++ .../accurest/dsl/internal/Common.groovy | 22 ++++++++ .../dsl/internal/MatchingStrategy.groovy | 2 +- .../accurest/dsl/internal/Request.groovy | 4 ++ .../accurest/util/ValidateUtils.groovy | 7 ++- .../builder/SpockMethodBuilderSpec.groovy | 2 + .../accurest/dsl/WiremockGroovyDslSpec.groovy | 54 +++++++++++++++++++ 8 files changed, 108 insertions(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index cc35423d97..7e7bb697bc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -120,12 +120,26 @@ class SpockMethodBodyBuilder { } private String buildUrlFromUrlPath(UrlPath urlPath) { - String params = urlPath.queryParameters.parameters.inject([]) { result, param -> + String params = urlPath.queryParameters.parameters + .findAll(this.&allowedQueryParameter) + .inject([]) { result, param -> result << "${param.name}=${resolveParamValue(param).toString()}" }.join('&') return "$urlPath.serverValue?$params" } + private boolean allowedQueryParameter(QueryParameter param) { + return allowedQueryParameter(param.serverValue) + } + + private boolean allowedQueryParameter(MatchingStrategy matchingStrategy) { + return matchingStrategy.type != MatchingStrategy.Type.ABSENT + } + + private boolean allowedQueryParameter(Object o) { + return true + } + private String resolveParamValue(QueryParameter param) { resolveParamValue(param.serverValue) } 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 index a5c100341b..e3285a9467 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy @@ -53,6 +53,10 @@ abstract class BaseWiremockStubStrategy { return parseBody(value.toString(), contentType) } + public Boolean parseBody(Boolean value, ContentType contentType) { + return value + } + public String parseBody(Map map, ContentType contentType) { def transformedMap = transformValues(map, transform) return parseBody(toJson(transformedMap), contentType) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 3dca0390ef..87d509de59 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -88,6 +88,28 @@ class Common { assert firstSide ==~ secondSide } + void assertThatSidesMatch(MatchingStrategy firstSide, MatchingStrategy secondSide) { + if (firstSide.type == MatchingStrategy.Type.ABSENT && secondSide != MatchingStrategy.Type.ABSENT) { + throwAbsentError() + } + } + + void assertThatSidesMatch(MatchingStrategy firstSide, Object secondSide) { + if (firstSide.type == MatchingStrategy.Type.ABSENT) { + throwAbsentError() + } + } + + void assertThatSidesMatch(Object firstSide, MatchingStrategy secondSide) { + if (secondSide.type == MatchingStrategy.Type.ABSENT) { + throwAbsentError() + } + } + + private void throwAbsentError() { + throw new IllegalStateException("Absent cannot only be used only on one side") + } + void assertThatSidesMatch(Object firstSide, Object secondSide) { // do nothing } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy index e9093dc9aa..c31c0b4bf6 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy @@ -35,7 +35,7 @@ class MatchingStrategy extends DslProperty { enum Type { EQUAL_TO("equalTo"), CONTAINS("contains"), MATCHING("matches"), NOT_MATCHING("doesNotMatch"), - EQUAL_TO_JSON("equalToJson"), EQUAL_TO_XML("equalToXml") + EQUAL_TO_JSON("equalToJson"), EQUAL_TO_XML("equalToXml"), ABSENT("absent") final String name diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 1ed604d4fb..9be791488a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -125,6 +125,10 @@ class Request extends Common { return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO_JSON) } + MatchingStrategy absent() { + return new MatchingStrategy(true, MatchingStrategy.Type.ABSENT) + } + } @CompileStatic diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy index eac7bce25c..7cb6e0f0ef 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy @@ -6,6 +6,9 @@ import io.codearte.accurest.dsl.internal.MatchingStrategy import java.util.regex.Pattern +import static io.codearte.accurest.dsl.internal.MatchingStrategy.Type.ABSENT +import static io.codearte.accurest.dsl.internal.MatchingStrategy.Type.EQUAL_TO + @TypeChecked class ValidateUtils { @@ -23,8 +26,10 @@ class ValidateUtils { throw new IllegalStateException("$msg can't be a pattern for the server side") } + static List ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE = [EQUAL_TO, ABSENT] + static void validateServerValue(MatchingStrategy matchingStrategy, String msg) { - if (matchingStrategy.type != MatchingStrategy.Type.EQUAL_TO) { + if (!ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE.contains(matchingStrategy.type)) { throw new IllegalStateException("$msg can't be of a matching type: $matchingStrategy.type for the server side") } validateServerValue(matchingStrategy.serverValue, msg) 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 index b38ec458b1..964f03811b 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -260,6 +260,8 @@ class SpockMethodBuilderSpec extends Specification { parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() } } } 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 80540ec70d..5e0b681604 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 @@ -695,6 +695,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("10")) parameter 'age': $(client(notMatching("^\\w*\$")), server(10)) parameter 'name': $(client(matching("Denis.*")), server("Denis")) + parameter 'credit': absent() } } } @@ -731,6 +732,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { }, "name": { "matches": "Denis.*" + }, + "credit": { + "absent": true } } }, @@ -863,6 +867,56 @@ class WiremockGroovyDslSpec extends WiremockSpec { e.message.contains "Query parameter 'age' can't be of a matching type: NOT_MATCHING for the server side" } + def "should not allow query parameter with a different absent variation for server/client"() { + when: + GroovyDsl.make dsl + then: + def e = thrown(IllegalStateException) + e.message.contains "Absent cannot only be used only on one side" + where: + dsl << [ + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(absent()), server("")) + } + } + } + response { + status 200 + } + }, + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(""), server(absent())) + } + } + } + response { + status 200 + } + }, + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(absent()), server(matching("abc"))) + } + } + } + response { + status 200 + } + } + ] + } + def "should generate request with url and queryParameters for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make { From 0eebda74394c433e7bc7df69fbb2931b433100da Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 25 Jun 2015 16:18:49 +0200 Subject: [PATCH 175/719] Fixed references to WireMock in the project so that it is correctly capitalized. --- README.md | 2 +- .../DslToWireMockClientConverter.groovy | 13 ++ ...r.groovy => DslToWireMockConverter.groovy} | 2 +- .../DslToWiremockClientConverter.groovy | 13 -- ...r.groovy => WireMockToDslConverter.groovy} | 22 ++-- ...> DslToWireMockClientConverterSpec.groovy} | 10 +- ...oovy => WireMockToDslConverterSpec.groovy} | 84 ++++++------ .../config/AccurestConfigProperties.groovy | 2 +- ...groovy => BaseWireMockStubStrategy.groovy} | 2 +- ...ovy => WireMockRequestStubStrategy.groovy} | 4 +- ...vy => WireMockResponseStubStrategy.groovy} | 4 +- .../accurest/dsl/WireMockStubStrategy.groovy | 21 +++ .../accurest/dsl/WiremockStubStrategy.groovy | 21 --- ...y => WireMockGroovyDslResponseSpec.groovy} | 6 +- ...ec.groovy => WireMockGroovyDslSpec.groovy} | 120 +++++++++--------- ...iremockSpec.groovy => WireMockSpec.groovy} | 4 +- .../plugin/AccurestGradlePlugin.groovy | 19 ++- ...rateWireMockClientStubsFromDslTask.groovy} | 8 +- .../plugin/BasicFunctionalSpec.groovy | 14 +- .../functionalTest/bootSimple/build.gradle | 14 +- .../functionalTest/sampleProject/build.gradle | 9 +- build.gradle | 1 + 22 files changed, 203 insertions(+), 192 deletions(-) create mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverter.groovy rename accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/{DslToWiremockConverter.groovy => DslToWireMockConverter.groovy} (89%) delete mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverter.groovy rename accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/{WiremockToDslConverter.groovy => WireMockToDslConverter.groovy} (88%) rename accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/{DslToWiremockClientConverterSpec.groovy => DslToWireMockClientConverterSpec.groovy} (90%) rename accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/{WiremockToDslConverterSpec.groovy => WireMockToDslConverterSpec.groovy} (79%) rename accurest-core/src/main/groovy/io/codearte/accurest/dsl/{BaseWiremockStubStrategy.groovy => BaseWireMockStubStrategy.groovy} (98%) rename accurest-core/src/main/groovy/io/codearte/accurest/dsl/{WiremockRequestStubStrategy.groovy => WireMockRequestStubStrategy.groovy} (98%) rename accurest-core/src/main/groovy/io/codearte/accurest/dsl/{WiremockResponseStubStrategy.groovy => WireMockResponseStubStrategy.groovy} (92%) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockStubStrategy.groovy rename accurest-core/src/test/groovy/io/codearte/accurest/dsl/{WiremockGroovyDslResponseSpec.groovy => WireMockGroovyDslResponseSpec.groovy} (82%) rename accurest-core/src/test/groovy/io/codearte/accurest/dsl/{WiremockGroovyDslSpec.groovy => WireMockGroovyDslSpec.groovy} (87%) rename accurest-core/src/test/groovy/io/codearte/accurest/dsl/{WiremockSpec.groovy => WireMockSpec.groovy} (76%) rename accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/{GenerateWiremockClientStubsFromDslTask.groovy => GenerateWireMockClientStubsFromDslTask.groovy} (74%) diff --git a/README.md b/README.md index d379b16aa0..6bf509470d 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Consumer Driven Contracts verifier for Java 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: -generating Wiremock's JSON stub definitions, allowing rapid development of the consumer side, +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. 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 new file mode 100644 index 0000000000..619bd8b235 --- /dev/null +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverter.groovy @@ -0,0 +1,13 @@ +package io.codearte.accurest.wiremock + +import groovy.transform.CompileStatic +import io.codearte.accurest.dsl.WireMockStubStrategy + +@CompileStatic +class DslToWireMockClientConverter extends DslToWireMockConverter { + + @Override + String convertContent(String dslBody) { + return new WireMockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWireMockClientStub() + } +} 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 similarity index 89% rename from accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockConverter.groovy rename to accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWireMockConverter.groovy index 5804010090..9163724610 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 @@ -4,7 +4,7 @@ import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl @CompileStatic -abstract class DslToWiremockConverter implements SingleFileConverter { +abstract class DslToWireMockConverter implements SingleFileConverter { @Override boolean canHandleFileName(String fileName) { 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 deleted file mode 100644 index 8156f17cf6..0000000000 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverter.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package io.codearte.accurest.wiremock - -import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.WiremockStubStrategy - -@CompileStatic -class DslToWiremockClientConverter extends DslToWiremockConverter { - - @Override - String convertContent(String dslBody) { - return new WiremockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWiremockClientStub() - } -} 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 similarity index 88% rename from accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WiremockToDslConverter.groovy rename to accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy index 543f9eff89..689edb3d9a 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 @@ -8,15 +8,15 @@ import nl.flotsam.xeger.Xeger import static org.apache.commons.lang3.StringEscapeUtils.escapeJava -class WiremockToDslConverter { - static String fromWiremockStub(String wiremockStringStub) { - return new WiremockToDslConverter().convertFromWiremockStub(wiremockStringStub) +class WireMockToDslConverter { + static String fromWireMockStub(String wireMockStringStub) { + return new WireMockToDslConverter().convertFromWireMockStub(wireMockStringStub) } - private String convertFromWiremockStub(String wiremockStringStub) { - Object wiremockStub = new JsonSlurper().parseText(wiremockStringStub) - def request = wiremockStub.request - def response = wiremockStub.response + private String convertFromWireMockStub(String wireMockStringStub) { + Object wireMockStub = new JsonSlurper().parseText(wireMockStringStub) + def request = wireMockStub.request + def response = wireMockStub.response def bodyPatterns = request.bodyPatterns String urlPattern = request.urlPattern return """\ @@ -146,8 +146,8 @@ class WiremockToDslConverter { if (!it.name.endsWith('json')) { return } - String dslFromWiremockStub = fromWiremockStub(it.text) - String dslWrappedWithFactoryMethod = wrapWithFactoryMethod(dslFromWiremockStub) + 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 = dslWrappedWithFactoryMethod @@ -158,10 +158,10 @@ class WiremockToDslConverter { } } - static String wrapWithFactoryMethod(String dslFromWiremockStub) { + static String wrapWithFactoryMethod(String dslFromWireMockStub) { return """\ ${GroovyDsl.name}.make { - $dslFromWiremockStub + $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 similarity index 90% rename from accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWiremockClientConverterSpec.groovy rename to accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverterSpec.groovy index edf11a256f..0831dde57b 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 @@ -3,11 +3,11 @@ package io.codearte.accurest.wiremock import groovy.json.JsonSlurper import spock.lang.Specification -class DslToWiremockClientConverterSpec extends Specification { +class DslToWireMockClientConverterSpec extends Specification { - def "should convert DSL file to Wiremock JSON"() { + def "should convert DSL file to WireMock JSON"() { given: - def converter = new DslToWiremockClientConverter() + def converter = new DslToWireMockClientConverter() and: String dslBody = """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -28,9 +28,9 @@ class DslToWiremockClientConverterSpec extends Specification { } - def "should convert DSL file with a nested list to Wiremock JSON"() { + def "should convert DSL file with a nested list to WireMock JSON"() { given: - def converter = new DslToWiremockClientConverter() + def converter = new DslToWireMockClientConverter() and: String dslBody = """ io.codearte.accurest.dsl.GroovyDsl.make { 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 similarity index 79% rename from accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy rename to accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy index b147d9da93..9cb1e9813f 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy @@ -4,11 +4,11 @@ import com.github.tomakehurst.wiremock.stubbing.StubMapping import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification -class WiremockToDslConverterSpec extends Specification { +class WireMockToDslConverterSpec extends Specification { - def 'should produce a Groovy DSL from Wiremock stub'() { + def 'should produce a Groovy DSL from WireMock stub'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request": { "method": "GET", @@ -32,7 +32,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -65,7 +65,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -74,9 +74,9 @@ class WiremockToDslConverterSpec extends Specification { } - def 'should convert Wiremock stub with response body containing simple JSON'() { + def 'should convert WireMock stub with response body containing simple JSON'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request": { "method": "DELETE", @@ -97,7 +97,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -119,7 +119,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -127,9 +127,9 @@ class WiremockToDslConverterSpec extends Specification { }""") == expectedGroovyDsl } - def 'should convert Wiremock stub with response body containing integer'() { + def 'should convert WireMock stub with response body containing integer'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request": { "method": "POST", @@ -150,7 +150,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -170,7 +170,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -178,9 +178,9 @@ class WiremockToDslConverterSpec extends Specification { }""") == expectedGroovyDsl } - def 'should convert Wiremock stub with response body as a list'() { + def 'should convert WireMock stub with response body as a list'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request": { "method": "POST", @@ -201,7 +201,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -224,7 +224,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -233,9 +233,9 @@ class WiremockToDslConverterSpec extends Specification { } - def 'should convert Wiremock stub with response body containing a nested list'() { + def 'should convert WireMock stub with response body containing a nested list'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request": { "method": "POST", @@ -253,7 +253,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -290,7 +290,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -298,9 +298,9 @@ class WiremockToDslConverterSpec extends Specification { }""") == expectedGroovyDsl } - def 'should convert Wiremock stub with request body checking equality to Json'() { + def 'should convert WireMock stub with request body checking equality to Json'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request": { "method": "POST", @@ -315,7 +315,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -328,7 +328,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -338,9 +338,9 @@ class WiremockToDslConverterSpec extends Specification { evaluatedGroovyDsl == expectedGroovyDsl } - def 'should convert Wiremock stub with request body checking matching to Json'() { + def 'should convert WireMock stub with request body checking matching to Json'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request": { "method": "POST", @@ -355,7 +355,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -368,7 +368,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -378,9 +378,9 @@ class WiremockToDslConverterSpec extends Specification { evaluatedGroovyDsl == expectedGroovyDsl } - def 'should convert Wiremock stub with request body with equalToJson'() { + def 'should convert WireMock stub with request body with equalToJson'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request" : { "url" : "/test", @@ -396,7 +396,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -409,7 +409,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -419,9 +419,9 @@ class WiremockToDslConverterSpec extends Specification { evaluatedGroovyDsl == expectedGroovyDsl } - def 'should convert Wiremock stub with request body with equalTo'() { + def 'should convert WireMock stub with request body with equalTo'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request" : { "url" : "/test", @@ -436,7 +436,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -449,7 +449,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -459,9 +459,9 @@ class WiremockToDslConverterSpec extends Specification { evaluatedGroovyDsl == expectedGroovyDsl } - def 'should convert Wiremock stub with request body with matches'() { + def 'should convert WireMock stub with request body with matches'() { given: - String wiremockStub = '''\ + String wireMockStub = '''\ { "request" : { "url" : "/test", @@ -476,7 +476,7 @@ class WiremockToDslConverterSpec extends Specification { } ''' and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) and: GroovyDsl expectedGroovyDsl = GroovyDsl.make { request { @@ -489,7 +489,7 @@ class WiremockToDslConverterSpec extends Specification { } } when: - String groovyDsl = WiremockToDslConverter.fromWiremockStub(wiremockStub) + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( """ io.codearte.accurest.dsl.GroovyDsl.make { @@ -499,7 +499,7 @@ class WiremockToDslConverterSpec extends Specification { evaluatedGroovyDsl == expectedGroovyDsl } - void stubMappingIsValidWiremockStub(String mappingDefinition) { + void stubMappingIsValidWireMockStub(String mappingDefinition) { StubMapping.buildFrom(mappingDefinition) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy index 965f3bf84a..9d69c3ee8e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy @@ -23,7 +23,7 @@ class AccurestConfigProperties { File generatedTestSourcesDir /** - * Dir where the generated Wiremock stubs from Groovy DSL should be placed. + * Dir where the generated WireMock stubs from Groovy DSL should be placed. * You can then mention them in your packaging task to create jar with stubs */ File stubsOutputDir 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 similarity index 98% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy index e3285a9467..0afb66273b 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWiremockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy @@ -13,7 +13,7 @@ import static io.codearte.accurest.util.ContentUtils.extractValue import static io.codearte.accurest.util.JsonConverter.transformValues @TypeChecked -abstract class BaseWiremockStubStrategy { +abstract class BaseWireMockStubStrategy { private static Closure transform = { it instanceof DslProperty ? transformValues(it.clientValue, transform) : it diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy similarity index 98% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index a98088b672..d0bb325bb1 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -21,11 +21,11 @@ import static io.codearte.accurest.util.RegexpBuilders.buildJSONRegexpMatch @TypeChecked @PackageScope -class WiremockRequestStubStrategy extends BaseWiremockStubStrategy { +class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { private final Request request - WiremockRequestStubStrategy(GroovyDsl groovyDsl) { + WireMockRequestStubStrategy(GroovyDsl groovyDsl) { this.request = groovyDsl.request } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy similarity index 92% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy index a17dad9420..3cb9a58155 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy @@ -11,12 +11,12 @@ import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHea @TypeChecked @PackageScope -class WiremockResponseStubStrategy extends BaseWiremockStubStrategy { +class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { private final Request request private final Response response - WiremockResponseStubStrategy(GroovyDsl groovyDsl) { + WireMockResponseStubStrategy(GroovyDsl groovyDsl) { this.response = groovyDsl.response this.request = groovyDsl.request } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy new file mode 100644 index 0000000000..1793b8e61c --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy @@ -0,0 +1,21 @@ +package io.codearte.accurest.dsl + +import groovy.json.JsonOutput +import groovy.transform.CompileStatic + +@CompileStatic +class WireMockStubStrategy { + + private final WireMockRequestStubStrategy wireMockRequestStubStrategy + private final WireMockResponseStubStrategy wireMockResponseStubStrategy + + WireMockStubStrategy(GroovyDsl groovyDsl) { + this.wireMockRequestStubStrategy = new WireMockRequestStubStrategy(groovyDsl) + this.wireMockResponseStubStrategy = new WireMockResponseStubStrategy(groovyDsl) + } + + String toWireMockClientStub() { + return JsonOutput.prettyPrint(JsonOutput.toJson([request : wireMockRequestStubStrategy.buildClientRequestContent(), + response: wireMockResponseStubStrategy.buildClientResponseContent()])) + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockStubStrategy.groovy deleted file mode 100644 index a4bf3ee9c4..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WiremockStubStrategy.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package io.codearte.accurest.dsl - -import groovy.json.JsonOutput -import groovy.transform.CompileStatic - -@CompileStatic -class WiremockStubStrategy { - - private final WiremockRequestStubStrategy wiremockRequestStubStrategy - private final WiremockResponseStubStrategy wiremockResponseStubStrategy - - WiremockStubStrategy(GroovyDsl groovyDsl) { - this.wiremockRequestStubStrategy = new WiremockRequestStubStrategy(groovyDsl) - this.wiremockResponseStubStrategy = new WiremockResponseStubStrategy(groovyDsl) - } - - String toWiremockClientStub() { - return JsonOutput.prettyPrint(JsonOutput.toJson([request : wiremockRequestStubStrategy.buildClientRequestContent(), - response: wiremockResponseStubStrategy.buildClientResponseContent()])) - } -} 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 similarity index 82% rename from accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslResponseSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslResponseSpec.groovy index 13299ceebe..07eb9aebda 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 @@ -3,7 +3,7 @@ package io.codearte.accurest.dsl import groovy.json.JsonSlurper import spock.lang.Specification -class WiremockGroovyDslResponseSpec extends Specification { +class WireMockGroovyDslResponseSpec extends Specification { def 'should generate response without body for client side'() { given: @@ -13,7 +13,7 @@ class WiremockGroovyDslResponseSpec extends Specification { } } expect: - new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(expectedStub) + new WireMockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(expectedStub) where: expectedStub << [''' { @@ -39,7 +39,7 @@ class WiremockGroovyDslResponseSpec extends Specification { } } expect: - new WiremockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(''' + new WireMockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(''' { "headers": { "Content-Type": "text/xml" 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 similarity index 87% rename from accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockGroovyDslSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy index ca68489624..e7e6886b5d 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 @@ -4,9 +4,9 @@ import groovy.json.JsonBuilder import groovy.json.JsonSlurper import spock.lang.Issue -class WiremockGroovyDslSpec extends WiremockSpec { +class WireMockGroovyDslSpec extends WireMockSpec { - def 'should convert groovy dsl stub to wiremock stub for the client side'() { + def 'should convert groovy dsl stub to wireMock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { request { @@ -33,9 +33,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -51,11 +51,11 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) } @Issue("#79") - def 'should convert groovy dsl stub to wiremock stub for the client side with a body containing a map'() { + def 'should convert groovy dsl stub to wireMock stub for the client side with a body containing a map'() { given: GroovyDsl groovyDsl = GroovyDsl.make { request { @@ -78,9 +78,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -98,7 +98,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) } @Issue("#86") @@ -122,9 +122,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "POST", @@ -147,10 +147,10 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) } - def 'should convert groovy dsl stub with Body as String to wiremock stub for the client side'() { + def 'should convert groovy dsl stub with Body as String to wireMock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { request { @@ -174,9 +174,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -192,10 +192,10 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) } - def 'should convert groovy dsl stub with simple Body as String to wiremock stub for the client side'() { + def 'should convert groovy dsl stub with simple Body as String to wireMock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { request { @@ -221,9 +221,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -244,7 +244,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) } def 'should use equalToJson when body match is defined as map'() { @@ -271,9 +271,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -290,7 +290,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) } def 'should use equalToJson when content type ends with json'() { @@ -313,7 +313,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String json = toWiremockClientJsonStub(groovyDsl) + String json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -337,7 +337,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def 'should use equalToXml when content type ends with xml'() { @@ -356,7 +356,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String json = toWiremockClientJsonStub(groovyDsl) + String json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -380,7 +380,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def 'should use equalToXml when content type is parsable xml'() { @@ -396,7 +396,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String json = toWiremockClientJsonStub(groovyDsl) + String json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -415,7 +415,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def 'should support xml as a response body'() { @@ -431,7 +431,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String json = toWiremockClientJsonStub(groovyDsl) + String json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -446,7 +446,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def 'should use equalToJson'() { @@ -462,7 +462,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String json = toWiremockClientJsonStub(groovyDsl) + String json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -481,7 +481,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def 'should use equalToXml'() { @@ -497,7 +497,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String json = toWiremockClientJsonStub(groovyDsl) + String json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -516,10 +516,10 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } - def 'should convert groovy dsl stub with regexp Body as String to wiremock stub for the client side'() { + def 'should convert groovy dsl stub with regexp Body as String to wireMock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { request { @@ -545,9 +545,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -566,7 +566,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) } def 'should convert groovy dsl stub with a regexp and an integer in request body'() { @@ -600,9 +600,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "PUT", @@ -626,7 +626,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(wiremockStub) + stubMappingIsValidWireMockStub(wireMockStub) } @@ -638,7 +638,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "method":"GET" } @@ -654,7 +654,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "method":"GET", "url":"/sth" @@ -673,7 +673,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "urlPattern":"^/[0-9]{2}$" } @@ -703,7 +703,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - def json = toWiremockClientJsonStub(groovyDsl) + def json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -743,7 +743,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def "should generate request with urlPath for client side"() { @@ -758,7 +758,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - def json = toWiremockClientJsonStub(groovyDsl) + def json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -772,7 +772,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def "should generate simple request with urlPath for client side"() { @@ -787,7 +787,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - def json = toWiremockClientJsonStub(groovyDsl) + def json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -801,7 +801,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def "should not allow regexp in url for server value"() { @@ -933,7 +933,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - def json = toWiremockClientJsonStub(groovyDsl) + def json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -955,7 +955,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } ''') and: - stubMappingIsValidWiremockStub(json) + stubMappingIsValidWireMockStub(json) } def "should generate stub with some headers section for client side"() { @@ -976,7 +976,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } expect: - new WiremockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' + new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' { "headers": { "Content-Type": { @@ -993,7 +993,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { ''') } - def 'should convert groovy dsl stub with rich tree Body as String to wiremock stub for the client side'() { + def 'should convert groovy dsl stub with rich tree Body as String to wireMock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { request { @@ -1032,9 +1032,9 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - String wiremockStub = new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wiremockStub) == new JsonSlurper().parseText(''' + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' { "request": { "method": "GET", @@ -1083,7 +1083,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { } } when: - def json = toWiremockClientJsonStub(groovyDsl) + def json = toWireMockClientJsonStub(groovyDsl) then: parseJson(json) == parseJson(''' { @@ -1115,7 +1115,7 @@ class WiremockGroovyDslSpec extends WiremockSpec { new JsonSlurper().parseText(json) } - String toWiremockClientJsonStub(groovyDsl) { - new WiremockStubStrategy(groovyDsl).toWiremockClientStub() + String toWireMockClientJsonStub(groovyDsl) { + new WireMockStubStrategy(groovyDsl).toWireMockClientStub() } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy similarity index 76% rename from accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy index ab1133c9ae..aad0fa879e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WiremockSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy @@ -5,9 +5,9 @@ import spock.lang.Specification import java.util.regex.Pattern -abstract class WiremockSpec extends Specification { +abstract class WireMockSpec extends Specification { - void stubMappingIsValidWiremockStub(String mappingDefinition) { + void stubMappingIsValidWireMockStub(String mappingDefinition) { StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) stubMapping.request.bodyPatterns.findAll { it.matches }.every { Pattern.compile(it.matches) 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 cee3f48357..dcec7b2f61 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 @@ -11,7 +11,7 @@ import org.gradle.api.Task class AccurestGradlePlugin implements Plugin { private static final String GENERATE_SERVER_TESTS_TASK_NAME = 'generateAccurest' - private static final String DSL_TO_WIREMOCK_CLIENT_TASK_NAME = 'generateWiremockClientStubs' + private static final String DSL_TO_WIREMOCK_CLIENT_TASK_NAME = 'generateWireMockClientStubs' private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin private static final String GROUP_NAME = "Verification" @@ -27,7 +27,8 @@ class AccurestGradlePlugin implements Plugin { setConfigurationDefaults(extension) createGenerateTestsTask(extension) - createAndConfigureGenerateWiremockClientStubsFromDslTask(extension) + createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) + deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) @@ -60,13 +61,21 @@ class AccurestGradlePlugin implements Plugin { } } - private void createAndConfigureGenerateWiremockClientStubsFromDslTask(AccurestConfigProperties extension) { - Task task = project.tasks.create(DSL_TO_WIREMOCK_CLIENT_TASK_NAME, GenerateWiremockClientStubsFromDslTask) - task.description = "Generate Wiremock client stubs from GroovyDSL" + private void createAndConfigureGenerateWireMockClientStubsFromDslTask(AccurestConfigProperties extension) { + Task task = project.tasks.create(DSL_TO_WIREMOCK_CLIENT_TASK_NAME, GenerateWireMockClientStubsFromDslTask) + task.description = "Generate WireMock client stubs from GroovyDSL" task.group = GROUP_NAME task.conventionMapping.with { contractsDslDir = { extension.contractsDslDir } stubsOutputDir = { extension.stubsOutputDir } } } + + private void deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() { + Task task = project.tasks.create('generateWiremockClientStubs') + task.dependsOn('generateWireMockClientStubs') + task.description = "DEPRECATED - Generates WireMock client stubs. - DEPRECATED - use 'generateWireMockClientStubs' task" + task.group = GROUP_NAME + task.doFirst {logger.warn("DEPRECATION WARNING. Task 'generateWiremockClientStubs' is deprecated. Use 'generateWireMockClientStubs' task instead.")} + } } diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy similarity index 74% rename from accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy rename to accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy index ab6f6473c1..be22c44def 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWiremockClientStubsFromDslTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy @@ -1,6 +1,6 @@ package io.codearte.accurest.plugin -import io.codearte.accurest.wiremock.DslToWiremockClientConverter +import io.codearte.accurest.wiremock.DslToWireMockClientConverter import io.codearte.accurest.wiremock.RecursiveFilesConverter import org.gradle.api.internal.ConventionTask import org.gradle.api.tasks.InputDirectory @@ -8,7 +8,7 @@ import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction //TODO: Implement as an incremental task: https://gradle.org/docs/current/userguide/custom_tasks.html#incremental_tasks ? -class GenerateWiremockClientStubsFromDslTask extends ConventionTask { +class GenerateWireMockClientStubsFromDslTask extends ConventionTask { @InputDirectory File contractsDslDir @@ -17,10 +17,10 @@ class GenerateWiremockClientStubsFromDslTask extends ConventionTask { @TaskAction void generate() { - logger.info("Accurest Plugin: Invoking GroovyDSL to Wiremock client stubs conversion") + logger.info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWiremockClientConverter(), getContractsDslDir(), + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), getContractsDslDir(), getStubsOutputDir()) converter.processFiles() } 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 96cabca538..d488f03ff4 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 @@ -23,7 +23,7 @@ class BasicFunctionalSpec extends IntegrationSpec { when: def result = runTasksSuccessfully('check') then: - result.wasExecuted(":generateWiremockClientStubs") + result.wasExecuted(":generateWireMockClientStubs") result.wasExecuted(":generateAccurest") and: "tests generated" @@ -38,7 +38,7 @@ class BasicFunctionalSpec extends IntegrationSpec { def "should generate valid client json stubs for simple input"() { when: - runTasksSuccessfully('generateWiremockClientStubs') + runTasksSuccessfully('generateWireMockClientStubs') then: def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text new JsonSlurper().parseText(generatedClientJsonStub) == new JsonSlurper().parseText(""" @@ -67,16 +67,16 @@ class BasicFunctionalSpec extends IntegrationSpec { assert !fileExists(GENERATED_CLIENT_JSON_STUB) assert !fileExists(TEST_EXECUTION_XML_REPORT) when: - runTasksSuccessfully('generateWiremockClientStubs', 'generateAccurest') + runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest') then: fileExists(GENERATED_CLIENT_JSON_STUB) fileExists(GENERATED_TEST) when: "running generation without change inputs" - def secondExecutionResult = runTasksSuccessfully('generateWiremockClientStubs', 'generateAccurest') + def secondExecutionResult = runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest') then: "tasks should be up-to-date" - secondExecutionResult.wasUpToDate(":generateWiremockClientStubs") + secondExecutionResult.wasUpToDate(":generateWireMockClientStubs") secondExecutionResult.wasUpToDate(":generateAccurest") when: "inputs changed" @@ -84,10 +84,10 @@ class BasicFunctionalSpec extends IntegrationSpec { groovyDslFile.text = groovyDslFile.text.replace("200", "599") and: "tasks run" - def thirdExecutionResult = runTasksSuccessfully('generateWiremockClientStubs', 'generateAccurest') + def thirdExecutionResult = runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest') then: "tasks should be reexecuted" - thirdExecutionResult.wasExecuted(":generateWiremockClientStubs") + thirdExecutionResult.wasExecuted(":generateWireMockClientStubs") thirdExecutionResult.wasExecuted(":generateAccurest") and: "changes visible in generate files" diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 1241194253..ee5c91b466 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -12,8 +12,8 @@ apply plugin: 'accurest' ext { contractsDir = file("${project.rootDir}/repository/mappings/com/ofg/twitter-places-analyzer") - wiremockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wiremockStubsOutputDir = new File(wiremockStubsOutputDirRoot, 'repository/mappings/') + wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") + wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'repository/mappings/') } configurations { @@ -59,16 +59,16 @@ accurest { basePackageForTests = 'accurest' contractsDslDir = contractsDir // generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/") - stubsOutputDir = wiremockStubsOutputDir + stubsOutputDir = wireMockStubsOutputDir } //TODO: Put it into the plugin -task createWiremockStubsOutputDir << { - wiremockStubsOutputDir.mkdirs() +task createWireMockStubsOutputDir << { + wireMockStubsOutputDir.mkdirs() } -generateWiremockClientStubs.dependsOn { createWiremockStubsOutputDir } -generateAccurest.dependsOn generateWiremockClientStubs +generateWireMockClientStubs.dependsOn { createWireMockStubsOutputDir } +generateAccurest.dependsOn generateWireMockClientStubs wrapper { gradleVersion '2.2.1' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 9bf00d6c55..90478ca0bd 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -40,8 +40,8 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') apply plugin: 'accurest' ext { - wiremockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wiremockStubsOutputDir = new File(wiremockStubsOutputDirRoot, 'mappings/') + wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") + wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'mappings/') } accurest { @@ -50,7 +50,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") - stubsOutputDir = wiremockStubsOutputDir + stubsOutputDir = wireMockStubsOutputDir } jar { @@ -79,7 +79,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') } configure(project(':fraudDetectionService')) { - test.dependsOn('generateWiremockClientStubs') + test.dependsOn('generateWireMockClientStubs') } configure(project(':loanApplicationService')) { @@ -92,3 +92,4 @@ configure(project(':loanApplicationService')) { generateAccurest.dependsOn('copyCollaboratorStubs') } + diff --git a/build.gradle b/build.gradle index 3ae3d0e265..835037077f 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ buildscript { repositories { mavenCentral() + mavenLocal() } dependencies { classpath "pl.allegro.tech.build:axion-release-plugin:1.2.2" From 07a74c2448b6ca90983ad36cb5c1544f0ad8e2cd Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 25 Jun 2015 17:47:11 +0200 Subject: [PATCH 176/719] Release version: 0.7.0 [ci skip] From 0d4644b96f32d09ca5b90ad4a697a7975974ccbe Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 6 Jul 2015 13:21:44 +0200 Subject: [PATCH 177/719] Fixed failure on empty String in the body. Added tests for this use case. --- .../accurest/util/ContentUtils.groovy | 6 + .../builder/SpockMethodBuilderSpec.groovy | 21 +- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 207 +++++++++++------- 3 files changed, 152 insertions(+), 82 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 59b4d726ee..b42cadcf5c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -34,6 +34,9 @@ class ContentUtils { * @return JSON structure with replaced client / server side parts */ public static Object extractValue(GString bodyAsValue, ContentType contentType, Closure valueProvider) { + if (bodyAsValue.isEmpty()){ + return bodyAsValue + } if (contentType == ContentType.JSON) { return extractValueForJSON(bodyAsValue, valueProvider) } @@ -164,6 +167,9 @@ class ContentUtils { } public static boolean isJsonType(GString gstring) { + if (gstring.isEmpty()) { + return false + } GString stringWithoutValues = new GStringImpl( gstring.values.collect({ it instanceof String || it instanceof GString ? it.toString() : escapeJson(it.toString()) 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 index 964f03811b..49c1d94981 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy @@ -286,5 +286,24 @@ class SpockMethodBuilderSpec extends Specification { spockTest.contains('responseBody.property2 == "b"') } - + def "should generate test for empty body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method('POST') + url("/ws/payments") + body("") + } + response { + status 406 + } + } + SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains(".body('')") + } } 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 e7e6886b5d..12aca1f271 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 @@ -111,7 +111,11 @@ class WireMockGroovyDslSpec extends WireMockSpec { headers { header("Content-Type": 'application/x-www-form-urlencoded') } - body("""paymentType=INCOMING&transferType=BANK&amount=${value(client(regex('[0-9]{3}\\.[0-9]{2}')), server(500.00))}&bookingDate=${value(client(regex('[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])')), server('2015-05-18'))}""") + body("""paymentType=INCOMING&transferType=BANK&amount=${ + value(client(regex('[0-9]{3}\\.[0-9]{2}')), server(500.00)) + }&bookingDate=${ + value(client(regex('[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])')), server('2015-05-18')) + }""") } response { status 204 @@ -290,7 +294,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } ''') and: - stubMappingIsValidWireMockStub(wireMockStub) + stubMappingIsValidWireMockStub(wireMockStub) } def 'should use equalToJson when content type ends with json'() { @@ -349,7 +353,9 @@ class WireMockGroovyDslSpec extends WireMockSpec { headers { header "Content-Type", "customtype/xml" } - body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + body """${value(client('Jozo'), server('Denis'))}${ + value(client(""), server('1234567890')) + }""" } response { status 200 @@ -389,7 +395,9 @@ class WireMockGroovyDslSpec extends WireMockSpec { request { method 'GET' url "/users" - body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + body """${value(client('Jozo'), server('Denis'))}${ + value(client(""), server('1234567890')) + }""" } response { status 200 @@ -427,7 +435,9 @@ class WireMockGroovyDslSpec extends WireMockSpec { } response { status 200 - body """${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""" + body """${value(client('Jozo'), server('Denis'))}${ + value(client(""), server('1234567890')) + }""" } } when: @@ -490,7 +500,9 @@ class WireMockGroovyDslSpec extends WireMockSpec { request { method 'GET' url "/users" - body equalToXml("""${value(client('Jozo'), server('Denis'))}${value(client(""), server('1234567890'))}""") + body equalToXml("""${value(client('Jozo'), server('Denis'))}${ + value(client(""), server('1234567890')) + }""") } response { status 200 @@ -522,28 +534,28 @@ class WireMockGroovyDslSpec extends WireMockSpec { def 'should convert groovy dsl stub with regexp Body as String to wireMock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - url $(client(regex('/[0-9]{2}')), server('/12')) - body """ + request { + method('GET') + url $(client(regex('/[0-9]{2}')), server('/12')) + body """ { "personalId": "${value(client(regex('^[0-9]{11}$')), server('57593728525'))}" } """ - } - response { - status 200 - body("""\ + } + response { + status 200 + body("""\ { "name": "Jan" } """ - ) - headers { - header 'Content-Type': 'text/plain' + ) + headers { + header 'Content-Type': 'text/plain' + } } } - } when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: @@ -827,43 +839,43 @@ class WireMockGroovyDslSpec extends WireMockSpec { def "should not allow regexp in query parameter for server value"() { when: - GroovyDsl.make { - request { - method 'GET' - url("abc") { - queryParameters { - parameter 'age': $(client(notMatching("^\\w*\$")), server(regex(".*"))) - } - } - } - response { - status 200 - } - } + GroovyDsl.make { + request { + method 'GET' + url("abc") { + queryParameters { + parameter 'age': $(client(notMatching("^\\w*\$")), server(regex(".*"))) + } + } + } + response { + status 200 + } + } then: - def e = thrown(IllegalStateException) - e.message.contains "Query parameter 'age' can't be a pattern for the server side" + def e = thrown(IllegalStateException) + e.message.contains "Query parameter 'age' can't be a pattern for the server side" } def "should not allow query parameter unresolvable for a server value"() { when: - GroovyDsl.make { - request { - method 'GET' - urlPath("users") { - queryParameters { - parameter 'age': notMatching("^\\w*\$") - parameter 'name': matching("Denis.*") - } - } - } - response { - status 200 - } - } + GroovyDsl.make { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'age': notMatching("^\\w*\$") + parameter 'name': matching("Denis.*") + } + } + } + response { + status 200 + } + } then: - def e = thrown(IllegalStateException) - e.message.contains "Query parameter 'age' can't be of a matching type: NOT_MATCHING for the server side" + def e = thrown(IllegalStateException) + e.message.contains "Query parameter 'age' can't be of a matching type: NOT_MATCHING for the server side" } def "should not allow query parameter with a different absent variation for server/client"() { @@ -874,45 +886,45 @@ class WireMockGroovyDslSpec extends WireMockSpec { e.message.contains "Absent cannot only be used only on one side" where: dsl << [ - { - request { - method 'GET' - urlPath("users") { - queryParameters { - parameter 'name': $(client(absent()), server("")) + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(absent()), server("")) + } } } - } - response { - status 200 - } - }, - { - request { - method 'GET' - urlPath("users") { - queryParameters { - parameter 'name': $(client(""), server(absent())) + response { + status 200 + } + }, + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(""), server(absent())) + } } } - } - response { - status 200 - } - }, - { - request { - method 'GET' - urlPath("users") { - queryParameters { - parameter 'name': $(client(absent()), server(matching("abc"))) + response { + status 200 + } + }, + { + request { + method 'GET' + urlPath("users") { + queryParameters { + parameter 'name': $(client(absent()), server(matching("abc"))) + } } } + response { + status 200 + } } - response { - status 200 - } - } ] } @@ -1107,6 +1119,39 @@ class WireMockGroovyDslSpec extends WireMockSpec { ''') } + def "should generate stub for empty body"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('POST') + url("test") + body("") + } + response { + status 406 + } + } + when: + def json = toWireMockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "request": { + "method": "POST", + "url": "test", + "bodyPatterns": [ + { + "equalTo": "" + } + ] + }, + "response": { + "status": 406 + } + } +''') + } + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } From 45741b7ed5bebf8aa76d40a08ef0e74e801ad67c Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 6 Jul 2015 13:39:20 +0200 Subject: [PATCH 178/719] Have completely removed the accurest version as it is not required. --- .../src/test/resources/functionalTest/bootSimple/build.gradle | 4 ---- .../resources/functionalTest/bootSimple/gradle.properties | 1 - .../test/resources/functionalTest/sampleProject/build.gradle | 1 - 3 files changed, 6 deletions(-) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index ee5c91b466..48929c705b 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -2,9 +2,6 @@ buildscript { repositories { mavenCentral() } - dependencies { - classpath "io.codearte.accurest:accurest-gradle-plugin:$accurestVersion" - } } apply plugin: 'groovy' @@ -49,7 +46,6 @@ dependencies { testCompile "org.spockframework:spock-spring:0.7-groovy-2.0" testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" - testCompile "io.codearte.accurest:accurest-core:$accurestVersion" testCompile "javax.servlet:javax.servlet-api:3.0.1" //provided testCompile "ch.qos.logback:logback-classic:1.1.2" } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties index 6e02ac3599..71fcc0538e 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties @@ -1,5 +1,4 @@ groupId=com.ofg jacksonMapper=1.9.13 restAssuredVersion=2.4.0 -accurestVersion=0.4.1 springVersion=4.1.4.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 90478ca0bd..068c0f6e47 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -5,7 +5,6 @@ buildscript { } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE") - classpath 'io.codearte.accurest:accurest-gradle-plugin:0.6.2' } } From b5b6586984d9277006a38260772d8e5c5b727e0c Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Wed, 15 Jul 2015 17:16:09 +0200 Subject: [PATCH 179/719] Add JAX-RS 2 Client API tests generation --- .../accurest/SingleTestGenerator.groovy | 7 +- .../JaxRsClientSpockMethodBodyBuilder.groovy | 95 +++++ .../accurest/builder/MethodBuilder.groovy | 26 +- .../MockMvcSpockMethodBodyBuilder.groovy | 77 ++++ .../builder/SpockMethodBodyBuilder.groovy | 252 ++++++------ .../codearte/accurest/config/TestMode.groovy | 2 +- .../codearte/accurest/util/ContentType.groovy | 12 +- .../JaxRsClientSpockMethodBuilderSpec.groovy | 362 ++++++++++++++++++ ...y => MockMvcSpockMethodBuilderSpec.groovy} | 24 +- .../plugin/SampleJerseyProjectSpec.groovy | 21 + .../sampleJerseyProject/build.gradle | 95 +++++ .../shouldMarkClientAsFraud.groovy | 27 ++ .../shouldMarkClientAsNotFraud.groovy | 28 ++ .../frauddetection/Application.java | 25 ++ .../FraudDetectionController.java | 38 ++ .../frauddetection/FraudRestApplication.java | 13 + .../frauddetection/model/FraudCheck.java | 29 ++ .../model/FraudCheckResult.java | 32 ++ .../model/FraudCheckStatus.java | 5 + .../src/main/resources/application.yml | 1 + .../com/blogspot/toomuchcoding/MvcSpec.groovy | 57 +++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 50514 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .../sampleJerseyProject/gradlew | 164 ++++++++ .../sampleJerseyProject/gradlew.bat | 90 +++++ .../loanApplicationService/mappings/.gitkeep | 0 .../frauddetection/Application.java | 17 + .../LoanApplicationService.java | 62 +++ .../frauddetection/model/Client.java | 14 + .../model/FraudCheckStatus.java | 5 + .../model/FraudServiceRequest.java | 34 ++ .../model/FraudServiceResponse.java | 27 ++ .../frauddetection/model/LoanApplication.java | 36 ++ .../model/LoanApplicationResult.java | 32 ++ .../model/LoanApplicationStatus.java | 5 + .../src/main/resources/application.yml | 1 + .../LoanApplicationServiceSpec.groovy | 50 +++ .../shouldMarkClientAsFraud.json | 23 ++ .../shouldMarkClientAsNotFraud.json | 23 ++ .../sampleJerseyProject/settings.gradle | 2 + 40 files changed, 1672 insertions(+), 147 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy rename accurest-core/src/test/groovy/io/codearte/accurest/builder/{SpockMethodBuilderSpec.groovy => MockMvcSpockMethodBuilderSpec.groovy} (87%) create mode 100755 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties create mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index bc6f35adde..2765d7114b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -11,6 +11,7 @@ import static io.codearte.accurest.builder.MethodBuilder.createTestMethod import static io.codearte.accurest.util.NamesUtil.capitalize class SingleTestGenerator { + private final AccurestConfigProperties configProperties SingleTestGenerator(AccurestConfigProperties configProperties) { @@ -34,7 +35,9 @@ class SingleTestGenerator { } } - if (configProperties.testMode == TestMode.MOCKMVC) { + if (configProperties.testMode == TestMode.JAXRSCLIENT) { + clazz.addStaticImport('javax.ws.rs.client.Entity.*') + } else if (configProperties.testMode == TestMode.MOCKMVC) { clazz.addStaticImport('com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*') } else { clazz.addStaticImport('com.jayway.restassured.RestAssured.*') @@ -52,7 +55,7 @@ class SingleTestGenerator { } listOfFiles.each { - clazz.addMethod(createTestMethod(it, configProperties.targetFramework)) + clazz.addMethod(createTestMethod(it, configProperties)) } return clazz.build() } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy new file mode 100644 index 0000000000..d3e07d7942 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy @@ -0,0 +1,95 @@ +package io.codearte.accurest.builder + +import groovy.transform.PackageScope +import groovy.transform.TypeChecked +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.internal.Header +import io.codearte.accurest.dsl.internal.QueryParameter + +@PackageScope +@TypeChecked +class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { + + JaxRsClientSpockMethodBodyBuilder(GroovyDsl stubDefinition) { + super(stubDefinition) + } + + @Override + protected void givenBlock(BlockBuilder bb) { + } + + @Override + protected void when(BlockBuilder bb) { + bb.addLine("def response = webTarget") + bb.indent() + + appendUrlPathAndQueryParameters(bb) + appendRequestWithRequiredResponseContentType(bb) + appendHeaders(bb) + appendMethodAndBody(bb) + + bb.unindent() + + bb.addEmptyLine() + bb.addLine("String responseAsString = response.readEntity(String)") + } + + protected void appendRequestWithRequiredResponseContentType(BlockBuilder bb) { + String acceptHeader = getHeader("Accept") + if (acceptHeader) { + bb.addLine(".request('$acceptHeader')") + } else { + bb.addLine(".request()") + } + } + + protected void appendUrlPathAndQueryParameters(BlockBuilder bb) { + if (request.url) { + bb.addLine(".path('$request.url.serverValue')") + } else if (request.urlPath) { + bb.addLine(".path('$request.urlPath.serverValue')") + request.urlPath.queryParameters?.parameters.findAll(this.&allowedQueryParameter).each { QueryParameter param -> + bb.addLine(".queryParam('$param.name', '${resolveParamValue(param).toString()}')") + } + } + } + + protected void appendMethodAndBody(BlockBuilder bb) { + String method = request.method.serverValue.toString().toLowerCase() + if (request.body) { + String contentType = getHeader('Content-Type') ?: getRequestContentType().mimeType + bb.addLine(".method('$method', entity('$bodyAsString', '$contentType'))") + } else { + bb.addLine(".method('$method')") + } + } + + protected appendHeaders(BlockBuilder bb) { + request.headers?.collect { Header header -> + if (header.name == 'Content-Type' || header.name == 'Accept') return // Particular headers are set via 'request' / 'entity' methods + bb.addLine(".header('${header.name}', '${header.serverValue}')") + } + } + + protected String getHeader(String name) { + return request.headers?.entries.find { it.name == name }?.serverValue + } + + @Override + protected void validateResponseCodeBlock(BlockBuilder bb) { + bb.addLine("response.status == $response.status.serverValue") + } + + @Override + protected void validateResponseHeadersBlock(BlockBuilder bb) { + response.headers?.collect { Header header -> + bb.addLine("response.getHeaderString('$header.name') == '$header.serverValue'") + } + } + + @Override + protected String getResponseAsString() { + return 'responseAsString' + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index dd791fb666..c4e8da6d04 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -1,7 +1,9 @@ package io.codearte.accurest.builder import groovy.util.logging.Slf4j +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.util.NamesUtil @@ -13,28 +15,36 @@ class MethodBuilder { private final String methodName private final GroovyDsl stubContent - private final TestFramework lang + private final AccurestConfigProperties configProperties - private MethodBuilder(String methodName, GroovyDsl stubContent, TestFramework lang) { + private MethodBuilder(String methodName, GroovyDsl stubContent, AccurestConfigProperties configProperties) { this.stubContent = stubContent this.methodName = methodName - this.lang = lang + this.configProperties = configProperties } - static MethodBuilder createTestMethod(File stubsFile, TestFramework lang) { + static MethodBuilder createTestMethod(File stubsFile, AccurestConfigProperties configProperties) { log.debug("Stub content from file [${stubsFile.text}]") GroovyDsl stubContent = new GroovyShell(this.classLoader).evaluate(stubsFile) log.debug("Stub content Groovy DSL [$stubContent]") String methodName = NamesUtil.camelCase(NamesUtil.toLastDot(NamesUtil.afterLast(stubsFile.path, File.separator))) - return new MethodBuilder(methodName, stubContent, lang) + return new MethodBuilder(methodName, stubContent, configProperties) } void appendTo(BlockBuilder blockBuilder) { - if (lang == TestFramework.JUNIT) { + if (configProperties.targetFramework == TestFramework.JUNIT) { blockBuilder.addLine('@Test') } - blockBuilder.addLine(lang.methodModifier + "$methodName() {") - new SpockMethodBodyBuilder(stubContent).appendTo(blockBuilder) + blockBuilder.addLine(configProperties.targetFramework.methodModifier + "$methodName() {") + getMethodBodyBuilder().appendTo(blockBuilder) blockBuilder.addLine('}') } + + private SpockMethodBodyBuilder getMethodBodyBuilder() { + if (configProperties.testMode == TestMode.JAXRSCLIENT) { + return new JaxRsClientSpockMethodBodyBuilder(stubContent) + } + return new MockMvcSpockMethodBodyBuilder(stubContent) + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy new file mode 100644 index 0000000000..40d6a24416 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -0,0 +1,77 @@ +package io.codearte.accurest.builder + +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.QueryParameter +import io.codearte.accurest.dsl.internal.Request +import io.codearte.accurest.dsl.internal.UrlPath + +@PackageScope +@TypeChecked +class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { + + MockMvcSpockMethodBodyBuilder(GroovyDsl stubDefinition) { + super(stubDefinition) + } + + protected void given(BlockBuilder bb) { + bb.addLine('def request = given()') + bb.indent() + request.headers?.collect { Header header -> + bb.addLine(".header('${header.name}', '${header.serverValue}')") + } + if (request.body) { + bb.addLine(".body('$bodyAsString')") + } + bb.unindent() + } + + protected void when(BlockBuilder bb) { + bb.addLine('def response = given().spec(request)') + bb.indent() + + String url = buildUrl(request) + String method = request.method.serverValue.toString().toLowerCase() + + bb.addLine(/.${method}("$url")/) + bb.unindent() + } + + protected void validateResponseCodeBlock(BlockBuilder bb) { + bb.addLine("response.statusCode == $response.status.serverValue") + } + + protected void validateResponseHeadersBlock(BlockBuilder bb) { + response.headers?.collect { Header header -> + bb.addLine("response.header('$header.name') == '$header.serverValue'") + } + } + + @Override + protected String getResponseAsString() { + return 'response.body.asString()' + } + + protected String buildUrl(Request request) { + if (request.url) + return request.url.serverValue; + if (request.urlPath) + return buildUrlFromUrlPath(request.urlPath) + throw new IllegalStateException("URL is not set!") + } + + @TypeChecked(TypeCheckingMode.SKIP) + protected String buildUrlFromUrlPath(UrlPath urlPath) { + String params = urlPath.queryParameters.parameters + .findAll(this.&allowedQueryParameter) + .inject([] as List) { List result, QueryParameter param -> + result << "${param.name}=${resolveParamValue(param).toString()}" + } + .join('&') + return "$urlPath.serverValue?$params" + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 7e7bb697bc..0101a64c9c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,16 +1,14 @@ 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.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.QueryParameter import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.dsl.internal.Response -import io.codearte.accurest.dsl.internal.UrlPath import io.codearte.accurest.util.ContentType import io.codearte.accurest.util.JsonConverter @@ -24,85 +22,95 @@ import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHea * @author Jakub Kubrynski */ @PackageScope -class SpockMethodBodyBuilder { - private final GroovyDsl stubDefinition +@TypeChecked +abstract class SpockMethodBodyBuilder { + + protected final Request request + protected final Response response SpockMethodBodyBuilder(GroovyDsl stubDefinition) { - this.stubDefinition = stubDefinition + this.request = stubDefinition.request + this.response = stubDefinition.response } void appendTo(BlockBuilder blockBuilder) { - Request request = stubDefinition.request - Response response = stubDefinition.response - blockBuilder.with { - startBlock() - addLine('given:').startBlock() - addLine('def request = given()') - indent() - request.headers?.collect { Header header -> - addLine(".header('${header.name}', '${header.serverValue}')") - } - if (request.body) { - Object bodyValue = extractServerValueFromBody(request.body.serverValue) - String matches = trimRepeatedQuotes(new JsonOutput().toJson(bodyValue)) - addLine(".body('$matches')") - } + blockBuilder.startBlock() - unindent().endBlock().addEmptyLine() + givenBlock(blockBuilder) + whenBlock(blockBuilder) + thenBlock(blockBuilder) - addLine('when:').startBlock() - addLine('def response = given().spec(request)') - indent() + blockBuilder.endBlock() + } - String url = buildUrl(request) - String method = request.method.serverValue.toLowerCase() + protected void thenBlock(BlockBuilder bb) { + bb.addLine('then:') + bb.startBlock() + then(bb) + bb.endBlock() + } - blockBuilder.addLine(/.${method}("$url")/) - unindent().endBlock().addEmptyLine() + protected void whenBlock(BlockBuilder bb) { + bb.addLine('when:') + bb.startBlock() + when(bb) + bb.endBlock().addEmptyLine() + } - addLine('then:').startBlock() - addLine("response.statusCode == $response.status.serverValue") + protected void givenBlock(BlockBuilder bb) { + bb.addLine('given:') + bb.startBlock() + given(bb) + bb.endBlock().addEmptyLine() + } - response.headers?.collect { Header header -> - addLine("response.header('$header.name') == '$header.serverValue'") - } - if (response.body) { - endBlock() - addLine('and:').startBlock() - def responseBody = response.body.serverValue - ContentType contentType = recognizeContentTypeFromHeader(response.headers) - if (contentType == ContentType.UNKNOWN) { - contentType = recognizeContentTypeFromContent(responseBody) - } - if (responseBody instanceof GString) { - responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) - } - if (contentType == ContentType.JSON) { - addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') - if (responseBody instanceof List) { - processArrayElements(responseBody, "", blockBuilder) - } else { - processMapElement(responseBody, blockBuilder, "") - } - } else if (contentType == ContentType.XML) { - addLine('def responseBody = new XmlSlurper().parseText(response.body.asString())') - // TODO xml validation - } - } - endBlock() + protected void given(BlockBuilder bb) {} - endBlock() + protected abstract void when(BlockBuilder bb) + + protected abstract void validateResponseCodeBlock(BlockBuilder bb) + + protected abstract void validateResponseHeadersBlock(BlockBuilder bb) + + protected abstract String getResponseAsString() + + protected void then(BlockBuilder bb) { + validateResponseCodeBlock(bb) + if (response.headers) { + validateResponseHeadersBlock(bb) + } + if (response.body) { + bb.endBlock() + bb.addLine('and:').startBlock() + validateResponseBodyBlock(bb) } } - private String trimRepeatedQuotes(String toTrim) { - if (toTrim.startsWith('"')) { - return toTrim.replaceAll('"', '') + protected void validateResponseBodyBlock(BlockBuilder bb) { + def responseBody = response.body.serverValue + ContentType contentType = getResponseContentType() + if (responseBody instanceof GString) { + responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) + } + if (contentType == ContentType.JSON) { + bb.addLine("def responseBody = new JsonSlurper().parseText($responseAsString)") + processBodyElement(bb, "", responseBody) + } else if (contentType == ContentType.XML) { + bb.addLine("def responseBody = new XmlSlurper().parseText($responseAsString)") + // TODO xml validation } - return toTrim } - private Object extractServerValueFromBody(bodyValue) { + protected String getBodyAsString() { + Object bodyValue = extractServerValueFromBody(request.body.serverValue) + return trimRepeatedQuotes(new JsonOutput().toJson(bodyValue)) + } + + protected String trimRepeatedQuotes(String toTrim) { + return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim + } + + protected Object extractServerValueFromBody(bodyValue) { if (bodyValue instanceof GString) { bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) } else { @@ -111,88 +119,86 @@ class SpockMethodBodyBuilder { return bodyValue } - private String buildUrl(Request request) { - if (request.url) - return request.url.serverValue; - if (request.urlPath) - return buildUrlFromUrlPath(request.urlPath) - throw new IllegalStateException("URL is not set!") - } - - private String buildUrlFromUrlPath(UrlPath urlPath) { - String params = urlPath.queryParameters.parameters - .findAll(this.&allowedQueryParameter) - .inject([]) { result, param -> - result << "${param.name}=${resolveParamValue(param).toString()}" - }.join('&') - return "$urlPath.serverValue?$params" - } - - private boolean allowedQueryParameter(QueryParameter param) { + protected boolean allowedQueryParameter(QueryParameter param) { return allowedQueryParameter(param.serverValue) } - private boolean allowedQueryParameter(MatchingStrategy matchingStrategy) { + protected boolean allowedQueryParameter(MatchingStrategy matchingStrategy) { return matchingStrategy.type != MatchingStrategy.Type.ABSENT } - private boolean allowedQueryParameter(Object o) { + protected boolean allowedQueryParameter(Object o) { return true } - private String resolveParamValue(QueryParameter param) { - resolveParamValue(param.serverValue) + protected String resolveParamValue(QueryParameter param) { + return resolveParamValue(param.serverValue) } - private String resolveParamValue(Object value) { - value.toString() + protected String resolveParamValue(Object value) { + return value.toString() } - private String resolveParamValue(MatchingStrategy matchingStrategy) { - matchingStrategy.serverValue.toString() + protected String resolveParamValue(MatchingStrategy matchingStrategy) { + return matchingStrategy.serverValue.toString() } - private void processBodyElement(BlockBuilder blockBuilder, String property, def value) { - if (value instanceof String) { - if (value.startsWith('$')) { - value = value.substring(1).replaceAll('\\$value', "responseBody$property") - blockBuilder.addLine(value) - } else { - blockBuilder.addLine("responseBody$property == \"${value}\"") - } - } else if (value instanceof Map) { - processMapElement(value, blockBuilder, property) - } else if (value instanceof Map.Entry) { - processEntryElement(blockBuilder, property, value) - } else if (value instanceof List) { - processArrayElements(value, property, blockBuilder) - } else if (value instanceof Pattern) { - blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${value}')") - } else if (value instanceof DslProperty) { - processBodyElement(blockBuilder, property, value.serverValue) - } else if (value instanceof ExecutionProperty) { - ExecutionProperty exec = (ExecutionProperty) value - blockBuilder.addLine("${exec.insertValue("responseBody$property")}") + protected void processBodyElement(BlockBuilder blockBuilder, String property, Object value) { + blockBuilder.addLine("responseBody$property == ${value}") + } + + protected void processBodyElement(BlockBuilder blockBuilder, String property, String value) { + if (value.startsWith('$')) { + value = value.substring(1).replaceAll('\\$value', "responseBody$property") + blockBuilder.addLine(value) } else { - blockBuilder.addLine("responseBody$property == ${value}") + blockBuilder.addLine("responseBody$property == \"${value}\"") } } - private void processMapElement(def value, BlockBuilder blockBuilder, String property) { - value.each { entry -> processEntryElement(blockBuilder, property, entry) } + protected void processBodyElement(BlockBuilder blockBuilder, String property, Pattern pattern) { + blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${pattern.pattern()}')") } - private def processEntryElement(BlockBuilder blockBuilder, String property, def entry) { - return processBodyElement(blockBuilder, property + "." + entry.key, entry.value) + protected void processBodyElement(BlockBuilder blockBuilder, String property, DslProperty dslProperty) { + processBodyElement(blockBuilder, property, dslProperty.serverValue) } - private void processArrayElements(List responseBody, String property, BlockBuilder blockBuilder) { - responseBody.eachWithIndex { - listElement, listIndex -> - listElement.each { entry -> - String prop = "$property[$listIndex]" ?: '' - processBodyElement(blockBuilder, prop, entry) - } + protected void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { + blockBuilder.addLine("${exec.insertValue("responseBody$property")}") + } + + protected void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) { + processBodyElement(blockBuilder, property + "." + entry.key, entry.value) + } + + protected void processBodyElement(BlockBuilder blockBuilder, String property, Map map) { + map.each { + processBodyElement(blockBuilder, property, it) } } + + protected void processBodyElement(BlockBuilder blockBuilder, String property, List list) { + list.eachWithIndex { listElement, listIndex -> + String prop = "$property[$listIndex]" ?: '' + processBodyElement(blockBuilder, prop, listElement) + } + } + + protected ContentType getRequestContentType() { + ContentType contentType = recognizeContentTypeFromHeader(request.headers) + if (contentType == ContentType.UNKNOWN) { + contentType = recognizeContentTypeFromContent(request.body.serverValue) + } + return contentType + } + + protected ContentType getResponseContentType() { + ContentType contentType = recognizeContentTypeFromHeader(response.headers) + if (contentType == ContentType.UNKNOWN) { + contentType = recognizeContentTypeFromContent(response.body.serverValue) + } + return contentType + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy index e8a232e37c..1c7732d49e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy @@ -4,5 +4,5 @@ package io.codearte.accurest.config * @author Jakub Kubrynski */ enum TestMode { - MOCKMVC, EXPLICIT + MOCKMVC, EXPLICIT, JAXRSCLIENT } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy index 142c93a945..7b9e402985 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy @@ -1,5 +1,15 @@ package io.codearte.accurest.util enum ContentType { - JSON, XML, UNKNOWN + + JSON("application/json"), + XML("application/xml"), + UNKNOWN("application/octet-stream") + + final String mimeType + + ContentType(String mimeType) { + this.mimeType = mimeType + } + } \ No newline at end of file diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy new file mode 100644 index 0000000000..6b39c26e8d --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -0,0 +1,362 @@ +package io.codearte.accurest.builder + +import io.codearte.accurest.dsl.GroovyDsl +import spock.lang.Issue +import spock.lang.Specification + +class JaxRsClientSpockMethodBuilderSpec 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" +}""" + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property2 == \"b\"") + } + + @Issue("#79") + def "should generate assertions for simple response body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property2[0].a == \"sth\"") + blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") + } + + @Issue("#82") + def "should generate proper request when body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + items: ['HOP'] + ) + } + response { + status 200 + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("entity('{\"items\":[\"HOP\"]}', 'application/json')") + } + + @Issue("#88") + def "should generate proper request when body constructed from GString"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + "property1=VAL1" + ) + } + response { + status 200 + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("entity('property1=VAL1', 'application/octet-stream')") + } + + 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" +}]""" + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(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"} + ] +}""" + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(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"} +} +''' + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property2.property3 == \"b\"") + } + + def "should generate regex assertions for map objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: "a", + property2: value( + client('123'), + server(regex('[0-9]{3}')) + ) + ) + headers { + header('Content-Type': 'application/json') + + } + + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + } + + def "should generate regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + headers { + header('Content-Type': 'application/json') + + } + + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + } + + def "should ignore 'Accept' header and use 'request' method"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + headers { + header("Accept", "text/plain") + } + } + response { + status 200 + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("request('text/plain')") + } + + def "should ignore 'Content-Type' header and use 'entity' method"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + headers { + header("Content-Type", "text/plain") + header("Timer", "123") + } + body '' + } + response { + status 200 + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("entity('', 'text/plain')") + blockBuilder.toString().contains("header('Timer', '123')") + !blockBuilder.toString().contains("header('Content-Type'") + + } + + def "should generate a call with an url path and query parameters"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains("queryParam('limit', '10'") + spockTest.contains("queryParam('offset', '20'") + spockTest.contains("queryParam('filter', 'email'") + spockTest.contains("queryParam('sort', 'name'") + spockTest.contains("queryParam('search', '55'") + spockTest.contains("queryParam('age', '99'") + spockTest.contains("queryParam('name', 'Denis.Stepanov'") + spockTest.contains("queryParam('email', 'bob@email.com'") + spockTest.contains('responseBody.property1 == "a"') + spockTest.contains('responseBody.property2 == "b"') + } + + def "should generate test for empty body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method('POST') + url("/ws/payments") + body("") + } + response { + status 406 + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains("entity('', 'application/octet-stream')") + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy similarity index 87% rename from accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 49c1d94981..55a43d2961 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/SpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -7,7 +7,7 @@ import spock.lang.Specification /** * @author Jakub Kubrynski */ -class SpockMethodBuilderSpec extends Specification { +class MockMvcSpockMethodBuilderSpec extends Specification { def "should generate assertions for simple response body"() { given: @@ -24,7 +24,7 @@ class SpockMethodBuilderSpec extends Specification { }""" } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -52,7 +52,7 @@ class SpockMethodBuilderSpec extends Specification { ) } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -77,7 +77,7 @@ class SpockMethodBuilderSpec extends Specification { status 200 } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -100,7 +100,7 @@ class SpockMethodBuilderSpec extends Specification { status 200 } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -126,7 +126,7 @@ class SpockMethodBuilderSpec extends Specification { }]""" } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -152,7 +152,7 @@ class SpockMethodBuilderSpec extends Specification { }""" } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -178,7 +178,7 @@ class SpockMethodBuilderSpec extends Specification { ''' } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -210,7 +210,7 @@ class SpockMethodBuilderSpec extends Specification { } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -236,7 +236,7 @@ class SpockMethodBuilderSpec extends Specification { } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -275,7 +275,7 @@ class SpockMethodBuilderSpec extends Specification { """ } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -298,7 +298,7 @@ class SpockMethodBuilderSpec extends Specification { status 406 } } - SpockMethodBodyBuilder builder = new SpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy new file mode 100755 index 0000000000..789d897199 --- /dev/null +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -0,0 +1,21 @@ +package io.codearte.accurest.plugin + +import nebula.test.IntegrationSpec +import spock.lang.Stepwise + +@Stepwise +class SampleJerseyProjectSpec extends IntegrationSpec { + + void setup() { + copyResources("functionalTest/sampleJerseyProject", "") + runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it + } + + def "should pass basic flow"() { + given: + assert fileExists('build.gradle') + expect: + runTasksSuccessfully('check') + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle new file mode 100644 index 0000000000..0ae605c532 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -0,0 +1,95 @@ +buildscript { + repositories { + mavenLocal() + mavenCentral() + } + dependencies { + classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE" + } +} + +ext { + spockVersion = '0.7-groovy-2.0' + restAssuredVersion = '2.4.0' + + accurestStubsBaseDirectory = 'src/test/resources/stubs' +} + +subprojects { + apply plugin: 'groovy' + + + repositories { + mavenCentral() + mavenLocal() + } + + dependencies { + testCompile "org.codehaus.groovy:groovy-all:2.3.7" + testCompile "org.spockframework:spock-core:$spockVersion" + testCompile("junit:junit:4.12") + testCompile('com.github.tomakehurst:wiremock:1.52') { + exclude group: 'org.mortbay.jetty', module: 'servlet-api' + } + } +} + +configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { + apply plugin: 'spring-boot' + apply plugin: 'accurest' + + ext { + wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") + wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'mappings/') + } + + accurest { + targetFramework = 'Spock' + testMode = 'JaxRsClient' + baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' + contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") + generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") + stubsOutputDir = wireMockStubsOutputDir + } + + jar { + version = '0.0.1' + } + + dependencies { + compile "javax.ws.rs:javax.ws.rs-api:2.0.1" + compile 'org.glassfish.jersey.containers:jersey-container-jetty-http:2.15' + compile('org.springframework.boot:spring-boot-starter-jersey:1.2.5.RELEASE') { + exclude module: "spring-boot-starter-tomcat" + } + compile 'org.springframework.boot:spring-boot-starter-jetty:1.2.5.RELEASE' + + testRuntime "org.spockframework:spock-spring:$spockVersion" + + compile 'org.glassfish.jersey.connectors:jersey-apache-connector:2.15' + testCompile 'org.springframework:spring-test:4.1.7.RELEASE' + } + + task cleanup(type: Delete) { + delete 'src/test/resources/mappings', 'src/test/resources/stubs' + } + + clean.dependsOn('cleanup') + +} + +configure(project(':fraudDetectionService')) { + test.dependsOn('generateWireMockClientStubs') +} + +configure(project(':loanApplicationService')) { + + task copyCollaboratorStubs(type: Copy) { + File fraudBuildDir = project(':fraudDetectionService').buildDir + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) + into "src/test/resources/" + } + + generateAccurest.dependsOn('copyCollaboratorStubs') +} + diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy new file mode 100644 index 0000000000..a47dff32e4 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy @@ -0,0 +1,27 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy new file mode 100644 index 0000000000..fa8cd88ade --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy @@ -0,0 +1,28 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java new file mode 100644 index 0000000000..2089bda142 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -0,0 +1,25 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import org.glassfish.jersey.client.HttpUrlConnectorProvider; +import org.glassfish.jersey.server.ResourceConfig; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + ResourceConfig resourceConfig() { + return ResourceConfig.forApplication(new FraudRestApplication()); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java new file mode 100644 index 0000000000..bb015f08a4 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java @@ -0,0 +1,38 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheck; +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckResult; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestBody; + +import javax.ws.rs.*; +import java.math.BigDecimal; + +import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.FRAUD; +import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.OK; + +@Controller +@Path("/") +public class FraudDetectionController { + + private static final String FRAUD_SERVICE_JSON_VERSION_1 = "application/vnd.fraud.v1+json"; + private static final String NO_REASON = null; + private static final String AMOUNT_TOO_HIGH = "Amount too high"; + private static final BigDecimal MAX_AMOUNT = new BigDecimal("5000"); + + @PUT + @Path("/fraudcheck") + @Produces(FRAUD_SERVICE_JSON_VERSION_1) + @Consumes(FRAUD_SERVICE_JSON_VERSION_1) + public FraudCheckResult fraudCheck(@RequestBody(required = false) FraudCheck fraudCheck) { + if (amountGreaterThanThreshold(fraudCheck)) { + return new FraudCheckResult(FRAUD, AMOUNT_TOO_HIGH); + } + return new FraudCheckResult(OK, NO_REASON); + } + + private boolean amountGreaterThanThreshold(FraudCheck fraudCheck) { + return MAX_AMOUNT.compareTo(fraudCheck.getLoanAmount()) < 0; + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java new file mode 100644 index 0000000000..ce70aa1050 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java @@ -0,0 +1,13 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import java.util.Collections; +import java.util.Set; + +public class FraudRestApplication extends javax.ws.rs.core.Application { + + @Override + public Set> getClasses() { + return Collections.>singleton(FraudDetectionController.class); + } + +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java new file mode 100644 index 0000000000..77471aee19 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java @@ -0,0 +1,29 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class FraudCheck { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudCheck() { + } + + public String getClientPesel() { + return clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java new file mode 100644 index 0000000000..28efc573f5 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java @@ -0,0 +1,32 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class FraudCheckResult { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudCheckResult() { + } + + public FraudCheckResult(FraudCheckStatus fraudCheckStatus, String rejectionReason) { + this.fraudCheckStatus = fraudCheckStatus; + this.rejectionReason = rejectionReason; + } + + public FraudCheckStatus getFraudCheckStatus() { + return fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b87c365d51 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml new file mode 100644 index 0000000000..a30a91f034 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml @@ -0,0 +1 @@ +server.port=8085 \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy new file mode 100644 index 0000000000..621d20ded4 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy @@ -0,0 +1,57 @@ +package com.blogspot.toomuchcoding +import com.blogspot.toomuchcoding.frauddetection.Application +import com.blogspot.toomuchcoding.frauddetection.FraudRestApplication +import org.eclipse.jetty.server.Server +import org.glassfish.jersey.apache.connector.ApacheConnectorProvider +import org.glassfish.jersey.client.ClientConfig +import org.glassfish.jersey.jetty.JettyHttpContainerFactory +import org.glassfish.jersey.server.ResourceConfig +import org.springframework.context.annotation.AnnotationConfigApplicationContext +import spock.lang.Shared +import spock.lang.Specification + +import javax.ws.rs.client.Client +import javax.ws.rs.client.ClientBuilder +import javax.ws.rs.client.WebTarget +import javax.ws.rs.core.UriBuilder + +import static org.springframework.util.SocketUtils.findAvailableTcpPort + +abstract class MvcSpec extends Specification { + + @Shared + WebTarget webTarget + + @Shared + private Server server + + @Shared + private Client client + + def setupSpec() { + + URI baseUri = UriBuilder.fromUri("http://localhost").port(findAvailableTcpPort(8000)).build() + + + ResourceConfig resourceConfig = ResourceConfig.forApplication(new FraudRestApplication()) + resourceConfig.property("contextConfig", new AnnotationConfigApplicationContext(Application)) + server = JettyHttpContainerFactory.createServer(baseUri, resourceConfig, true) + + ClientConfig clientConfig = new ClientConfig() + clientConfig.connectorProvider(new ApacheConnectorProvider()) + client = ClientBuilder.newClient(clientConfig) + + webTarget = client.target(baseUri) + + server.start() + } + + def cleanupSpec() { + client?.close() + server?.stop() + } + + void assertThatRejectionReasonIsNull(def rejectionReason) { + assert !rejectionReason + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..667288ad6c2b3b87c990ece1267e56f0bcbf3622 GIT binary patch literal 50514 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +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"` + + # 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 "$@" diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat new file mode 100644 index 0000000000..8a0b282aa6 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat @@ -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 Windowz 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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java new file mode 100644 index 0000000000..5a1a60244e --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -0,0 +1,17 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java new file mode 100644 index 0000000000..82476a3a46 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java @@ -0,0 +1,62 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus; +import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceRequest; +import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceResponse; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class LoanApplicationService { + + private static final String FRAUD_SERVICE_JSON_VERSION_1 = + "application/vnd.fraud.v1+json"; + + private final RestTemplate restTemplate; + + public LoanApplicationService() { + this.restTemplate = new RestTemplate(); + } + + public LoanApplicationResult loanApplication(LoanApplication loanApplication) { + FraudServiceRequest request = + new FraudServiceRequest(loanApplication); + + FraudServiceResponse response = + sendRequestToFraudDetectionService(request); + + return buildResponseFromFraudResult(response); + } + + private FraudServiceResponse sendRequestToFraudDetectionService( + FraudServiceRequest request) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1); + + ResponseEntity response = + restTemplate.exchange("http://localhost:8080/fraudcheck", HttpMethod.PUT, + new HttpEntity<>(request, httpHeaders), + FraudServiceResponse.class); + + return response.getBody(); + } + + private LoanApplicationResult buildResponseFromFraudResult(FraudServiceResponse response) { + LoanApplicationStatus applicationStatus = null; + if (FraudCheckStatus.OK == response.getFraudCheckStatus()) { + applicationStatus = LoanApplicationStatus.LOAN_APPLIED; + } else if (FraudCheckStatus.FRAUD == response.getFraudCheckStatus()) { + applicationStatus = LoanApplicationStatus.LOAN_APPLICATION_REJECTED; + } + + return new LoanApplicationResult(applicationStatus, response.getRejectionReason()); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java new file mode 100644 index 0000000000..5e91273eda --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java @@ -0,0 +1,14 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class Client { + + private String pesel; + + public String getPesel() { + return pesel; + } + + public void setPesel(String pesel) { + this.pesel = pesel; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b87c365d51 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java new file mode 100644 index 0000000000..ac595998bc --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java @@ -0,0 +1,34 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class FraudServiceRequest { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudServiceRequest() { + } + + public FraudServiceRequest(LoanApplication loanApplication) { + this.clientPesel = loanApplication.getClient().getPesel(); + this.loanAmount = loanApplication.getAmount(); + } + + public String getClientPesel() { + return clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java new file mode 100644 index 0000000000..9f3353ecbf --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java @@ -0,0 +1,27 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class FraudServiceResponse { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudServiceResponse() { + } + + public FraudCheckStatus getFraudCheckStatus() { + return fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java new file mode 100644 index 0000000000..816087988b --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java @@ -0,0 +1,36 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class LoanApplication { + + private Client client; + + private BigDecimal amount; + + private String loanApplicationId; + + public Client getClient() { + return client; + } + + public void setClient(Client client) { + this.client = client; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + public String getLoanApplicationId() { + return loanApplicationId; + } + + public void setLoanApplicationId(String loanApplicationId) { + this.loanApplicationId = loanApplicationId; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java new file mode 100644 index 0000000000..523f4f2ea3 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java @@ -0,0 +1,32 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class LoanApplicationResult { + + private LoanApplicationStatus loanApplicationStatus; + + private String rejectionReason; + + public LoanApplicationResult() { + } + + public LoanApplicationResult(LoanApplicationStatus loanApplicationStatus, String rejectionReason) { + this.loanApplicationStatus = loanApplicationStatus; + this.rejectionReason = rejectionReason; + } + + public LoanApplicationStatus getLoanApplicationStatus() { + return loanApplicationStatus; + } + + public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) { + this.loanApplicationStatus = loanApplicationStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java new file mode 100644 index 0000000000..7f7f86e0ea --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum LoanApplicationStatus { + LOAN_APPLIED, LOAN_APPLICATION_REJECTED +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml new file mode 100644 index 0000000000..e86bbd0e0f --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml @@ -0,0 +1 @@ +server.port=8090 \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy new file mode 100644 index 0000000000..58d17673ce --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy @@ -0,0 +1,50 @@ +package com.blogspot.toomuchcoding + +import com.blogspot.toomuchcoding.frauddetection.Application +import com.blogspot.toomuchcoding.frauddetection.LoanApplicationService +import com.blogspot.toomuchcoding.frauddetection.model.Client +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus +import com.github.tomakehurst.wiremock.junit.WireMockClassRule +import org.junit.ClassRule +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.test.context.ContextConfiguration +import spock.lang.Shared +import spock.lang.Specification + +@ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) +class LoanApplicationServiceSpec extends Specification { + + @ClassRule + @Shared + WireMockClassRule wireMockRule = new WireMockClassRule() + + @Autowired + LoanApplicationService sut + + def 'should successfully apply for loan'() { + given: + LoanApplication application = + new LoanApplication(client: new Client(pesel: '1234567890'), amount: 123.123) + when: + LoanApplicationResult loanApplication = sut.loanApplication(application) + then: + loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED + loanApplication.rejectionReason == null + } + + def 'should be rejected due to abnormal loan amount'() { + given: + LoanApplication application = + new LoanApplication(client: new Client(pesel: '1234567890'), amount: 99_999) + when: + LoanApplicationResult loanApplication = sut.loanApplication(application) + then: + loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLICATION_REJECTED + loanApplication.rejectionReason == 'Amount too high' + } + + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json new file mode 100644 index 0000000000..90383f2ce1 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "\\s*\\{\\s*\"clientPesel\"\\s*:\\s*\"?[0-9]{10}\"?\\s*,\\s*\"loanAmount\"\\s*:\\s*\"?99999\"?\\s*\\}\\s*" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json new file mode 100644 index 0000000000..2f47855910 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "\\s*\\{\\s*\"clientPesel\"\\s*:\\s*\"?[0-9]{10}\"?\\s*,\\s*\"loanAmount\"\\s*:\\s*\"?123.123\"?\\s*\\}\\s*" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle new file mode 100644 index 0000000000..6a42a6c7ce --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle @@ -0,0 +1,2 @@ +include ':fraudDetectionService' +include ':loanApplicationService' From 179b78c5c38d8921712c8035be1afd2d21f06116 Mon Sep 17 00:00:00 2001 From: Kamil Szymanski Date: Mon, 27 Jul 2015 11:05:43 +0200 Subject: [PATCH 180/719] Allow using single quotes for quoting in stub definitions --- .../wiremock/WireMockToDslConverter.groovy | 8 +++++++- .../wiremock/WireMockToDslConverterSpec.groovy | 16 +++++++--------- build.gradle | 4 ++-- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy index 689edb3d9a..2b377c7e3a 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy @@ -1,6 +1,8 @@ package io.codearte.accurest.wiremock + import groovy.io.FileType import groovy.json.JsonOutput +import groovy.json.JsonParserType import groovy.json.JsonSlurper import groovy.xml.XmlUtil import io.codearte.accurest.dsl.GroovyDsl @@ -14,7 +16,7 @@ class WireMockToDslConverter { } private String convertFromWireMockStub(String wireMockStringStub) { - Object wireMockStub = new JsonSlurper().parseText(wireMockStringStub) + Object wireMockStub = parseStubDefinition(wireMockStringStub) def request = wireMockStub.request def response = wireMockStub.response def bodyPatterns = request.bodyPatterns @@ -55,6 +57,10 @@ class WireMockToDslConverter { """ } + private Object parseStubDefinition(String wireMockStringStub) { + new JsonSlurper().setType(JsonParserType.LAX).parseText(wireMockStringStub) + } + private String buildHeader(String method, Object value) { switch (method) { case 'equalTo': diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy index 9cb1e9813f..cec123a88d 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy @@ -24,7 +24,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" } @@ -74,7 +74,7 @@ class WireMockToDslConverterSpec extends Specification { } - def 'should convert WireMock stub with response body containing simple JSON'() { + def 'should convert WireMock stub with response body containing JSON with escaped double quotes'() { given: String wireMockStub = '''\ { @@ -193,7 +193,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" } @@ -232,7 +232,6 @@ class WireMockToDslConverterSpec extends Specification { }""") == expectedGroovyDsl } - def 'should convert WireMock stub with response body containing a nested list'() { given: String wireMockStub = '''\ @@ -248,7 +247,7 @@ class WireMockToDslConverterSpec extends Specification { }, "response": { "status": 200, - "body":"[{\\"amount\\":1.01,\\"name\\":\\"Name\\",\\"info\\":{\\"title\\":\\"title1\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null},{\\"amount\\":2.01,\\"name\\":\\"Name2\\",\\"info\\":{\\"title\\":\\"title2\\",\\"payload\\":null},\\"booleanvalue\\":true,\\"user\\":null}]" + "body": '[{"amount":1.01, "name":"Name", "info":{"title":"title1", "payload":null}, "booleanvalue":true, "user":null}, {"amount":2.01, "name":"Name2", "info":{"title":"title2", "payload":null}, "booleanvalue":true, "user":null}]' } } ''' @@ -306,7 +305,7 @@ class WireMockToDslConverterSpec extends Specification { "method": "POST", "url": "/test", "bodyPatterns": [{ - "equalTo": "{\\"property1\\":\\"abc\\",\\"property2\\":\\"2017-01\\",\\"property3\\":\\"666\\",\\"property4\\":1428566412}" + "equalTo": '{"property1":"abc", "property2":"2017-01", "property3":"666", "property4":1428566412}' }] }, "response": { @@ -386,7 +385,7 @@ class WireMockToDslConverterSpec extends Specification { "url" : "/test", "method" : "POST", "bodyPatterns" : [ { - "equalToJson" : "{\\"pan\\":\\"4855141150107894\\",\\"expirationDate\\":\\"2017-01\\",\\"dcvx\\":\\"178\\"}", + "equalToJson" : '{"pan":"4855141150107894", "expirationDate":"2017-01", "dcvx":"178"}', "jsonCompareMode" : "LENIENT" } ] }, @@ -427,7 +426,7 @@ class WireMockToDslConverterSpec extends Specification { "url" : "/test", "method" : "POST", "bodyPatterns" : [ { - "equalTo" : "{\\"pan\\":\\"4855141150107894\\",\\"expirationDate\\":\\"2017-01\\",\\"dcvx\\":\\"178\\"}" + "equalTo" : '{"pan":"4855141150107894", "expirationDate":"2017-01", "dcvx":"178"}' } ] }, "response" : { @@ -502,5 +501,4 @@ class WireMockToDslConverterSpec extends Specification { void stubMappingIsValidWireMockStub(String mappingDefinition) { StubMapping.buildFrom(mappingDefinition) } - } diff --git a/build.gradle b/build.gradle index 835037077f..8b8d47bb77 100644 --- a/build.gradle +++ b/build.gradle @@ -91,7 +91,7 @@ project(':accurest-core') { compile 'org.apache.commons:commons-lang3:[3.3,)' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - testCompile 'com.github.tomakehurst:wiremock:1.53' + testCompile 'com.github.tomakehurst:wiremock:1.57' } } @@ -101,7 +101,7 @@ project(':accurest-converters') { compile 'org.apache.commons:commons-lang3:[3.0,)' compile 'commons-io:commons-io:[2.0,)' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger - testCompile 'com.github.tomakehurst:wiremock:1.53' + testCompile 'com.github.tomakehurst:wiremock:1.57' testCompile 'org.hamcrest:hamcrest-all:1.3' } } From 3ad8b5800450ca4b821cc94c2480609e82bd8852 Mon Sep 17 00:00:00 2001 From: "konrad.dobrzynski" Date: Tue, 28 Jul 2015 10:33:17 +0200 Subject: [PATCH 181/719] [#108] Added possibility to validate against single value --- .../codearte/accurest/wiremock/RecursiveFilesConverter.groovy | 2 +- .../codearte/accurest/builder/SpockMethodBodyBuilder.groovy | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy index 5eb8f81d45..0f74866305 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy @@ -33,7 +33,7 @@ class RecursiveFilesConverter { File newGroovyFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) newGroovyFile.text = convertedContent } catch (Exception e) { - throw new ConversionAccurestException("Unable to convertion of ${sourceFile.name}", e) + throw new ConversionAccurestException("Unable to make convertion of ${sourceFile.name}", e) } } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 7e7bb697bc..1b26c272ab 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -81,8 +81,10 @@ class SpockMethodBodyBuilder { addLine('def responseBody = new JsonSlurper().parseText(response.body.asString())') if (responseBody instanceof List) { processArrayElements(responseBody, "", blockBuilder) - } else { + } else if (responseBody instanceof Map) { processMapElement(responseBody, blockBuilder, "") + } else { + processBodyElement(blockBuilder, '', responseBody) } } else if (contentType == ContentType.XML) { addLine('def responseBody = new XmlSlurper().parseText(response.body.asString())') From 722bf280166a9ceda88aa28c13d832c3db0bc4d9 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 28 Jul 2015 11:33:18 +0200 Subject: [PATCH 182/719] Release version: 0.7.2 [ci skip] From 3a8baa2212d810bdecaeccef0c1338169bf6bc09 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Fri, 31 Jul 2015 13:14:36 +0200 Subject: [PATCH 183/719] #106 has changed the logic in test method generation and the fix from #109 will not work anymore. Modified it to make single value validation possible. Added tests. --- .../builder/SpockMethodBodyBuilder.groovy | 3 +++ .../JaxRsClientSpockMethodBuilderSpec.groovy | 22 +++++++++++++++++++ .../MockMvcSpockMethodBuilderSpec.groovy | 22 +++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 0101a64c9c..f0d29ebefe 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -98,6 +98,9 @@ abstract class SpockMethodBodyBuilder { } else if (contentType == ContentType.XML) { bb.addLine("def responseBody = new XmlSlurper().parseText($responseAsString)") // TODO xml validation + } else { + bb.addLine("def responseBody = ($responseAsString)") + processBodyElement(bb, "", responseBody) } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index 6b39c26e8d..f7e0b7d777 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -359,4 +359,26 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: spockTest.contains("entity('', 'application/octet-stream')") } + + def "should generate test for String in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "POST" + url "test" + } + response { + status 200 + body "test" + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('def responseBody = (response.body.asString())') + spockTest.contains('responseBody == "test"') + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 55a43d2961..57d840710c 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -306,4 +306,26 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: spockTest.contains(".body('')") } + + def "should generate test for String in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "POST" + url "test" + } + response { + status 200 + body "test" + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('def responseBody = (response.body.asString())') + spockTest.contains('responseBody == "test"') + } } From 9ccc2a2b8a2025b32e39e69504d43c3c48df657c Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 4 Aug 2015 23:22:39 +0200 Subject: [PATCH 184/719] Support for stub priority --- .../wiremock/WireMockToDslConverter.groovy | 2 + .../WireMockToDslConverterSpec.groovy | 38 +++++++++++++++++++ .../io/codearte/accurest/dsl/GroovyDsl.groovy | 5 +++ .../accurest/dsl/WireMockStubStrategy.groovy | 14 +++++-- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 29 ++++++++++++++ 5 files changed, 85 insertions(+), 3 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy index 2b377c7e3a..e7a2a45f97 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 @@ -17,11 +17,13 @@ class WireMockToDslConverter { private String convertFromWireMockStub(String wireMockStringStub) { Object wireMockStub = parseStubDefinition(wireMockStringStub) + Integer priority = wireMockStub.priority def request = wireMockStub.request def response = wireMockStub.response def bodyPatterns = request.bodyPatterns String urlPattern = request.urlPattern return """\ + ${priority ? "priority ${priority}" : ''} request { ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy index cec123a88d..80e8592276 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy @@ -498,6 +498,44 @@ class WireMockToDslConverterSpec extends Specification { evaluatedGroovyDsl == expectedGroovyDsl } + def 'should convert WireMock stub with priorities'() { + given: + String wireMockStub = '''\ + { + "priority" : 2, + "request" : { + "url" : "/test", + "method" : "POST" + }, + "response" : { + "status" : 200 + } + } + ''' + and: + stubMappingIsValidWireMockStub(wireMockStub) + and: + GroovyDsl expectedGroovyDsl = GroovyDsl.make { + priority 2 + request { + method 'POST' + url '/test' + } + response { + status 200 + } + } + when: + String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) + then: + GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + """ io.codearte.accurest.dsl.GroovyDsl.make { + $groovyDsl + }""") + and: + evaluatedGroovyDsl == expectedGroovyDsl + } + void stubMappingIsValidWireMockStub(String mappingDefinition) { StubMapping.buildFrom(mappingDefinition) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy index 1007e14cec..93f65f6678 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy @@ -11,6 +11,7 @@ import io.codearte.accurest.dsl.internal.Response @ToString(includeFields = true, includePackage = false, includeNames = true) class GroovyDsl { + Integer priority Request request Response response @@ -21,6 +22,10 @@ class GroovyDsl { return dsl } + void priority(int priority) { + this.priority = new Integer(priority) + } + void request(@DelegatesTo(Request) Closure closure) { this.request = new Request() closure.delegate = request diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy index 1793b8e61c..acff79a11a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest.dsl import groovy.json.JsonOutput +import groovy.transform.CompileDynamic import groovy.transform.CompileStatic @CompileStatic @@ -8,14 +9,21 @@ class WireMockStubStrategy { private final WireMockRequestStubStrategy wireMockRequestStubStrategy private final WireMockResponseStubStrategy wireMockResponseStubStrategy + private final Integer priority WireMockStubStrategy(GroovyDsl groovyDsl) { this.wireMockRequestStubStrategy = new WireMockRequestStubStrategy(groovyDsl) this.wireMockResponseStubStrategy = new WireMockResponseStubStrategy(groovyDsl) + this.priority = groovyDsl.priority } + @CompileDynamic String toWireMockClientStub() { - return JsonOutput.prettyPrint(JsonOutput.toJson([request : wireMockRequestStubStrategy.buildClientRequestContent(), - response: wireMockResponseStubStrategy.buildClientResponseContent()])) + def wiremockStubDefinition = [request : wireMockRequestStubStrategy.buildClientRequestContent(), + response: wireMockResponseStubStrategy.buildClientResponseContent()] + if (priority) { + wiremockStubDefinition.priority = priority + } + return JsonOutput.prettyPrint(JsonOutput.toJson(wiremockStubDefinition)) } -} +} \ No newline at end of file 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 12aca1f271..ced69beeb1 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 @@ -1152,6 +1152,35 @@ class WireMockGroovyDslSpec extends WireMockSpec { ''') } + def "should generate stub with priority"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + priority 9 + request { + method('POST') + url("test") + } + response { + status 406 + } + } + when: + def json = toWireMockClientJsonStub(groovyDsl) + then: + parseJson(json) == parseJson(''' + { + "priority": 9, + "request": { + "method": "POST", + "url": "test" + }, + "response": { + "status": 406 + } + } + ''') + } + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } From e3733dd6c32b1d26bb3d03f8fcb7aab00f1c82a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Wed, 5 Aug 2015 11:08:41 +0200 Subject: [PATCH 185/719] small code improvment --- .../src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy index 93f65f6678..af046d188f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy @@ -23,7 +23,7 @@ class GroovyDsl { } void priority(int priority) { - this.priority = new Integer(priority) + this.priority = priority } void request(@DelegatesTo(Request) Closure closure) { From 0109ce42338ca085db04116c890648e29dae7d52 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 5 Aug 2015 16:19:03 +0200 Subject: [PATCH 186/719] Added priority to the sample project DSL and test. Changes in tests to reflect stub-priority feature added by @mariuszs. --- .../io/codearte/accurest/plugin/BasicFunctionalSpec.groovy | 1 + .../pairId/colleratePlacesFromTweet.groovy | 1 + 2 files changed, 2 insertions(+) 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 d488f03ff4..ce2d32dafe 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 @@ -43,6 +43,7 @@ class BasicFunctionalSpec extends IntegrationSpec { def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text new JsonSlurper().parseText(generatedClientJsonStub) == new JsonSlurper().parseText(""" { + "priority: 2", "request": { "method": "PUT", "headers": { 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 08b137a054..6fe36c6a89 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,5 @@ io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 request { method 'PUT' url '/api/12' From daa3ccb7ea0a55f6af16c17aeac702f8d73a7222 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 5 Aug 2015 18:01:03 +0200 Subject: [PATCH 187/719] [#113] Fixed missing regex in headers --- .../MockMvcSpockMethodBodyBuilder.groovy | 12 ++++++- .../MockMvcSpockMethodBuilderSpec.groovy | 33 +++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index 40d6a24416..d686bcc54e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -9,6 +9,8 @@ import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.dsl.internal.UrlPath +import java.util.regex.Pattern + @PackageScope @TypeChecked class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { @@ -46,10 +48,18 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { protected void validateResponseHeadersBlock(BlockBuilder bb) { response.headers?.collect { Header header -> - bb.addLine("response.header('$header.name') == '$header.serverValue'") + bb.addLine("response.header('$header.name') ${convertHeaderComparison(header.serverValue)}") } } + private String convertHeaderComparison(Object headerValue) { + return " == '$headerValue'" + } + + private String convertHeaderComparison(Pattern headerValue) { + return "==~ java.util.regex.Pattern.compile('$headerValue')" + } + @Override protected String getResponseAsString() { return 'response.body.asString()' diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 57d840710c..d29c1f87b5 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -328,4 +328,37 @@ class MockMvcSpockMethodBuilderSpec extends Specification { spockTest.contains('def responseBody = (response.body.asString())') spockTest.contains('responseBody == "test"') } + + @Issue('113') + def "should generate regex test for String in response header"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'POST' + url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) + headers { header 'Content-Type': 'application/json' } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex('http://localhost/partners/[0-9]+/users/[0-9]+'))) + } + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''') + } } From 96aae0895c0b84d5dca9a25af04390db0a6ba6c7 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 7 Aug 2015 14:33:48 +0200 Subject: [PATCH 188/719] test fix, bad sample json --- .../io/codearte/accurest/plugin/BasicFunctionalSpec.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 ce2d32dafe..5b101daa03 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 @@ -43,7 +43,7 @@ class BasicFunctionalSpec extends IntegrationSpec { def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text new JsonSlurper().parseText(generatedClientJsonStub) == new JsonSlurper().parseText(""" { - "priority: 2", + "priority": 2, "request": { "method": "PUT", "headers": { From d940265111de53438bfba00e4433c7c6b51da6bb Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 7 Aug 2015 14:35:07 +0200 Subject: [PATCH 189/719] Release version: 0.8.1 [ci skip] From b51dd53b7bc8350ca136d9e01e2e5a1c56e5c24a Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 7 Aug 2015 14:36:01 +0200 Subject: [PATCH 190/719] Release version: 0.8.1 [ci skip] From e0436ace9fd62744b12b17994dc51eb9e455537d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 7 Aug 2015 21:38:54 +0200 Subject: [PATCH 191/719] [#115] added possibility to have some predefined regex --- .../accurest/dsl/internal/Common.groovy | 10 ++-- .../dsl/internal/RegexPatterns.groovy | 30 +++++++++++ .../MockMvcSpockMethodBuilderSpec.groovy | 33 ++++++++++++ .../dsl/internal/RegexPatternsSpec.groovy | 53 +++++++++++++++++++ 4 files changed, 122 insertions(+), 4 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 87d509de59..9030d9b9f3 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -13,6 +13,8 @@ import java.util.regex.Pattern @PackageScope class Common { + @Delegate private final RegexPatterns regexPatterns = new RegexPatterns() + Map convertObjectsToDslProperties(Map body) { return body.collectEntries { Map.Entry entry -> @@ -80,12 +82,12 @@ class Common { return new ServerDslProperty(serverValue) } - void assertThatSidesMatch(Pattern firstSide, String secondSide) { - assert secondSide ==~ firstSide + void assertThatSidesMatch(Pattern pattern, String value) { + assert value ==~ pattern } - void assertThatSidesMatch(String firstSide, Pattern secondSide) { - assert firstSide ==~ secondSide + void assertThatSidesMatch(String value, Pattern pattern) { + assert value ==~ pattern } void assertThatSidesMatch(MatchingStrategy firstSide, MatchingStrategy secondSide) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy new file mode 100644 index 0000000000..210668a2a9 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy @@ -0,0 +1,30 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic + +import java.util.regex.Pattern + +@CompileStatic +class RegexPatterns { + + private static final Pattern IP_ADDRESS = Pattern.compile('([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])'); + private static final Pattern HOSTNAME_PATTERN = Pattern.compile('((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?'); + private static final Pattern EMAIL = Pattern.compile('[_]*([a-z0-9]+(\\.|_*)?)+@([a-z][a-z0-9-]+(\\.|-*\\.))+[a-z]{2,6}'); + private static final Pattern URL = Pattern.compile('((www\\.|(http|https|ftp|news|file)+\\:\\/\\/)[_.a-z0-9-]+\\.[a-z0-9\\/_:@=.+?,##%&~-]*[^.|\\\'|\\# |!|\\(|?|,| |>|<|;|\\)])'); + + String ipAddress() { + return IP_ADDRESS.pattern() + } + + String hostname() { + return HOSTNAME_PATTERN.pattern() + } + + String email() { + return EMAIL.pattern() + } + + String url() { + return URL.pattern() + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index d29c1f87b5..6d2ed106d1 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -361,4 +361,37 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''') } + + @Issue('115') + def "should generate regex with helper method"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'POST' + url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) + headers { header 'Content-Type': 'application/json' } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex("^${hostname()}/partners/[0-9]+/users/[0-9]+"))) + } + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''') + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy new file mode 100644 index 0000000000..38430aa42f --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy @@ -0,0 +1,53 @@ +package io.codearte.accurest.dsl.internal + +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.regex.Pattern + +class RegexPatternsSpec extends Specification { + + RegexPatterns regexPatterns = new RegexPatterns() + + @Unroll + def "should generate a regex for ip address [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.ipAddress()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + '123.123.123.123' || true + 'a.b.' || false + } + + @Unroll + def "should generate a regex for hostname [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.hostname()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + 'https://asd.com' || true + 'https://asd.com:8080' || true + 'https://asd.com/asd' || false + 'asd.com' || false + } + + @Unroll + def "should generate a regex for email [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.email()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + 'asd@asd.com' || true + 'a.b.' || false + } + + @Unroll + def "should generate a regex for url [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.url()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + 'ftp://asd.com:9090/asd/a?a=b' || true + 'a.b.' || false + } +} From f3efc6b9dd3deb72071146643bd6bd7017304fbe Mon Sep 17 00:00:00 2001 From: Adam Wojszczyk Date: Mon, 10 Aug 2015 11:49:35 +0200 Subject: [PATCH 192/719] Add localhost assertions to regexPatternsSpec --- .../accurest/dsl/internal/RegexPatternsSpec.groovy | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy index 38430aa42f..848ed8511d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy @@ -24,11 +24,13 @@ class RegexPatternsSpec extends Specification { expect: shouldMatch == Pattern.compile(regexPatterns.hostname()).matcher(textToMatch).matches() where: - textToMatch || shouldMatch - 'https://asd.com' || true - 'https://asd.com:8080' || true - 'https://asd.com/asd' || false - 'asd.com' || false + textToMatch || shouldMatch + 'https://asd.com' || true + 'https://asd.com:8080' || true + 'https://localhost' || true + 'https://localhost:8080' || true + 'https://asd.com/asd' || false + 'asd.com' || false } @Unroll From 5bc9fe938704f5b22cbdc8b0a01819b09a225223 Mon Sep 17 00:00:00 2001 From: Spencer Gibb Date: Mon, 10 Aug 2015 10:37:44 -0600 Subject: [PATCH 193/719] Some grammar and formatting changes --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6bf509470d..b079b674a9 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,10 @@ Accurate REST Consumer Driven Contracts verifier for Java -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: +To make a long story short - AccuREST is a tool for Consumer Driven Contract (CDC) development. AccuREST ships an easy DSL for describing REST contracts for JVM-based applications. The contract DSL is used by AccuREST for two things: -generating WireMock's JSON stub definitions, allowing rapid development of the consumer side, +1. 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. +2. moving TDD to an architecture level. -For more information please follow to the [Wiki](https://github.com/Codearte/accurest/wiki/1.-Introduction) +For more information please go to the [Wiki](https://github.com/Codearte/accurest/wiki/1.-Introduction) From 7d39ef49b46eac2878c14a416d38b10b292905ef Mon Sep 17 00:00:00 2001 From: Adam Wojszczyk Date: Mon, 17 Aug 2015 15:48:06 +0200 Subject: [PATCH 194/719] Allow fields' values to be empty lists during searching for patterns --- .../dsl/WireMockRequestStubStrategy.groovy | 2 +- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 35 +++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index d0bb325bb1..d540069484 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -139,7 +139,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { } private boolean containsPattern(Collection collection) { - return collection.collect(this.&containsPattern).inject { a, b -> a || b } + return collection.collect(this.&containsPattern).inject('') { a, b -> a || b } } private boolean containsPattern(Object[] objects) { 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 ced69beeb1..23d8f65f35 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 @@ -1192,4 +1192,39 @@ class WireMockGroovyDslSpec extends WireMockSpec { String toWireMockClientJsonStub(groovyDsl) { new WireMockStubStrategy(groovyDsl).toWireMockClientStub() } + + def 'should generate stub with empty list as a value of a field'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('POST') + body( + values: [] + ) + } + response { + status 200 + } + } + when: + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + then: + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + { + "request": { + "method": "POST", + "bodyPatterns": [ + { + "equalToJson": "{\\"values\\":[]}" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWireMockStub(wireMockStub) + } } From b3b9dced26c7de1ee228a0613256164a46a7c611 Mon Sep 17 00:00:00 2001 From: Adam Wojszczyk Date: Mon, 17 Aug 2015 16:03:33 +0200 Subject: [PATCH 195/719] [#121] Allow fields' values to be empty lists during searching for patterns --- .../groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy | 1 + 1 file changed, 1 insertion(+) 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 23d8f65f35..d38124d532 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 @@ -1193,6 +1193,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { new WireMockStubStrategy(groovyDsl).toWireMockClientStub() } + @Issue("#121") def 'should generate stub with empty list as a value of a field'() { given: GroovyDsl groovyDsl = GroovyDsl.make { From ee87decf82a43adba091149a9ea6ace0df5a3eef Mon Sep 17 00:00:00 2001 From: Adam Wojszczyk Date: Mon, 17 Aug 2015 16:05:32 +0200 Subject: [PATCH 196/719] [#121] Allow fields' values to be empty lists during searching for patterns - reformat --- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) 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 d38124d532..1867c49eda 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 @@ -1181,18 +1181,6 @@ class WireMockGroovyDslSpec extends WireMockSpec { ''') } - String toJsonString(value) { - new JsonBuilder(value).toPrettyString() - } - - Object parseJson(json) { - new JsonSlurper().parseText(json) - } - - String toWireMockClientJsonStub(groovyDsl) { - new WireMockStubStrategy(groovyDsl).toWireMockClientStub() - } - @Issue("#121") def 'should generate stub with empty list as a value of a field'() { given: @@ -1200,7 +1188,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { request { method('POST') body( - values: [] + values: [] ) } response { @@ -1228,4 +1216,16 @@ class WireMockGroovyDslSpec extends WireMockSpec { and: stubMappingIsValidWireMockStub(wireMockStub) } + + String toJsonString(value) { + new JsonBuilder(value).toPrettyString() + } + + Object parseJson(json) { + new JsonSlurper().parseText(json) + } + + String toWireMockClientJsonStub(groovyDsl) { + new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + } } From 7879779e48ca8651f40abd635825c779eeec40e9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 22 Aug 2015 09:37:35 +0200 Subject: [PATCH 197/719] [#124] Multiline strings support. Fixes #124 --- .../builder/SpockMethodBodyBuilder.groovy | 2 +- .../JaxRsClientSpockMethodBuilderSpec.groovy | 35 ++++--- .../MockMvcSpockMethodBuilderSpec.groovy | 93 ++++++++++++------- 3 files changed, 80 insertions(+), 50 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index f0d29ebefe..af8993e140 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -155,7 +155,7 @@ abstract class SpockMethodBodyBuilder { value = value.substring(1).replaceAll('\\$value', "responseBody$property") blockBuilder.addLine(value) } else { - blockBuilder.addLine("responseBody$property == \"${value}\"") + blockBuilder.addLine("responseBody$property == '''${value}'''") } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index f7e0b7d777..07123d6265 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -26,8 +26,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") - blockBuilder.toString().contains("responseBody.property2 == \"b\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") + blockBuilder.toString().contains("responseBody.property2 == '''b'''") } @Issue("#79") @@ -54,9 +54,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") - blockBuilder.toString().contains("responseBody.property2[0].a == \"sth\"") - blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") + blockBuilder.toString().contains("responseBody.property2[0].a == '''sth'''") + blockBuilder.toString().contains("responseBody.property2[1].b == '''sthElse'''") } @Issue("#82") @@ -128,8 +128,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody[0].property1 == \"a\"") - blockBuilder.toString().contains("responseBody[1].property2 == \"b\"") + blockBuilder.toString().contains("responseBody[0].property1 == '''a'''") + blockBuilder.toString().contains("responseBody[1].property2 == '''b'''") } def "should generate assertions for array inside response body element"() { @@ -154,8 +154,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1[0].property2 == \"test1\"") - blockBuilder.toString().contains("responseBody.property1[1].property3 == \"test2\"") + 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"() { @@ -180,8 +180,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") - blockBuilder.toString().contains("responseBody.property2.property3 == \"b\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") + blockBuilder.toString().contains("responseBody.property2.property3 == '''b'''") } def "should generate regex assertions for map objects in response body"() { @@ -212,7 +212,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") } @@ -238,7 +238,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") } @@ -335,8 +335,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { spockTest.contains("queryParam('age', '99'") spockTest.contains("queryParam('name', 'Denis.Stepanov'") spockTest.contains("queryParam('email', 'bob@email.com'") - spockTest.contains('responseBody.property1 == "a"') - spockTest.contains('responseBody.property2 == "b"') + spockTest.contains("responseBody.property1 == '''a'''") + spockTest.contains("responseBody.property2 == '''b'''") } def "should generate test for empty body"() { @@ -372,13 +372,12 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { body "test" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains('def responseBody = (response.body.asString())') - spockTest.contains('responseBody == "test"') + spockTest.contains("responseBody == '''test'''") } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 6d2ed106d1..c314de48ca 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -3,13 +3,15 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Issue import spock.lang.Specification +import spock.lang.Unroll /** * @author Jakub Kubrynski */ class MockMvcSpockMethodBuilderSpec extends Specification { - def "should generate assertions for simple response body"() { + @Unroll + def "should generate assertions for simple response body for [#spockMethodBuilder]"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -24,13 +26,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { }""" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") - blockBuilder.toString().contains("responseBody.property2 == \"b\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") + blockBuilder.toString().contains("responseBody.property2 == '''b'''") } @Issue("#79") @@ -52,14 +54,14 @@ class MockMvcSpockMethodBuilderSpec extends Specification { ) } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") - blockBuilder.toString().contains("responseBody.property2[0].a == \"sth\"") - blockBuilder.toString().contains("responseBody.property2[1].b == \"sthElse\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") + blockBuilder.toString().contains("responseBody.property2[0].a == '''sth'''") + blockBuilder.toString().contains("responseBody.property2[1].b == '''sthElse'''") } @Issue("#82") @@ -77,7 +79,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { status 200 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -100,7 +102,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { status 200 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -126,13 +128,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { }]""" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody[0].property1 == \"a\"") - blockBuilder.toString().contains("responseBody[1].property2 == \"b\"") + blockBuilder.toString().contains("responseBody[0].property1 == '''a'''") + blockBuilder.toString().contains("responseBody[1].property2 == '''b'''") } def "should generate assertions for array inside response body element"() { @@ -152,13 +154,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { }""" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(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\"") + 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"() { @@ -178,13 +180,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { ''' } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") - blockBuilder.toString().contains("responseBody.property2.property3 == \"b\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") + blockBuilder.toString().contains("responseBody.property2.property3 == '''b'''") } def "should generate regex assertions for map objects in response body"() { @@ -210,12 +212,12 @@ class MockMvcSpockMethodBuilderSpec extends Specification { } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") } @@ -236,13 +238,14 @@ class MockMvcSpockMethodBuilderSpec extends Specification { } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == \"a\"") + blockBuilder.toString().contains("responseBody.property1 == '''a'''") blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + } def "should generate a call with an url path and query parameters"() { @@ -275,15 +278,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification { """ } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - spockTest.contains('responseBody.property1 == "a"') - spockTest.contains('responseBody.property2 == "b"') + spockTest.contains("responseBody.property1 == '''a'''") + spockTest.contains("responseBody.property2 == '''b'''") } def "should generate test for empty body"() { @@ -298,7 +301,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { status 406 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -319,14 +322,14 @@ class MockMvcSpockMethodBuilderSpec extends Specification { body "test" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: spockTest.contains('def responseBody = (response.body.asString())') - spockTest.contains('responseBody == "test"') + spockTest.contains("responseBody == '''test'''") } @Issue('113') @@ -353,7 +356,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { } } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -386,7 +389,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { } } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -394,4 +397,32 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''') } + + @Issue('124') + def "should create proper response body matching for multiline strings"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + + request { + method 'POST' + url '/invitations' + } + + response { + status 422 + body( + message: "First line\n" + + " Second line" + ) + } + } + SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains("""responseBody.message == '''First line + Second line'''""") + } } From 23446397ba8e2e292a6b24500141e5310b1ac899 Mon Sep 17 00:00:00 2001 From: Adam Wojszczyk Date: Mon, 24 Aug 2015 16:13:04 +0200 Subject: [PATCH 198/719] [#127] Add stub as an alias for client and test as an alias for server --- .../accurest/dsl/internal/Common.groovy | 8 +++++ .../MockMvcSpockMethodBuilderSpec.groovy | 31 ++++++++++++++++ .../accurest/dsl/WireMockGroovyDslSpec.groovy | 36 +++++++++++++++++++ 3 files changed, 75 insertions(+) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 9030d9b9f3..6cb78b67ba 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -78,10 +78,18 @@ class Common { return new ClientDslProperty(clientValue) } + ClientDslProperty stub(Object clientValue) { + return new ClientDslProperty(clientValue) + } + ServerDslProperty server(Object serverValue) { return new ServerDslProperty(serverValue) } + ServerDslProperty test(Object serverValue) { + return new ServerDslProperty(serverValue) + } + void assertThatSidesMatch(Pattern pattern, String value) { assert value ==~ pattern } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 6d2ed106d1..4875a1f744 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -329,6 +329,37 @@ class MockMvcSpockMethodBuilderSpec extends Specification { spockTest.contains('responseBody == "test"') } + @Issue("#127") + def 'should use "stub" as an alias for "client"'() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property: value( + stub(123), + test(123) + ) + ) + headers { + header('Content-Type': 'application/json') + + } + + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("responseBody.property == 123") + } + @Issue('113') def "should generate regex test for String in response header"() { given: 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 1867c49eda..cb0a75255a 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 @@ -1181,6 +1181,42 @@ class WireMockGroovyDslSpec extends WireMockSpec { ''') } + @Issue("#127") + def 'should use "test" as an alias for "server"'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method('POST') + body( + property: value(stub("value"), test("value")) + ) + } + response { + status 200 + } + } + when: + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + then: + new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + { + "request": { + "method": "POST", + "bodyPatterns": [ + { + "equalToJson": "{\\"property\\":\\"value\\"}" + } + ] + }, + "response": { + "status": 200 + } + } + ''') + and: + stubMappingIsValidWireMockStub(wireMockStub) + } + @Issue("#121") def 'should generate stub with empty list as a value of a field'() { given: From 154818c7974ff04a5387072b4424f2e3c71f6f85 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 22 Aug 2015 10:38:41 +0200 Subject: [PATCH 199/719] [#121] Introduced full JSONPath support - converted all json comparison to JSON Paths - started to use forked Wiremock with support for jsonpath 2.0.0 - changed automatic resolution of Wiremock to support the forked version until WIremock is officially fixed --- .travis.yml | 6 + .../DslToWireMockClientConverterSpec.groovy | 81 ++- .../accurest/SingleTestGenerator.groovy | 11 +- .../accurest/builder/ClassBuilder.groovy | 5 + .../builder/SpockMethodBodyBuilder.groovy | 62 +- .../dsl/BaseWireMockStubStrategy.groovy | 2 +- .../dsl/WireMockRequestStubStrategy.groovy | 201 ++++--- .../dsl/WireMockResponseStubStrategy.groovy | 30 +- .../accurest/dsl/WireMockStubStrategy.groovy | 15 +- .../internal/JsonStructureConverter.groovy | 4 +- .../dsl/internal/MatchingStrategy.groovy | 2 +- .../accurest/util/ContentUtils.groovy | 57 +- .../accurest/util/JsonPathEntry.groovy | 41 ++ .../util/JsonPathJsonConverter.groovy | 153 +++++ .../codearte/accurest/util/JsonPaths.groovy | 23 + ...onConverter.groovy => MapConverter.groovy} | 18 +- .../JaxRsClientSpockMethodBuilderSpec.groovy | 40 +- .../MockMvcSpockMethodBuilderSpec.groovy | 131 ++--- .../dsl/WireMockGroovyDslResponseSpec.groovy | 52 -- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 529 ++++++++---------- .../util/JsonPathJsonConverterSpec.groovy | 199 +++++++ .../plugin/AccurestGradlePlugin.groovy | 16 + .../functionalTest/sampleProject/build.gradle | 1 - build.gradle | 11 +- gradle/release.gradle | 2 +- 25 files changed, 1093 insertions(+), 599 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathJsonConverter.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy rename accurest-core/src/main/groovy/io/codearte/accurest/util/{JsonConverter.groovy => MapConverter.groovy} (79%) delete mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslResponseSpec.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/util/JsonPathJsonConverterSpec.groovy diff --git a/.travis.yml b/.travis.yml index 7a0dff7140..074a9aabda 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,15 @@ language: java +sudo: false jdk: - oraclejdk7 - openjdk7 - oraclejdk8 +cache: + directories: + - $HOME/.gradle + - $HOME/.m2 + install: ./gradlew assemble script: ./gradlew check --stacktrace --info --continue \ No newline at end of file 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 0831dde57b..22fc850efe 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 @@ -1,6 +1,6 @@ package io.codearte.accurest.wiremock -import groovy.json.JsonSlurper +import org.skyscreamer.jsonassert.JSONAssert import spock.lang.Specification class DslToWireMockClientConverterSpec extends Specification { @@ -23,8 +23,9 @@ class DslToWireMockClientConverterSpec extends Specification { when: String json = converter.convertContent(dslBody) then: - new JsonSlurper().parseText(json) == new JsonSlurper().parseText(""" -{"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}}""") + JSONAssert.assertEquals(''' +{"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}} +''', json, false) } @@ -80,22 +81,62 @@ class DslToWireMockClientConverterSpec extends Specification { when: String json = converter.convertContent(dslBody) then: - new JsonSlurper().parseText(json) == new JsonSlurper().parseText("""{ - "request":{ - "method":"PUT", - "url":"/api/12", - "bodyPatterns": [ - { "equalToJson": "[{\\"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" - } - } - }, - "response":{ - "status":200} - } -""") + JSONAssert.assertEquals(''' +{ + "request" : { + "url" : "/api/12", + "method" : "PUT", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.country == 'United States')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.name == 'Washington')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box[?(@.type == 'Polygon')]" + }, { + "matchesJsonPath" : "$[*][?(@.id_str == '492967299297845248')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.country_code == 'US')]" + }, { + "matchesJsonPath" : "$[*][?(@.id == 492967299297845248)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.id == '01fbe706f872cb32')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.url == 'http://api.twitter.com/1/geo/id/01fbe706f872cb32.json')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" + }, { + "matchesJsonPath" : "$[*][?(@.text == 'Gonna see you at Warsaw')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.place_type == 'city')]" + }, { + "matchesJsonPath" : "$[*][?(@.created_at == 'Sat Jul 26 09:38:57 +0000 2014')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.full_name == 'Washington, DC')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/vnd.com.ofg.twitter-places-analyzer.v1+json" + } + } + }, + "response" : { + "status" : 200 + } +} +''', json, false) } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 2765d7114b..fb2d135419 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -50,14 +50,23 @@ class SingleTestGenerator { } if (configProperties.ruleClassForTests) { + clazz.addImport('org.junit.Rule') - .addRule(configProperties.ruleClassForTests) + .addRule(configProperties.ruleClassForTests) } + addJsonPathRelatedImports(clazz) + listOfFiles.each { clazz.addMethod(createTestMethod(it, configProperties)) } return clazz.build() } + private ClassBuilder addJsonPathRelatedImports(ClassBuilder clazz) { + clazz.addImport(['com.jayway.jsonpath.DocumentContext', + 'com.jayway.jsonpath.JsonPath', + 'net.minidev.json.JSONArray']) + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy index 29f4fc2c14..3e3a8ce1c0 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy @@ -43,6 +43,11 @@ class ClassBuilder { return this } + ClassBuilder addImport(List importsToAdd) { + imports.addAll(importsToAdd) + return this + } + ClassBuilder addStaticImport(String importToAdd) { staticImports << importToAdd return this diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index af8993e140..49df619015 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -3,21 +3,13 @@ import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked 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.MatchingStrategy -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.* import io.codearte.accurest.util.ContentType -import io.codearte.accurest.util.JsonConverter - -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 +import io.codearte.accurest.util.MapConverter +import io.codearte.accurest.util.JsonPathJsonConverter +import io.codearte.accurest.util.JsonPaths +import static io.codearte.accurest.util.ContentUtils.* /** * @author Jakub Kubrynski */ @@ -93,17 +85,34 @@ abstract class SpockMethodBodyBuilder { responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) } if (contentType == ContentType.JSON) { - bb.addLine("def responseBody = new JsonSlurper().parseText($responseAsString)") + appendJsonPath(bb, responseAsString) + JsonPaths jsonPaths = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(responseBody) + jsonPaths.each { + it.buildJsonPathComparison('parsedJson').each { + bb.addLine(it) + } + } processBodyElement(bb, "", responseBody) } else if (contentType == ContentType.XML) { bb.addLine("def responseBody = new XmlSlurper().parseText($responseAsString)") // TODO xml validation } else { bb.addLine("def responseBody = ($responseAsString)") - processBodyElement(bb, "", responseBody) + processText(bb, "", responseBody as String) } } + protected void processText(BlockBuilder blockBuilder, String property, String value) { + if (value.startsWith('$')) { + value = value.substring(1).replaceAll('\\$value', "responseBody$property") + blockBuilder.addLine(value) + } else { + blockBuilder.addLine("responseBody$property == \"${value}\"") + } + } + + protected String + protected String getBodyAsString() { Object bodyValue = extractServerValueFromBody(request.body.serverValue) return trimRepeatedQuotes(new JsonOutput().toJson(bodyValue)) @@ -117,7 +126,7 @@ abstract class SpockMethodBodyBuilder { if (bodyValue instanceof GString) { bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) } else { - bodyValue = JsonConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) + bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) } return bodyValue } @@ -147,28 +156,15 @@ abstract class SpockMethodBodyBuilder { } protected void processBodyElement(BlockBuilder blockBuilder, String property, Object value) { - blockBuilder.addLine("responseBody$property == ${value}") + } - protected void processBodyElement(BlockBuilder blockBuilder, String property, String value) { - if (value.startsWith('$')) { - value = value.substring(1).replaceAll('\\$value', "responseBody$property") - blockBuilder.addLine(value) - } else { - blockBuilder.addLine("responseBody$property == '''${value}'''") - } - } - - protected void processBodyElement(BlockBuilder blockBuilder, String property, Pattern pattern) { - blockBuilder.addLine("responseBody$property ==~ java.util.regex.Pattern.compile('${pattern.pattern()}')") - } - - protected void processBodyElement(BlockBuilder blockBuilder, String property, DslProperty dslProperty) { - processBodyElement(blockBuilder, property, dslProperty.serverValue) + protected void appendJsonPath(BlockBuilder blockBuilder, String json) { + blockBuilder.addLine("DocumentContext parsedJson = JsonPath.parse($json)") } protected void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { - blockBuilder.addLine("${exec.insertValue("responseBody$property")}") + blockBuilder.addLine("${exec.insertValue("parsedJson.read('\\\$$property')")}") } protected void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) { 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 index 0afb66273b..c69e5539fa 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy @@ -10,7 +10,7 @@ import io.codearte.accurest.util.ContentType import java.util.regex.Pattern import static io.codearte.accurest.util.ContentUtils.extractValue -import static io.codearte.accurest.util.JsonConverter.transformValues +import static io.codearte.accurest.util.MapConverter.transformValues @TypeChecked abstract class BaseWireMockStubStrategy { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index d540069484..923b614f7a 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -1,21 +1,21 @@ package io.codearte.accurest.dsl +import com.github.tomakehurst.wiremock.http.RequestMethod +import com.github.tomakehurst.wiremock.matching.RequestPattern +import com.github.tomakehurst.wiremock.matching.ValuePattern +import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked -import io.codearte.accurest.dsl.internal.Body -import io.codearte.accurest.dsl.internal.ClientRequest -import io.codearte.accurest.dsl.internal.DslProperty -import io.codearte.accurest.dsl.internal.MatchingStrategy -import io.codearte.accurest.dsl.internal.QueryParameter -import io.codearte.accurest.dsl.internal.QueryParameters -import io.codearte.accurest.dsl.internal.Request +import groovy.transform.TypeCheckingMode +import io.codearte.accurest.dsl.internal.* import io.codearte.accurest.util.ContentType +import io.codearte.accurest.util.ContentUtils +import io.codearte.accurest.util.JsonPathJsonConverter +import io.codearte.accurest.util.JsonPaths +import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.getEqualsTypeFromContentType -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromMatchingStrategy +import static io.codearte.accurest.util.ContentUtils.* import static io.codearte.accurest.util.RegexpBuilders.buildGStringRegexpMatch import static io.codearte.accurest.util.RegexpBuilders.buildJSONRegexpMatch @@ -30,74 +30,144 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { } @PackageScope - Map buildClientRequestContent() { - return buildRequestContent(new ClientRequest(request)) + RequestPattern buildClientRequestContent() { + RequestPattern requestPattern = new RequestPattern() + appendMethod(requestPattern) + appendHeaders(requestPattern) + appendUrl(requestPattern) + appendQueryParameters(requestPattern) + appendBody(requestPattern) + return requestPattern } - private Map buildRequestContent(ClientRequest request) { - return ([method : request?.method?.clientValue, - headers : buildClientRequestHeadersSection(request.headers) - ] << appendUrl(request) << appendQueryParameters(request) << appendBody(request)).findAll { it.value } + private void appendMethod(RequestPattern requestPattern) { + if(!request.method) { + return + } + requestPattern.setMethod(RequestMethod.fromString(request.method.clientValue?.toString())) } - private Map appendUrl(ClientRequest clientRequest) { - Object urlPath = clientRequest?.urlPath?.clientValue + private void appendBody(RequestPattern requestPattern) { + if (!request.body) { + return + } + ContentType contentType = tryToGetContentType() + if (contentType == ContentType.JSON) { + JsonPaths values = JsonPathJsonConverter.transformToJsonPathWithStubsSideValues(getMatchingStrategyFromBody(request.body)?.clientValue) + if (values.empty) { + requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT, + equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ] + } else { + requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath) } ?: null + } + } else if (contentType == ContentType.XML) { + requestPattern.bodyPatterns = [new ValuePattern(equalToXml: getMatchingStrategy(request.body.clientValue).clientValue.toString())] + } else if (containsPattern(request?.body)) { + MatchingStrategy matchingStrategy = appendBodyRegexpMatchPattern(request.body) + requestPattern.bodyPatterns = [convertToValuePattern(matchingStrategy)] + } else { + requestPattern.bodyPatterns = [convertToValuePattern(getMatchingStrategy(request.body.clientValue))] + } + } + + private ContentType tryToGetContentType() { + ContentType contentType = recognizeContentTypeFromHeader(request.headers) + if (contentType == ContentType.UNKNOWN) { + if (!request.body.clientValue) { + return ContentType.UNKNOWN + } + return ContentUtils.getClientContentType(request.body.clientValue) + } + return contentType + } + + private void appendHeaders(RequestPattern requestPattern) { + if(!request.headers) { + return + } + request.headers.entries.each { + requestPattern.addHeader(it.name, convertToValuePattern(it.clientValue)) + } + } + + private void appendUrl(RequestPattern requestPattern) { + Object urlPath = request?.urlPath?.clientValue if (urlPath) { - return [urlPath: urlPath] + requestPattern.setUrlPath(urlPath.toString()) } - Object url = clientRequest?.url?.clientValue - return url instanceof Pattern ? [urlPattern: url.pattern()] : [url: url] - } - - private Map appendQueryParameters(ClientRequest clientRequest) { - QueryParameters queryParameters = clientRequest?.urlPath?.queryParameters ?: clientRequest?.url?.queryParameters - return queryParameters && !queryParameters.parameters.isEmpty() ? - [queryParameters: buildUrlPathQueryParameters(queryParameters)] : [:] - } - - private Map buildUrlPathQueryParameters(QueryParameters queryParameters) { - return queryParameters.parameters.collectEntries { QueryParameter param -> - parseQueryParameter(param.name, param.clientValue) + if(!request.url) { + return + } + Object url = request?.url?.clientValue + if(url instanceof Pattern) { + requestPattern.setUrlPattern(url.pattern()) + } else { + requestPattern.setUrl(url.toString()) } } - protected Map parseQueryParameter(String name, MatchingStrategy matchingStrategy) { - return buildQueryParameter(name, matchingStrategy.clientValue, matchingStrategy.type) + private void appendQueryParameters(RequestPattern requestPattern) { + QueryParameters queryParameters = request?.urlPath?.queryParameters ?: request?.url?.queryParameters + queryParameters?.parameters?.each { + requestPattern.addQueryParam(it.name, convertToValuePattern(it.clientValue)) + } } - protected Map parseQueryParameter(String name, Object value) { - return buildQueryParameter(name, value, MatchingStrategy.Type.EQUAL_TO) + @TypeChecked(TypeCheckingMode.SKIP) + private static ValuePattern convertToValuePattern(Object object) { + switch (object) { + case Pattern: + Pattern value = object as Pattern + return ValuePattern.matches(value.pattern()) + case MatchingStrategy: + MatchingStrategy value = object as MatchingStrategy + switch (value.type) { + case MatchingStrategy.Type.NOT_MATCHING: + return new ValuePattern(doesNotMatch: value.clientValue) + case MatchingStrategy.Type.ABSENT: + return ValuePattern.absent() + default: + return ValuePattern."${value.type.name}"(value.clientValue) + } + default: + return ValuePattern.equalTo(object.toString()) + } } - protected Map parseQueryParameter(String name, Pattern pattern) { - return buildQueryParameter(name, pattern.pattern(), MatchingStrategy.Type.MATCHING) + private MatchingStrategy getMatchingStrategyFromBody(Body body) { + if(!body) { + return null + } + return getMatchingStrategy(body.clientValue) } - private Map buildQueryParameter(String name, Pattern pattern, MatchingStrategy.Type type) { - return buildQueryParameter(name, pattern.pattern(), type) + private MatchingStrategy getMatchingStrategy(MatchingStrategy matchingStrategy) { + return getMatchingStrategyIncludingContentType(matchingStrategy) + } + private MatchingStrategy getMatchingStrategy(GString gString) { + if (!gString) { + return new MatchingStrategy("", MatchingStrategy.Type.EQUAL_TO) + } + def extractedValue = ContentUtils.extractValue(gString) { + it instanceof DslProperty ? it.clientValue : getStringFromGString(it) + } + def value = getStringFromGString(extractedValue) + return getMatchingStrategy(value) } - private Map buildQueryParameter(String name, Object value, MatchingStrategy.Type type) { - return [(name): [(type.name) : value]] + private def getStringFromGString(Object object) { + return object instanceof GString ? object.toString() : object } - private Map appendBody(ClientRequest clientRequest) { - return clientRequest.body? appendBody(clientRequest.body) : [:] + private MatchingStrategy getMatchingStrategy(Object bodyValue) { + return tryToFindMachingStrategy(bodyValue) } - private Map appendBody(Body body) { - return [bodyPatterns: (appendBodyPatterns(body.clientValue))] + private MatchingStrategy tryToFindMachingStrategy(Object bodyValue) { + return new MatchingStrategy(MapConverter.transformToClientValues(bodyValue), getEqualsTypeFromContentTypeHeader()) } - private List> appendBodyPatterns(MatchingStrategy matchingStrategy) { - return [appendBodyPattern(matchingStrategy)] - } - - private List> appendBodyPatterns(Object bodyValue) { - return appendBodyPatterns(new MatchingStrategy(bodyValue, getEqualsTypeFromContentTypeHeader())) - } - - private Map appendBodyPattern(MatchingStrategy matchingStrategy) { + private MatchingStrategy getMatchingStrategyIncludingContentType(MatchingStrategy matchingStrategy) { MatchingStrategy.Type type = matchingStrategy.type Object value = matchingStrategy.clientValue ContentType contentType = recognizeContentTypeFromMatchingStrategy(type) @@ -105,29 +175,22 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { contentType = recognizeContentTypeFromContent(value) type = getEqualsTypeFromContentType(contentType) } - if (containsPattern(value)) { - return appendBodyRegexpMatchPattern(value, contentType) - } - return buildMatchPattern(new MatchingStrategy(parseBody(value, contentType), type)) + return new MatchingStrategy(parseBody(value, contentType), type) } - private Map appendBodyRegexpMatchPattern(Object value, ContentType contentType) { + private MatchingStrategy appendBodyRegexpMatchPattern(Object value, ContentType contentType) { switch (contentType) { case ContentType.JSON: - return buildMatchPattern(new MatchingStrategy(buildJSONRegexpMatch(value), MatchingStrategy.Type.MATCHING)) + return new MatchingStrategy(buildJSONRegexpMatch(value), MatchingStrategy.Type.MATCHING) case ContentType.UNKNOWN: - return buildMatchPattern(new MatchingStrategy(buildGStringRegexpMatch(value), MatchingStrategy.Type.MATCHING)) + return new MatchingStrategy(buildGStringRegexpMatch(value), MatchingStrategy.Type.MATCHING) case ContentType.XML: throw new IllegalStateException("XML pattern matching is not implemented yet") } } - private Map buildMatchPattern(MatchingStrategy matchingStrategy) { - Map result = [(matchingStrategy.type.name): matchingStrategy.clientValue.toString()] - if (matchingStrategy.type == MatchingStrategy.Type.EQUAL_TO_JSON && matchingStrategy.jsonCompareMode) { - return result << [jsonCompareMode : (matchingStrategy.jsonCompareMode.toString())] - } - return result + private MatchingStrategy appendBodyRegexpMatchPattern(Object value) { + return appendBodyRegexpMatchPattern(value, ContentType.UNKNOWN) } private boolean containsPattern(GString bodyAsValue) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy index 3cb9a58155..5af5898257 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy @@ -1,7 +1,9 @@ package io.codearte.accurest.dsl +import com.github.tomakehurst.wiremock.http.HttpHeader +import com.github.tomakehurst.wiremock.http.HttpHeaders +import com.github.tomakehurst.wiremock.http.ResponseDefinition import groovy.transform.PackageScope import groovy.transform.TypeChecked -import io.codearte.accurest.dsl.internal.ClientResponse import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.dsl.internal.Response import io.codearte.accurest.util.ContentType @@ -22,23 +24,31 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { } @PackageScope - Map buildClientResponseContent() { - return buildResponseContent(new ClientResponse(response)) + ResponseDefinition buildClientResponseContent() { + ResponseDefinition responseDefinition = new ResponseDefinition() + responseDefinition.setStatus(response.status.clientValue as Integer) + appendHeaders(responseDefinition) + appendBody(responseDefinition) + return responseDefinition } - private Map buildResponseContent(ClientResponse response) { - return ([status : response?.status?.clientValue, - headers: buildClientResponseHeadersSection(response.headers) - ] << appendBody(response)).findAll { it.value } + private void appendHeaders(ResponseDefinition responseDefinition) { + if(!(response.headers)) { + return + } + responseDefinition.setHeaders(new HttpHeaders(response.headers.entries?.collect { new HttpHeader(it.name, it.clientValue.toString()) })) } - private Map appendBody(ClientResponse response) { - Object body = response?.body?.clientValue + private void appendBody(ResponseDefinition responseDefinition) { + if (!response.body) { + return + } + Object body = response.body.clientValue ContentType contentType = recognizeContentTypeFromHeader(response.headers) if (contentType == ContentType.UNKNOWN) { contentType = recognizeContentTypeFromContent(body) } - return body != null ? [body: parseBody(body, contentType)] : [:] + responseDefinition.setBody(parseBody(body, contentType)) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy index acff79a11a..337f7b8557 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy @@ -1,6 +1,8 @@ package io.codearte.accurest.dsl -import groovy.json.JsonOutput +import com.github.tomakehurst.wiremock.http.ResponseDefinition +import com.github.tomakehurst.wiremock.matching.RequestPattern +import com.github.tomakehurst.wiremock.stubbing.StubMapping import groovy.transform.CompileDynamic import groovy.transform.CompileStatic @@ -19,11 +21,14 @@ class WireMockStubStrategy { @CompileDynamic String toWireMockClientStub() { - def wiremockStubDefinition = [request : wireMockRequestStubStrategy.buildClientRequestContent(), - response: wireMockResponseStubStrategy.buildClientResponseContent()] + StubMapping stubMapping = new StubMapping() + RequestPattern request = wireMockRequestStubStrategy.buildClientRequestContent() + ResponseDefinition response = wireMockResponseStubStrategy.buildClientResponseContent() if (priority) { - wiremockStubDefinition.priority = priority + stubMapping.priority = priority } - return JsonOutput.prettyPrint(JsonOutput.toJson(wiremockStubDefinition)) + stubMapping.request = request + stubMapping.response = response + return StubMapping.buildJsonStringFor(stubMapping) } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy index f5860bfaad..b6b6f79eee 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy @@ -2,7 +2,7 @@ package io.codearte.accurest.dsl.internal import groovy.json.JsonOutput import groovy.transform.CompileStatic -import io.codearte.accurest.util.JsonConverter +import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern @@ -17,7 +17,7 @@ class JsonStructureConverter { Closure performAdditionalLogicOnSerializedJson, Closure convertSerializedJsonToSth) { LinkedList queue = new LinkedList<>() - def transformedJson = JsonConverter.transformValues(parsedJson, { + def transformedJson = MapConverter.transformValues(parsedJson, { if(retrievePlaceholders(it)) { queue.push(it) return TEMPORARY_PLACEHOLDER diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy index c31c0b4bf6..191af8d7ee 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy @@ -34,7 +34,7 @@ class MatchingStrategy extends DslProperty { enum Type { - EQUAL_TO("equalTo"), CONTAINS("contains"), MATCHING("matches"), NOT_MATCHING("doesNotMatch"), + EQUAL_TO("equalTo"), CONTAINS("containing"), MATCHING("matches"), NOT_MATCHING("doesNotMatch"), EQUAL_TO_JSON("equalToJson"), EQUAL_TO_XML("equalToXml"), ABSENT("absent") final String name diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index b42cadcf5c..a7e66f9ec3 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.util import groovy.json.JsonException +import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.transform.TypeChecked import groovy.util.logging.Slf4j @@ -18,6 +19,10 @@ import static org.apache.commons.lang3.StringEscapeUtils.escapeXml11 @Slf4j class ContentUtils { + public static final Closure GET_STUB_SIDE = { + it instanceof DslProperty ? it.clientValue : it + } + private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' @@ -57,7 +62,57 @@ class ContentUtils { return extractValueForGString(bodyAsValue, valueProvider) } } + } + public static ContentType getClientContentType(GString bodyAsValue) { + try { + extractValueForJSON(bodyAsValue, GET_STUB_SIDE) + return ContentType.JSON + } catch(JsonException e) { + try { + new XmlSlurper().parseText(extractValueForXML(bodyAsValue, GET_STUB_SIDE).toString()) + return ContentType.XML + } catch (Exception exception) { + extractValueForGString(bodyAsValue, GET_STUB_SIDE) + return ContentType.UNKNOWN + } + } + } + + public static ContentType getClientContentType(String bodyAsValue) { + try { + new JsonSlurper().parseText(bodyAsValue) + return ContentType.JSON + } catch(JsonException e) { + try { + new XmlSlurper().parseText(bodyAsValue) + return ContentType.XML + } catch (Exception exception) { + return ContentType.UNKNOWN + } + } + } + + public static ContentType getClientContentType(Object bodyAsValue) { + return ContentType.UNKNOWN + } + + public static ContentType getClientContentType(Map bodyAsValue) { + try { + JsonOutput.toJson(bodyAsValue) + return ContentType.JSON + } catch (Exception ignore) { + return ContentType.UNKNOWN + } + } + + public static ContentType getClientContentType(List bodyAsValue) { + try { + JsonOutput.toJson(bodyAsValue) + return ContentType.JSON + } catch (Exception ignore) { + return ContentType.UNKNOWN + } } private static GStringImpl extractValueForGString(GString bodyAsValue, Closure valueProvider) { @@ -108,7 +163,7 @@ class ContentUtils { } private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) { - JsonConverter.transformValues(parsedJson, { Object value -> + MapConverter.transformValues(parsedJson, { Object value -> if (value instanceof String) { String string = (String) value Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy new file mode 100644 index 0000000000..0e0f928f22 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy @@ -0,0 +1,41 @@ +package io.codearte.accurest.util + +import java.util.regex.Pattern + +class JsonPathEntry { + final String jsonPath + final String optionalSuffix + final Object value + + JsonPathEntry(String jsonPath, String optionalSuffix, Object value) { + this.jsonPath = jsonPath + this.optionalSuffix = optionalSuffix + this.value = value + } + + List buildJsonPathComparison(String parsedJsonVariable) { + if (optionalSuffix) { + return ["!${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).empty"] + } else if (traversesOverCollections()) { + return ["${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).size() == 1", + "${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).get(0) ${operator()} ${potentiallyWrappedWithQuotesValue()}"] + } + return ["${parsedJsonVariable}.read('''${jsonPath}''') ${operator()} ${potentiallyWrappedWithQuotesValue()}"] + } + + private boolean traversesOverCollections() { + return jsonPath.contains('[*]') + } + + String operator() { + return value instanceof Pattern ? "==~" : "==" + } + + String potentiallyWrappedWithQuotesValue() { + return value instanceof Number ? value : "'''$value'''" + } + + static JsonPathEntry simple(String jsonPath, Object value) { + return new JsonPathEntry(jsonPath, "", value) + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathJsonConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathJsonConverter.groovy new file mode 100644 index 0000000000..28625a1cbf --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathJsonConverter.groovy @@ -0,0 +1,153 @@ +package io.codearte.accurest.util + +import groovy.json.JsonSlurper +import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.dsl.internal.ExecutionProperty + +import java.util.regex.Pattern +/** + * @author Marcin Grzejszczak + */ +class JsonPathJsonConverter { + + private static final Boolean SERVER_SIDE = false + private static final Boolean CLIENT_SIDE = true + + public static final String ROOT_JSON_PATH_ELEMENT = '$' + public static final String ALL_ELEMENTS = "[*]" + + public static JsonPaths transformToJsonPathWithTestsSideValues(def json) { + return transformToJsonPathWithValues(json, SERVER_SIDE) + } + + public static JsonPaths transformToJsonPathWithStubsSideValues(def json) { + return transformToJsonPathWithValues(json, CLIENT_SIDE) + } + + private static JsonPaths transformToJsonPathWithValues(def json, boolean clientSide) { + if(!json) { + return new JsonPaths() + } + JsonPaths pathsAndValues = [] as Set + Object convertedJson = getClientOrServerSideValues(json, clientSide) + traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value -> + if (value instanceof ExecutionProperty) { + return + } + JsonPathEntry entry = getValueToInsert(key, value) + pathsAndValues.add(entry) + } + return pathsAndValues + } + + private static Object getClientOrServerSideValues(json, boolean clientSide) { + return MapConverter.transformValues(json) { + boolean dslProp = it instanceof DslProperty + if (dslProp) { + DslProperty dslProperty = ((DslProperty) it) + return clientSide ? + getClientOrServerSideValues(dslProperty.clientValue, clientSide) : getClientOrServerSideValues(dslProperty.serverValue, clientSide) + } + return it + } + } + + protected static def traverseRecursively(Class parentType, String key, def value, Closure closure) { + if (value instanceof String && value) { + try { + def json = new JsonSlurper().parseText(value) + if (json instanceof Map) { + return convertWithKey(parentType, key, json, closure) + } + } catch (Exception ignore) { + return closure(key, value) + } + } else if (isAnEntryWithNonCollectionLikeValue(value)) { + return convertWithKey(List, key, value as Map, closure) + } else if (isAnEntryWithoutNestedStructures(value)) { + return convertWithKey(List, key, value as Map, closure) + } else if (value instanceof Map) { + return convertWithKey(Map, key, value as Map, closure) + } else if (value instanceof List) { + value.each { def element -> + traverseRecursively(List, "$key[*]", element, closure) + } + return value + } + try { + return closure(key, value) + } catch (Exception ignore) { + return value + } + } + + private static boolean isAnEntryWithNonCollectionLikeValue(def value) { + if (!(value instanceof Map)) { + return false + } + Map valueAsMap = ((Map) value) + boolean mapHasOneEntry = valueAsMap.size() == 1 + if (!mapHasOneEntry) { + return false + } + Object valueOfEntry = valueAsMap.entrySet().first().value + return !(valueOfEntry instanceof Map || valueOfEntry instanceof List) + } + + private static boolean isAnEntryWithoutNestedStructures(def value) { + if (!(value instanceof Map)) { + return false + } + Map valueAsMap = ((Map) value) + return valueAsMap.entrySet().every { Map.Entry entry -> + [String, Number].any { entry.value.getClass().isAssignableFrom(it) } + } + } + + private static Map convertWithKey(Class parentType, String parentKey, Map map, Closure closureToExecute) { + return map.collectEntries { + String entrykey, value -> + [entrykey, traverseRecursively(parentType, "${parentKey}.${entrykey}", value, closureToExecute)] + } + } + + private static void traverseRecursivelyForKey(def json, String rootKey, Closure closure) { + traverseRecursively(Map, rootKey, json, closure) + } + + private static JsonPathEntry getValueToInsert(String key, Object value) { + return convertToListElementFiltering(key, value) + } + + protected static JsonPathEntry convertToListElementFiltering(String key, Object value) { + if (key.endsWith(ALL_ELEMENTS)) { + int lastAllElements = key.lastIndexOf(ALL_ELEMENTS) + String keyWithoutAllElements = key.substring(0, lastAllElements) + return JsonPathEntry.simple("""$keyWithoutAllElements[?(@ ${compareWith(value)})]""".toString(), value) + } + return getKeyForTraversalOfListWithNonPrimitiveTypes(key, value) + } + + private static JsonPathEntry getKeyForTraversalOfListWithNonPrimitiveTypes(String key, Object value) { + int lastDot = key.lastIndexOf('.') + String keyWithoutLastElement = key.substring(0, lastDot) + String lastElement = key.substring(lastDot + 1).replaceAll(~/\[\*\]/, "") + return new JsonPathEntry( + """$keyWithoutLastElement[?(@.$lastElement ${compareWith(value)})]""".toString(), + lastElement, + value + ) + } + + protected static String compareWith(Object value) { + if (value instanceof Pattern) { + return """=~ /${(value as Pattern).pattern()}/""" + } + return """== ${potentiallyWrappedWithQuotesValue(value)}""" + } + + protected static String potentiallyWrappedWithQuotesValue(Object value) { + return value instanceof Number ? value : "'$value'" + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy new file mode 100644 index 0000000000..6c4aad1214 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy @@ -0,0 +1,23 @@ +package io.codearte.accurest.util + +class JsonPaths extends HashSet { + + Object getAt(String key) { + return find { + it.jsonPath == key + }?.value + } + + Object putAt(String key, Object value) { + JsonPathEntry entry = find { + it.jsonPath == key + } + if (!entry) { + return null + } + Object oldValue = entry.value + add(new JsonPathEntry(entry.jsonPath, entry.optionalSuffix, value)) + return oldValue + } +} + diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy similarity index 79% rename from accurest-core/src/main/groovy/io/codearte/accurest/util/JsonConverter.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy index 208a3aefa3..14568e7584 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy @@ -1,15 +1,16 @@ package io.codearte.accurest.util import groovy.json.JsonSlurper +import io.codearte.accurest.dsl.internal.DslProperty + /** * @author Marcin Grzejszczak */ -class JsonConverter { +class MapConverter { - private static Map convert(Map map, Closure closure) { - return map.collectEntries { - key, value -> - [key, transformValues(value, closure)] + static def transformToClientValues(def value) { + return transformValues(value) { + it instanceof DslProperty ? it.clientValue : it } } @@ -35,4 +36,11 @@ class JsonConverter { } } + private static Map convert(Map map, Closure closure) { + return map.collectEntries { + key, value -> + [key, transformValues(value, closure)] + } + } + } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index 07123d6265..8bd272b7ac 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -26,8 +26,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2 == '''b'''") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") } @Issue("#79") @@ -54,9 +54,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2[0].a == '''sth'''") - blockBuilder.toString().contains("responseBody.property2[1].b == '''sthElse'''") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") + blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") } @Issue("#82") @@ -128,8 +128,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody[0].property1 == '''a'''") - blockBuilder.toString().contains("responseBody[1].property2 == '''b'''") + blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") + blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") } def "should generate assertions for array inside response body element"() { @@ -154,8 +154,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1[0].property2 == '''test1'''") - blockBuilder.toString().contains("responseBody.property1[1].property3 == '''test2'''") + blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") + blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") } def "should generate assertions for nested objects in response body"() { @@ -180,8 +180,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2.property3 == '''b'''") + blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") } def "should generate regex assertions for map objects in response body"() { @@ -212,8 +212,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") } def "should generate regex assertions for string objects in response body"() { @@ -238,8 +238,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") } def "should ignore 'Accept' header and use 'request' method"() { @@ -335,8 +335,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { spockTest.contains("queryParam('age', '99'") spockTest.contains("queryParam('name', 'Denis.Stepanov'") spockTest.contains("queryParam('email', 'bob@email.com'") - spockTest.contains("responseBody.property1 == '''a'''") - spockTest.contains("responseBody.property2 == '''b'''") + spockTest.contains('$[?(@.property2 == \'b\')]') + spockTest.contains('$[?(@.property1 == \'a\')]') } def "should generate test for empty body"() { @@ -372,12 +372,14 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { body "test" } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains("responseBody == '''test'''") + spockTest.contains('def responseBody = (response.body.asString())') + spockTest.contains('responseBody == "test"') } + } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index df36f3058f..dcbf988168 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -3,15 +3,13 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Issue import spock.lang.Specification -import spock.lang.Unroll /** * @author Jakub Kubrynski */ class MockMvcSpockMethodBuilderSpec extends Specification { - @Unroll - def "should generate assertions for simple response body for [#spockMethodBuilder]"() { + def "should generate assertions for simple response body"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -26,13 +24,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { }""" } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2 == '''b'''") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") } @Issue("#79") @@ -54,14 +52,14 @@ class MockMvcSpockMethodBuilderSpec extends Specification { ) } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2[0].a == '''sth'''") - blockBuilder.toString().contains("responseBody.property2[1].b == '''sthElse'''") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") + blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") } @Issue("#82") @@ -79,7 +77,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { status 200 } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -102,7 +100,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { status 200 } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -128,13 +126,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { }]""" } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody[0].property1 == '''a'''") - blockBuilder.toString().contains("responseBody[1].property2 == '''b'''") + blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") + blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") } def "should generate assertions for array inside response body element"() { @@ -154,13 +152,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { }""" } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(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'''") + blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") + blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") } def "should generate assertions for nested objects in response body"() { @@ -180,13 +178,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { ''' } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2.property3 == '''b'''") + blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") } def "should generate regex assertions for map objects in response body"() { @@ -212,13 +210,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") + blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") } def "should generate regex assertions for string objects in response body"() { @@ -238,14 +236,13 @@ class MockMvcSpockMethodBuilderSpec extends Specification { } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("responseBody.property1 == '''a'''") - blockBuilder.toString().contains("responseBody.property2 ==~ java.util.regex.Pattern.compile('[0-9]{3}')") - + blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") } def "should generate a call with an url path and query parameters"() { @@ -278,15 +275,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification { """ } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - spockTest.contains("responseBody.property1 == '''a'''") - spockTest.contains("responseBody.property2 == '''b'''") + spockTest.contains('$[?(@.property2 == \'b\')]') + spockTest.contains('$[?(@.property1 == \'a\')]') } def "should generate test for empty body"() { @@ -301,7 +298,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { status 406 } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -322,45 +319,14 @@ class MockMvcSpockMethodBuilderSpec extends Specification { body "test" } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: spockTest.contains('def responseBody = (response.body.asString())') - spockTest.contains("responseBody == '''test'''") - } - - @Issue("#127") - def 'should use "stub" as an alias for "client"'() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property: value( - stub(123), - test(123) - ) - ) - headers { - header('Content-Type': 'application/json') - - } - - } - } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("responseBody.property == 123") + spockTest.contains('responseBody == "test"') } @Issue('113') @@ -387,7 +353,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { } } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -420,7 +386,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification { } } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -429,31 +395,38 @@ class MockMvcSpockMethodBuilderSpec extends Specification { spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''') } - @Issue('124') - def "should create proper response body matching for multiline strings"() { + def "should work with more complex stuff and jsonpaths"() { given: GroovyDsl contractDsl = GroovyDsl.make { - + priority 10 request { method 'POST' - url '/invitations' + url '/validation/client' + headers { + header 'Content-Type': 'application/json' + } + body( + bank_account_number: '0014282912345698765432161182', + email: 'foo@bar.com', + phone_number: '100299300', + personal_id: 'ABC123456' + ) } response { - status 422 - body( - message: "First line\n" + - " Second line" - ) + status 200 + body(errors: [ + [property: "bank_account_number", message: "incorrect_format"] + ]) } } - SpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains("""responseBody.message == '''First line - Second line'''""") + spockTest.contains('''$.errors[*][?(@.property == 'bank_account_number')]''') + spockTest.contains('''$.errors[*][?(@.message == 'incorrect_format')]''') } } 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 deleted file mode 100644 index 07eb9aebda..0000000000 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslResponseSpec.groovy +++ /dev/null @@ -1,52 +0,0 @@ -package io.codearte.accurest.dsl - -import groovy.json.JsonSlurper -import spock.lang.Specification - -class WireMockGroovyDslResponseSpec extends Specification { - - def 'should generate response without body for client side'() { - given: - GroovyDsl dsl = GroovyDsl.make { - response { - status 200 - } - } - expect: - new WireMockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(expectedStub) - where: - expectedStub << [''' - { - "status": 200 - } - ''', - - ''' - { - "status": 200 - } - '''] - } - - def 'should generate headers for response for client side'() { - given: - GroovyDsl dsl = GroovyDsl.make { - response { - headers { - header 'Content-Type', $(client('text/xml'), server('text/*')) - } - status 200 - } - } - expect: - new WireMockResponseStubStrategy(dsl).buildClientResponseContent() == new JsonSlurper().parseText(''' - { - "headers": { - "Content-Type": "text/xml" - }, - "status": 200 - } - ''') - } - -} 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 cb0a75255a..3356c1a7c9 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,7 +1,7 @@ package io.codearte.accurest.dsl - import groovy.json.JsonBuilder import groovy.json.JsonSlurper +import org.skyscreamer.jsonassert.JSONAssert import spock.lang.Issue class WireMockGroovyDslSpec extends WireMockSpec { @@ -35,21 +35,21 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' -{ - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}" - }, - "response": { - "status": 200, - "body": "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}", - "headers": { - "Content-Type": "text/plain" - } - } -} -''') + JSONAssert.assertEquals(''' + { + "request" : { + "urlPattern" : "/[0-9]{2}", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}", + "headers" : { + "Content-Type" : "text/plain" + } + } + } + ''', wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -80,23 +80,23 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + JSONAssert.assertEquals(''' { - "request": { - "method": "GET", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.pl.devoxx.aggregatr.v1+json" - } - }, - "url": "/ingredients" - }, - "response": { - "status": 200, - "body": "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}" + "request" : { + "url" : "/ingredients", + "method" : "GET", + "headers" : { + "Content-Type" : { + "equalTo" : "application/vnd.pl.devoxx.aggregatr.v1+json" + } } + }, + "response" : { + "status" : 200, + "body" : "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}" + } } -''') +''', wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -128,7 +128,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + JSONAssert.assertEquals(''' { "request": { "method": "POST", @@ -149,7 +149,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "body": "{\\"paymentId\\":\\"4\\",\\"foundExistingPayment\\":false}" } } -''') +''', wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -180,21 +180,21 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + JSONAssert.assertEquals((''' { - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}" - }, - "response": { - "status": 200, - "body": "{\\"created\\":\\"2014-02-02 12:23:43\\",\\"id\\":\\"123\\",\\"name\\":\\"Jan\\",\\"surname\\":\\"Kowalsky\\"}", - "headers": { - "Content-Type": "text/plain" - } + "request" : { + "urlPattern" : "/[0-9]{2}", + "method" : "GET" + }, + "response" : { + "status" : 200, + "body" : "{\\"created\\":\\"2014-02-02 12:23:43\\",\\"id\\":\\"123\\",\\"name\\":\\"Jan\\",\\"surname\\":\\"Kowalsky\\"}", + "headers" : { + "Content-Type" : "text/plain" } + } } -''') +'''), wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -227,26 +227,24 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + JSONAssert.assertEquals(''' { - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}", - "bodyPatterns": [ - { - "equalToJson":"{\\"name\\":\\"Jan\\"}" - } - ] - }, - "response": { - "status": 200, - "body": "{\\"name\\":\\"Jan\\"}", - "headers": { - "Content-Type": "text/plain" - } + "request" : { + "urlPattern" : "/[0-9]{2}", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.name == 'Jan')]" + } ] + }, + "response" : { + "status" : 200, + "body" : "{\\"name\\":\\"Jan\\"}", + "headers" : { + "Content-Type" : "text/plain" } + } } -''') +''', wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -277,22 +275,26 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' - { - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}", - "bodyPatterns": [ - { - "equalToJson": "{\\"id\\":\\"123\\",\\"surname\\":\\"Kowalsky\\",\\"name\\":\\"Jan\\",\\"created\\":\\"2014-02-02 12:23:43\\"}" - } - ] - }, - "response": { - "status": 200, - } - } - ''') + JSONAssert.assertEquals((''' +{ + "request" : { + "urlPattern" : "/[0-9]{2}", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.created == '2014-02-02 12:23:43')]" + }, { + "matchesJsonPath" : "$[?(@.surname == 'Kowalsky')]" + }, { + "matchesJsonPath" : "$[?(@.name == 'Jan')]" + }, { + "matchesJsonPath" : "$[?(@.id == '123')]" + } ] + }, + "response" : { + "status" : 200 + } +} + '''), wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -319,27 +321,25 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' - { - "request": { - "method": "GET", - "url": "/users", - "headers": { - "Content-Type": { - "equalTo": "customtype/json" - } - }, - "bodyPatterns": [ - { - "equalToJson":"{\\"name\\":\\"Jan\\"}" - } - ] - }, - "response": { - "status": 200 - } - } - ''') + JSONAssert.assertEquals((''' +{ + "request" : { + "url" : "/users", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.name == 'Jan')]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "customtype/json" + } + } + }, + "response" : { + "status" : 200 + } +} + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -364,7 +364,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -384,7 +384,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -406,7 +406,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -421,7 +421,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -443,7 +443,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -454,7 +454,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "body":"Jozo<test>" } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -474,7 +474,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -489,7 +489,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -511,7 +511,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -526,7 +526,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -559,24 +559,24 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + JSONAssert.assertEquals((''' { - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}", - "bodyPatterns": [ - {"matches": "\\\\s*\\\\{\\\\s*\\\"personalId\\\"\\\\s*:\\\\s*\\\"?^[0-9]{11}$\\\"?\\\\s*\\\\}\\\\s*"} - ] - }, - "response": { - "status": 200, - "body": "{\\"name\\":\\"Jan\\"}", - "headers": { - "Content-Type": "text/plain" - } + "request" : { + "urlPattern" : "/[0-9]{2}", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.personalId =~ /^[0-9]{11}$/)]" + } ] + }, + "response" : { + "status" : 200, + "body" : "{\\"name\\":\\"Jan\\"}", + "headers" : { + "Content-Type" : "text/plain" } + } } -''') +'''), wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -614,84 +614,35 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + JSONAssert.assertEquals((''' { - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - {"matches": "\\\\s*\\\\{\\\\s*\\"clientPesel\\"\\\\s*:\\\\s*\\"?[0-9]{10}\\"?\\\\s*,\\\\s*\\"loanAmount\\"\\\\s*:\\\\s*\\"?123.123\\"?\\\\s*\\\\}\\\\s*"} - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\\"fraudCheckStatus\\":\\"OK\\",\\"rejectionReason\\":null}" + "request" : { + "url" : "/fraudcheck", + "method" : "PUT", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.loanAmount == 123.123)]" + }, { + "matchesJsonPath" : "$[?(@.clientPesel =~ /[0-9]{10}/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/vnd.fraud.v1+json" + } } + }, + "response" : { + "status" : 200, + "body" : "{\\"fraudCheckStatus\\":\\"OK\\",\\"rejectionReason\\":null}", + "headers" : { + "Content-Type" : "application/vnd.fraud.v1+json" + } + } } -''') +'''), wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } - - def "should generate stub with GET"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method("GET") - } - } - expect: - new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' - { - "method":"GET" - } - ''') - } - - def "should generate request when two elements are provided "() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - method("GET") - url("/sth") - } - } - expect: - new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' - { - "method":"GET", - "url":"/sth" - } - ''') - } - - def "should generate request with urlPattern for client side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - url $( - client(~/^\/[0-9]{2}$/), - server('/12') - ) - } - } - expect: - new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' - { - "urlPattern":"^/[0-9]{2}$" - } - ''') - } - def "should generate request with urlPath and queryParameters for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make { @@ -717,7 +668,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -753,7 +704,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200, } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -772,7 +723,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -782,7 +733,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200, } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -801,7 +752,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -811,7 +762,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200, } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } @@ -947,7 +898,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "GET", @@ -965,46 +916,11 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200, } } - ''') + '''), json, false) and: stubMappingIsValidWireMockStub(json) } - def "should generate stub with some headers section for client side"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - request { - headers { - header('Content-Type': 'text/xml') - header('Accept': $( - client(regex('text/.*')), - server('text/plain') - )) - header('X-Custom-Header': $( - client(regex('^.*2134.*$')), - server('121345') - )) - } - } - } - expect: - new WireMockRequestStubStrategy(groovyDsl).buildClientRequestContent() == new JsonSlurper().parseText(''' - { - "headers": { - "Content-Type": { - "equalTo": "text/xml" - }, - "Accept": { - "matches": "text/.*" - }, - "X-Custom-Header": { - "matches": "^.*2134.*$" - } - } - } - ''') - } - def 'should convert groovy dsl stub with rich tree Body as String to wireMock stub for the client side'() { given: GroovyDsl groovyDsl = GroovyDsl.make { @@ -1046,25 +962,38 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' - { - "request": { - "method": "GET", - "urlPattern": "/[0-9]{2}", - "bodyPatterns": [ - { - "matches": "\\\\s*\\\\{\\\\s*\\"birthDate\\"\\\\s*:\\\\s*\\"?[0-9]{4}-[0-9]{2}-[0-9]{2}\\"?\\\\s*,\\\\s*\\"errors\\"\\\\s*:\\\\s*\\\\[\\\\s*\\\\{\\\\s*\\"propertyName\\"\\\\s*:\\\\s*\\"?[0-9]{2}\\"?\\\\s*,\\\\s*\\"providerValue\\"\\\\s*:\\\\s*\\"?Test\\"?\\\\s*\\\\}\\\\s*,\\\\s*\\\\{\\\\s*\\"propertyName\\"\\\\s*:\\\\s*\\"?[0-9]{2}\\"?\\\\s*,\\\\s*\\"providerValue\\"\\\\s*:\\\\s*\\"?Test\\"?\\\\s*\\\\}\\\\s*\\\\]\\\\s*,\\\\s*\\"firstName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"lastName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"personalId\\"\\\\s*:\\\\s*\\"?[0-9]{11}\\"?\\\\s*\\\\}\\\\s*" - } - ] }, - "response": { - "status": 200, - "body": "{\\"name\\":\\"Jan\\"}", - "headers": { - "Content-Type": "text/plain" - } - } - } - ''') + JSONAssert.assertEquals((''' +{ + "request" : { + "urlPattern" : "/[0-9]{2}", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]" + }, { + "matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]" + }, { + "matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]" + }, { + "matchesJsonPath" : "$[?(@.lastName =~ /.*/)]" + }, { + "matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]" + }, { + "matchesJsonPath" : "$[?(@.birthDate =~ /[0-9]{4}-[0-9]{2}-[0-9]{2}/)]" + }, { + "matchesJsonPath" : "$[?(@.personalId =~ /[0-9]{11}/)]" + }, { + "matchesJsonPath" : "$[?(@.firstName =~ /.*/)]" + } ] + }, + "response" : { + "status" : 200, + "body" : "{\\"name\\":\\"Jan\\"}", + "headers" : { + "Content-Type" : "text/plain" + } + } +} + '''), wireMockStub, false) } def 'should use regexp matches when request body match is defined using a map with a pattern'() { @@ -1097,26 +1026,34 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' - { - "request": { - "method": "POST", - "url": "/reissue-payment-order", - "bodyPatterns": [ - { - "matches": "\\\\s*\\\\{\\\\s*\\"loanNumber\\"\\\\s*:\\\\s*\\"?999997001\\"?\\\\s*,\\\\s*\\"amount\\"\\\\s*:\\\\s*\\"?[0-9.]+\\"?\\\\s*,\\\\s*\\"currency\\"\\\\s*:\\\\s*\\"?DKK\\"?\\\\s*,\\\\s*\\"applicationName\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"username\\"\\\\s*:\\\\s*\\"?.*\\"?\\\\s*,\\\\s*\\"cardId\\"\\\\s*:\\\\s*\\"?1\\"?\\\\s*\\\\}\\\\s*" - } - ] - }, - "response": { - "status": 200, - "body": "{\\"status\\":\\"OK\\"}", - "headers": { - "Content-Type": "application/json" - } - } - } - ''') + JSONAssert.assertEquals((''' +{ + "request" : { + "url" : "/reissue-payment-order", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.loanNumber == '999997001')]" + }, { + "matchesJsonPath" : "$[?(@.username =~ /.*/)]" + }, { + "matchesJsonPath" : "$[?(@.amount =~ /[0-9.]+/)]" + }, { + "matchesJsonPath" : "$[?(@.cardId == 1)]" + }, { + "matchesJsonPath" : "$[?(@.currency == 'DKK')]" + }, { + "matchesJsonPath" : "$[?(@.applicationName =~ /.*/)]" + } ] + }, + "response" : { + "status" : 200, + "body" : "{\\"status\\":\\"OK\\"}", + "headers" : { + "Content-Type" : "application/json" + } + } +} + '''), json, false) } def "should generate stub for empty body"() { @@ -1134,7 +1071,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "request": { "method": "POST", @@ -1149,7 +1086,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 406 } } -''') +'''), json, false) } def "should generate stub with priority"() { @@ -1167,7 +1104,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - parseJson(json) == parseJson(''' + JSONAssert.assertEquals((''' { "priority": 9, "request": { @@ -1178,7 +1115,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 406 } } - ''') + '''), json, false) } @Issue("#127") @@ -1198,21 +1135,19 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' - { - "request": { - "method": "POST", - "bodyPatterns": [ - { - "equalToJson": "{\\"property\\":\\"value\\"}" - } - ] - }, - "response": { - "status": 200 - } - } - ''') + JSONAssert.assertEquals((''' +{ + "request" : { + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.property == 'value')]" + } ] + }, + "response" : { + "status" : 200 + } +} + '''), wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -1234,7 +1169,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - new JsonSlurper().parseText(wireMockStub) == new JsonSlurper().parseText(''' + JSONAssert.assertEquals((''' { "request": { "method": "POST", @@ -1248,7 +1183,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - ''') + '''), wireMockStub, false) and: stubMappingIsValidWireMockStub(wireMockStub) } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonPathJsonConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonPathJsonConverterSpec.groovy new file mode 100644 index 0000000000..a7e9f621d7 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonPathJsonConverterSpec.groovy @@ -0,0 +1,199 @@ +package io.codearte.accurest.util +import groovy.json.JsonOutput +import groovy.json.JsonSlurper +import com.jayway.jsonpath.Configuration +import com.jayway.jsonpath.DocumentContext +import com.jayway.jsonpath.JsonPath +import com.jayway.jsonpath.Option +import net.minidev.json.JSONArray +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.regex.Pattern + +class JsonPathJsonConverterSpec extends Specification { + + @Unroll + def 'should convert a json with list as root to a map of path to value'() { + when: + JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value' + pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4 + pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1' + pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name2')]'''] == 'name2' + pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name == 'name3')]'''] == 'name3' + and: + assertThatJsonPathsInMapAreValid(json, pathAndValues) + where: + json << [ + ''' + [ { + "some" : { + "nested" : { + "json" : "with value", + "anothervalue": 4, + "withlist" : [ + { "name" :"name1"} , {"name": "name2"}, {"anothernested": { "name": "name3"} } + ] + } + } + }, + { + "someother" : { + "nested" : { + "json" : "with value", + "anothervalue": 4, + "withlist" : [ + { "name" :"name1"} , {"name": "name2"} + ] + } + } + } + ] + ''', + ''' + [{ + "someother" : { + "nested" : { + "json" : "with value", + "anothervalue": 4, + "withlist" : [ + { "name" :"name1"} , {"name": "name2"} + ] + } + } + }, + { + "some" : { + "nested" : { + "json" : "with value", + "anothervalue": 4, + "withlist" : [ + {"name": "name2"}, {"anothernested": { "name": "name3"} }, { "name" :"name1"} + ] + } + } + } + ]'''] + } + + def 'should convert a json with a map as root to a map of path to value'() { + given: + String json = ''' + { + "some" : { + "nested" : { + "json" : "with value", + "anothervalue": 4, + "withlist" : [ + { "name" :"name1"} , {"name": "name2"} + ] + } + } + } +''' + when: + JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues['''$.some.nested[?(@.json == 'with value')]'''] == 'with value' + pathAndValues['''$.some.nested[?(@.anothervalue == 4)]'''] == 4 + pathAndValues['''$.some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1' + pathAndValues['''$.some.nested.withlist[*][?(@.name == 'name2')]'''] == 'name2' + and: + assertThatJsonPathsInMapAreValid(json, pathAndValues) + } + + def 'should convert a json with a list'() { + given: + String json = ''' + { + "items" : ["HOP"] + } +''' + when: + JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues['''$.items[?(@ == 'HOP')]'''] == 'HOP' + and: + assertThatJsonPathsInMapAreValid(json, pathAndValues) + } + + + def 'should convert a json with a list of errors'() { + given: + String json = ''' + { + "errors" : [ + { "property" : "email", "message" : "inconsistent value" }, + { "property" : "email", "message" : "inconsistent value2" } + ] + } +''' + when: + JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email' + pathAndValues['''$.errors[*][?(@.message == 'inconsistent value')]'''] == 'inconsistent value' + pathAndValues['''$.errors[*][?(@.message == 'inconsistent value2')]'''] == 'inconsistent value2' + pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email' + and: + assertThatJsonPathsInMapAreValid(json, pathAndValues) + } + + + def 'should convert a map json with a regex pattern'() { + given: + List json = [ + [some: + [nested: [ + json: "with value", + anothervalue: 4, + withlist: + [ + [name: "name2"], + [name: "name1"], + [anothernested: + [name: Pattern.compile('[a-zA-Z]+')] + ], + [age: "123456789"] + ] + ] + ] + ], + [someother: + [nested: [ + json: "with value", + anothervalue: 4, + withlist: + [ + [name: "name2"], + [name: "name1"] + ] + ] + ] + ] + ] + when: + JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(json) + then: + pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value' + pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4 + pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1' + pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name2')]'''] + (pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''] as Pattern).pattern() == '[a-zA-Z]+' + when: + pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''] = "Kowalski" + json.some.nested.withlist[0][2].anothernested.name = "Kowalski" + then: + assertThatJsonPathsInMapAreValid(JsonOutput.prettyPrint(JsonOutput.toJson(json)), pathAndValues) + } + + private void assertThatJsonPathsInMapAreValid(String json, JsonPaths pathAndValues) { + DocumentContext parsedJson = JsonPath.using(Configuration.builder().options(Option.ALWAYS_RETURN_LIST).build()).parse(json); + pathAndValues.each { + assert parsedJson.read(it.jsonPath, JSONArray).getAt(it.optionalSuffix ?: 0) == it.optionalSuffix ? [it.value] : it.value + } + } + +} 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 dcec7b2f61..f93809b40a 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 @@ -4,6 +4,7 @@ import io.codearte.accurest.config.AccurestConfigProperties import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.artifacts.DependencyResolveDetails /** * @author Jakub Kubrynski @@ -29,6 +30,21 @@ class AccurestGradlePlugin implements Plugin { createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() + project.dependencies.add("testCompile", "io.codearte.accurest:accurest-core:+") + project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:wiremock:0.0.1") + project.repositories { jcenter() } + project.configurations { + all { + resolutionStrategy { + eachDependency { DependencyResolveDetails details -> + if (details.requested.group == 'com.github.tomakehurst' && details.requested.name == "wiremock") { + details.useTarget("com.blogspot.toomuchcoding:wiremock:0.0.1") + } + } + } + } + } + project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 068c0f6e47..aa4e17339c 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -18,7 +18,6 @@ ext { subprojects { apply plugin: 'groovy' - repositories { mavenCentral() mavenLocal() diff --git a/build.gradle b/build.gradle index 8b8d47bb77..b77eab32f6 100644 --- a/build.gradle +++ b/build.gradle @@ -48,6 +48,7 @@ subprojects { repositories { mavenLocal() mavenCentral() + jcenter() } //Dependencies in all subprojects - http://solidsoft.wordpress.com/2014/11/13/gradle-tricks-display-dependencies-for-all-subprojects-in-multi-project-build/ @@ -84,15 +85,21 @@ subprojects { } project(':accurest-core') { + dependencies { compile 'org.slf4j:slf4j-api:[1.6.0,)' compile 'org.codehaus.plexus:plexus-utils:[3.0.0,)' compile 'commons-io:commons-io:[2.0,)' compile 'org.apache.commons:commons-lang3:[3.3,)' + compile 'com.google.code.gson:gson:2.3.1' + compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' + compile 'asm:asm:3.3.1' + compile 'com.blogspot.toomuchcoding:wiremock:0.0.1' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - testCompile 'com.github.tomakehurst:wiremock:1.57' + testCompile 'org.skyscreamer:jsonassert:1.2.3' } + } project(':accurest-converters') { @@ -101,7 +108,7 @@ project(':accurest-converters') { compile 'org.apache.commons:commons-lang3:[3.0,)' compile 'commons-io:commons-io:[2.0,)' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger - testCompile 'com.github.tomakehurst:wiremock:1.57' + testCompile 'com.blogspot.toomuchcoding:wiremock:0.0.1' testCompile 'org.hamcrest:hamcrest-all:1.3' } } diff --git a/gradle/release.gradle b/gradle/release.gradle index 34e8ae08ef..3300caac3c 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -12,7 +12,7 @@ task sourcesJar(type: Jar) { } artifacts { - archives javadocJar, sourcesJar + archives javadocJar, sourcesJar, repackagedJar } signing { From 0021a0dd70820cdf2848cd5cc4d2d036f9b92da7 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 30 Aug 2015 19:33:21 +0200 Subject: [PATCH 200/719] Went towards beta version of wiremock --- .../dsl/WireMockResponseStubStrategy.groovy | 21 +++++++++---------- .../plugin/AccurestGradlePlugin.groovy | 6 +----- build.gradle | 6 ++++-- gradle/release.gradle | 2 +- 4 files changed, 16 insertions(+), 19 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy index 5af5898257..3df86b21ef 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy @@ -25,30 +25,29 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { @PackageScope ResponseDefinition buildClientResponseContent() { - ResponseDefinition responseDefinition = new ResponseDefinition() - responseDefinition.setStatus(response.status.clientValue as Integer) - appendHeaders(responseDefinition) - appendBody(responseDefinition) - return responseDefinition + int status = response.status.clientValue as Integer + HttpHeaders httpHeaders = getHttpHeaders() + String body = getBody() + return new ResponseDefinition(status, body as String, null, null, null, httpHeaders, null, null, null, null, null) } - private void appendHeaders(ResponseDefinition responseDefinition) { + private HttpHeaders getHttpHeaders() { if(!(response.headers)) { - return + return null } - responseDefinition.setHeaders(new HttpHeaders(response.headers.entries?.collect { new HttpHeader(it.name, it.clientValue.toString()) })) + return new HttpHeaders(response.headers.entries?.collect { new HttpHeader(it.name, it.clientValue.toString()) }) } - private void appendBody(ResponseDefinition responseDefinition) { + private String getBody() { if (!response.body) { - return + return null } Object body = response.body.clientValue ContentType contentType = recognizeContentTypeFromHeader(response.headers) if (contentType == ContentType.UNKNOWN) { contentType = recognizeContentTypeFromContent(body) } - responseDefinition.setBody(parseBody(body, contentType)) + return parseBody(body, contentType) } 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 f93809b40a..1e905a9ff5 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,5 +1,4 @@ package io.codearte.accurest.plugin - import io.codearte.accurest.config.AccurestConfigProperties import org.gradle.api.Plugin import org.gradle.api.Project @@ -30,11 +29,9 @@ class AccurestGradlePlugin implements Plugin { createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() - project.dependencies.add("testCompile", "io.codearte.accurest:accurest-core:+") - project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:wiremock:0.0.1") - project.repositories { jcenter() } project.configurations { all { + exclude group: 'org.glassfish.jersey.jetty', module: 'jetty-server' resolutionStrategy { eachDependency { DependencyResolveDetails details -> if (details.requested.group == 'com.github.tomakehurst' && details.requested.name == "wiremock") { @@ -45,7 +42,6 @@ class AccurestGradlePlugin implements Plugin { } } - project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) if (hasIdea) { diff --git a/build.gradle b/build.gradle index b77eab32f6..2ff7dc03cf 100644 --- a/build.gradle +++ b/build.gradle @@ -94,7 +94,9 @@ project(':accurest-core') { compile 'com.google.code.gson:gson:2.3.1' compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' compile 'asm:asm:3.3.1' - compile 'com.blogspot.toomuchcoding:wiremock:0.0.1' + compile('com.github.tomakehurst:wiremock:2.0.0-beta') { + exclude group: 'org.mortbay.jetty', module: 'servlet-api' + } testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile 'org.skyscreamer:jsonassert:1.2.3' @@ -108,7 +110,7 @@ project(':accurest-converters') { compile 'org.apache.commons:commons-lang3:[3.0,)' compile 'commons-io:commons-io:[2.0,)' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger - testCompile 'com.blogspot.toomuchcoding:wiremock:0.0.1' + testCompile 'com.github.tomakehurst:wiremock:2.0.0-beta' testCompile 'org.hamcrest:hamcrest-all:1.3' } } diff --git a/gradle/release.gradle b/gradle/release.gradle index 3300caac3c..34e8ae08ef 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -12,7 +12,7 @@ task sourcesJar(type: Jar) { } artifacts { - archives javadocJar, sourcesJar, repackagedJar + archives javadocJar, sourcesJar } signing { From ca2c051ea22126a9fe31314212641773961aa56f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 30 Aug 2015 20:44:44 +0200 Subject: [PATCH 201/719] Revert "Went towards beta version of wiremock" This reverts commit 0021a0dd70820cdf2848cd5cc4d2d036f9b92da7. --- .../dsl/WireMockResponseStubStrategy.groovy | 21 ++++++++++--------- .../plugin/AccurestGradlePlugin.groovy | 6 +++++- build.gradle | 6 ++---- gradle/release.gradle | 2 +- 4 files changed, 19 insertions(+), 16 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy index 3df86b21ef..5af5898257 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy @@ -25,29 +25,30 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { @PackageScope ResponseDefinition buildClientResponseContent() { - int status = response.status.clientValue as Integer - HttpHeaders httpHeaders = getHttpHeaders() - String body = getBody() - return new ResponseDefinition(status, body as String, null, null, null, httpHeaders, null, null, null, null, null) + ResponseDefinition responseDefinition = new ResponseDefinition() + responseDefinition.setStatus(response.status.clientValue as Integer) + appendHeaders(responseDefinition) + appendBody(responseDefinition) + return responseDefinition } - private HttpHeaders getHttpHeaders() { + private void appendHeaders(ResponseDefinition responseDefinition) { if(!(response.headers)) { - return null + return } - return new HttpHeaders(response.headers.entries?.collect { new HttpHeader(it.name, it.clientValue.toString()) }) + responseDefinition.setHeaders(new HttpHeaders(response.headers.entries?.collect { new HttpHeader(it.name, it.clientValue.toString()) })) } - private String getBody() { + private void appendBody(ResponseDefinition responseDefinition) { if (!response.body) { - return null + return } Object body = response.body.clientValue ContentType contentType = recognizeContentTypeFromHeader(response.headers) if (contentType == ContentType.UNKNOWN) { contentType = recognizeContentTypeFromContent(body) } - return parseBody(body, contentType) + responseDefinition.setBody(parseBody(body, contentType)) } 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 1e905a9ff5..f93809b40a 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,4 +1,5 @@ package io.codearte.accurest.plugin + import io.codearte.accurest.config.AccurestConfigProperties import org.gradle.api.Plugin import org.gradle.api.Project @@ -29,9 +30,11 @@ class AccurestGradlePlugin implements Plugin { createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() + project.dependencies.add("testCompile", "io.codearte.accurest:accurest-core:+") + project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:wiremock:0.0.1") + project.repositories { jcenter() } project.configurations { all { - exclude group: 'org.glassfish.jersey.jetty', module: 'jetty-server' resolutionStrategy { eachDependency { DependencyResolveDetails details -> if (details.requested.group == 'com.github.tomakehurst' && details.requested.name == "wiremock") { @@ -42,6 +45,7 @@ class AccurestGradlePlugin implements Plugin { } } + project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) if (hasIdea) { diff --git a/build.gradle b/build.gradle index 2ff7dc03cf..b77eab32f6 100644 --- a/build.gradle +++ b/build.gradle @@ -94,9 +94,7 @@ project(':accurest-core') { compile 'com.google.code.gson:gson:2.3.1' compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' compile 'asm:asm:3.3.1' - compile('com.github.tomakehurst:wiremock:2.0.0-beta') { - exclude group: 'org.mortbay.jetty', module: 'servlet-api' - } + compile 'com.blogspot.toomuchcoding:wiremock:0.0.1' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile 'org.skyscreamer:jsonassert:1.2.3' @@ -110,7 +108,7 @@ project(':accurest-converters') { compile 'org.apache.commons:commons-lang3:[3.0,)' compile 'commons-io:commons-io:[2.0,)' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger - testCompile 'com.github.tomakehurst:wiremock:2.0.0-beta' + testCompile 'com.blogspot.toomuchcoding:wiremock:0.0.1' testCompile 'org.hamcrest:hamcrest-all:1.3' } } diff --git a/gradle/release.gradle b/gradle/release.gradle index 34e8ae08ef..3300caac3c 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -12,7 +12,7 @@ task sourcesJar(type: Jar) { } artifacts { - archives javadocJar, sourcesJar + archives javadocJar, sourcesJar, repackagedJar } signing { From 365af5981aa5d0e95882bf29432b31ac2e182134 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Wed, 2 Sep 2015 22:46:30 +0200 Subject: [PATCH 202/719] Simplify release mechanism --- build.gradle | 34 +---------------- gradle/release.gradle | 88 ++++++++++++++++--------------------------- 2 files changed, 34 insertions(+), 88 deletions(-) diff --git a/build.gradle b/build.gradle index 8b8d47bb77..7a0bace6ef 100644 --- a/build.gradle +++ b/build.gradle @@ -5,17 +5,12 @@ buildscript { } dependencies { classpath "pl.allegro.tech.build:axion-release-plugin:1.2.2" + classpath "com.bmuschko:gradle-nexus-plugin:2.3" classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.3" } } apply plugin: "pl.allegro.tech.build.axion-release" -apply plugin: 'io.codearte.nexus-staging' - -nexusStaging { - packageGroup = "io.codearte" - stagingProfileId = '93c08fdebde1ff' -} scmVersion { tag { prefix = "accurest" } @@ -34,11 +29,7 @@ allprojects { subprojects { apply plugin: 'groovy' - apply plugin: 'maven-publish' - - if (!version.contains('SNAPSHOT')) { - apply from: "$rootDir/gradle/release.gradle" - } + apply from: "$rootDir/gradle/release.gradle" group = 'io.codearte.accurest' @@ -60,27 +51,6 @@ subprojects { exclude(group: 'org.codehaus.groovy') } } - - publishing { - publications { - maven(MavenPublication) { - from components.java - pom.withXml { - //#89 - workaround to not to have only runtime dependencies in generated pom.xml - //Known limitation in maven-publish - - http://forums.gradle.org/gradle/topics/maven_publish_plugin_generated_pom_making_dependency_scope_runtime#reply_14120711 - asNode().dependencies.'*'.findAll() { - it.scope.text() == 'runtime' && project.configurations.compile.allDependencies.find { dep -> - dep.name == it.artifactId.text() - } - }.each() { - it.scope*.value = 'compile' - } - } - } - } - } - - uploadArchives.dependsOn { check } } project(':accurest-core') { diff --git a/gradle/release.gradle b/gradle/release.gradle index 34e8ae08ef..abe79f9d5e 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -1,64 +1,40 @@ -apply plugin: 'maven' -apply plugin: 'signing' +apply plugin: 'com.bmuschko.nexus' +apply plugin: 'io.codearte.nexus-staging' -task javadocJar(type: Jar) { - classifier = 'javadoc' - from javadoc -} +modifyPom { + project { + name "$project.name" + packaging 'jar' + description 'RESTful Contract Verifier' + url 'https://github.com/Codearte/accurest' + inceptionYear '2014' -task sourcesJar(type: Jar) { - classifier = 'sources' - from sourceSets.main.allSource -} + scm { + connection 'scm:git:git@github.com:Codearte/accurest.git' + developerConnection 'scm:git:git@github.com:Codearte/accurest.git' + url 'https://github.com/Codearte/accurest' + } -artifacts { - archives javadocJar, sourcesJar -} - -signing { - sign configurations.archives -} - -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: nexusUsername, password: nexusPassword) + licenses { + license { + name 'The Apache License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' } + } - snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: nexusUsername, password: nexusPassword) - } - - pom.project { - name "$project.name" - packaging 'jar' - description 'RESTful Contract Verifier' - url 'http://codearte.github.io/accurest' - - scm { - connection 'scm:git:git@github.com:Codearte/accurest.git' - developerConnection 'scm:git:git@github.com:Codearte/accurest.git' - url 'https://github.com/Codearte/accurest' - } - - licenses { - license { - name 'The Apache License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } - - developers { - developer { - id 'jkubrynski' - name 'Jakub Kubrynski' - email 'jk ATT codearte DOTT io' - } - } + developers { + developer { + id 'jkubrynski' + name 'Jakub Kubrynski' + email 'jk ATT codearte DOTT io' } } } -} \ No newline at end of file +} + +uploadArchives.dependsOn { check } + +nexusStaging { + packageGroup = "io.codearte" + stagingProfileId = '93c08fdebde1ff' +} From 0129666047b12e93b8c8f958a81a3625a1819e41 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Wed, 2 Sep 2015 22:49:40 +0200 Subject: [PATCH 203/719] Add marcingrzejszczak as a developer in pom.xml --- gradle/release.gradle | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gradle/release.gradle b/gradle/release.gradle index abe79f9d5e..8052622761 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -28,6 +28,11 @@ modifyPom { name 'Jakub Kubrynski' email 'jk ATT codearte DOTT io' } + developer { + id 'marcingrzejszczak' + name 'Marcin Grzejszczak' + email 'marcin ATT grzejszczak DOTT pl' + } } } } From 9a5afb849de5b898054b42faa03907c14c814ff2 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Thu, 3 Sep 2015 00:09:48 +0200 Subject: [PATCH 204/719] nexus-staging-plugin is applied only in root project --- build.gradle | 7 +++++++ gradle/release.gradle | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/build.gradle b/build.gradle index 7a0bace6ef..e6cb6bf127 100644 --- a/build.gradle +++ b/build.gradle @@ -27,6 +27,13 @@ allprojects { project.version = scmVersion.version } +apply plugin: 'io.codearte.nexus-staging' + +nexusStaging { + packageGroup = "io.codearte" + stagingProfileId = '93c08fdebde1ff' +} + subprojects { apply plugin: 'groovy' apply from: "$rootDir/gradle/release.gradle" diff --git a/gradle/release.gradle b/gradle/release.gradle index 8052622761..32e134b828 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -1,5 +1,4 @@ apply plugin: 'com.bmuschko.nexus' -apply plugin: 'io.codearte.nexus-staging' modifyPom { project { @@ -38,8 +37,3 @@ modifyPom { } uploadArchives.dependsOn { check } - -nexusStaging { - packageGroup = "io.codearte" - stagingProfileId = '93c08fdebde1ff' -} From bc51211a504f28c1a7a7cc35af2622102b6d840b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 2 Sep 2015 23:57:49 +0200 Subject: [PATCH 205/719] [#123] Removed obsolete accurest-core dependency --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 1 - 1 file changed, 1 deletion(-) 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 f93809b40a..e7c9feafde 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 @@ -30,7 +30,6 @@ class AccurestGradlePlugin implements Plugin { createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() - project.dependencies.add("testCompile", "io.codearte.accurest:accurest-core:+") project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:wiremock:0.0.1") project.repositories { jcenter() } project.configurations { From 14deedec760f01c4ea0fe83cb4cc4349587b495e Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Thu, 3 Sep 2015 00:40:19 +0200 Subject: [PATCH 206/719] Travis should run also functional tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 074a9aabda..bdf2cb280b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,4 +12,4 @@ cache: - $HOME/.m2 install: ./gradlew assemble -script: ./gradlew check --stacktrace --info --continue \ No newline at end of file +script: ./gradlew check funcTest --stacktrace --info --continue From 7122e3006ed05d4622edd35a72d573ff7b44526d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 3 Sep 2015 00:46:48 +0200 Subject: [PATCH 207/719] Fixed the functional tests --- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 99 ++++++++++--------- .../plugin/BasicFunctionalSpec.groovy | 42 ++++---- .../accurest/util/AssertionUtil.groovy | 12 +++ build.gradle | 11 ++- settings.gradle | 2 +- 5 files changed, 94 insertions(+), 72 deletions(-) create mode 100644 accurest-testing-utils/src/main/groovy/io/codearte/accurest/util/AssertionUtil.groovy 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 3356c1a7c9..548f309b00 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,7 +1,8 @@ package io.codearte.accurest.dsl + import groovy.json.JsonBuilder import groovy.json.JsonSlurper -import org.skyscreamer.jsonassert.JSONAssert +import io.codearte.accurest.util.AssertionUtil import spock.lang.Issue class WireMockGroovyDslSpec extends WireMockSpec { @@ -35,7 +36,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals(''' + AssertionUtil.assertThatJsonsAreEqual(''' { "request" : { "urlPattern" : "/[0-9]{2}", @@ -49,7 +50,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } } } - ''', wireMockStub, false) + ''', wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -80,7 +81,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals(''' + AssertionUtil.assertThatJsonsAreEqual(''' { "request" : { "url" : "/ingredients", @@ -96,7 +97,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "body" : "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}" } } -''', wireMockStub, false) +''', wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -128,7 +129,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals(''' + AssertionUtil.assertThatJsonsAreEqual(''' { "request": { "method": "POST", @@ -149,7 +150,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "body": "{\\"paymentId\\":\\"4\\",\\"foundExistingPayment\\":false}" } } -''', wireMockStub, false) +''', wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -180,7 +181,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { "urlPattern" : "/[0-9]{2}", @@ -194,7 +195,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } } } -'''), wireMockStub, false) +'''), wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -227,7 +228,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals(''' + AssertionUtil.assertThatJsonsAreEqual(''' { "request" : { "urlPattern" : "/[0-9]{2}", @@ -244,7 +245,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } } } -''', wireMockStub, false) +''', wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -275,7 +276,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { "urlPattern" : "/[0-9]{2}", @@ -294,7 +295,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status" : 200 } } - '''), wireMockStub, false) + '''), wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -321,7 +322,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { "url" : "/users", @@ -339,7 +340,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status" : 200 } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -364,7 +365,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -384,7 +385,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -406,7 +407,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -421,7 +422,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -443,7 +444,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -454,7 +455,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "body":"Jozo<test>" } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -474,7 +475,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -489,7 +490,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -511,7 +512,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -526,7 +527,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -559,7 +560,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { "urlPattern" : "/[0-9]{2}", @@ -576,7 +577,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } } } -'''), wireMockStub, false) +'''), wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -614,7 +615,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { "url" : "/fraudcheck", @@ -638,7 +639,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } } } -'''), wireMockStub, false) +'''), wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -668,7 +669,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -704,7 +705,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200, } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -723,7 +724,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -733,7 +734,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200, } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -752,7 +753,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -762,7 +763,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200, } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -898,7 +899,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "GET", @@ -916,7 +917,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200, } } - '''), json, false) + '''), json) and: stubMappingIsValidWireMockStub(json) } @@ -962,7 +963,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { "urlPattern" : "/[0-9]{2}", @@ -993,7 +994,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } } } - '''), wireMockStub, false) + '''), wireMockStub) } def 'should use regexp matches when request body match is defined using a map with a pattern'() { @@ -1026,7 +1027,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { "url" : "/reissue-payment-order", @@ -1053,7 +1054,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { } } } - '''), json, false) + '''), json) } def "should generate stub for empty body"() { @@ -1071,7 +1072,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "POST", @@ -1086,7 +1087,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 406 } } -'''), json, false) +'''), json) } def "should generate stub with priority"() { @@ -1104,7 +1105,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: def json = toWireMockClientJsonStub(groovyDsl) then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "priority": 9, "request": { @@ -1115,7 +1116,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 406 } } - '''), json, false) + '''), json) } @Issue("#127") @@ -1135,7 +1136,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { "method" : "POST", @@ -1147,7 +1148,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status" : 200 } } - '''), wireMockStub, false) + '''), wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } @@ -1169,7 +1170,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { when: String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() then: - JSONAssert.assertEquals((''' + AssertionUtil.assertThatJsonsAreEqual((''' { "request": { "method": "POST", @@ -1183,7 +1184,7 @@ class WireMockGroovyDslSpec extends WireMockSpec { "status": 200 } } - '''), wireMockStub, false) + '''), wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } 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 5b101daa03..a54d20308e 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 @@ -1,6 +1,6 @@ package io.codearte.accurest.plugin -import groovy.json.JsonSlurper +import io.codearte.accurest.util.AssertionUtil import nebula.test.IntegrationSpec import spock.lang.Stepwise @@ -41,26 +41,26 @@ class BasicFunctionalSpec extends IntegrationSpec { runTasksSuccessfully('generateWireMockClientStubs') then: def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text - new JsonSlurper().parseText(generatedClientJsonStub) == new JsonSlurper().parseText(""" -{ - "priority": 2, - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/json" - } - }, - "url": "/api/12", - "bodyPatterns": [ - { "equalToJson": "[{\\"text\\":\\"Gonna see you at Warsaw\\"}]" } - ] - }, - "response": { - "status": 200 - } -} -""") + AssertionUtil.assertThatJsonsAreEqual(""" + { + "request" : { + "url" : "/api/12", + "method" : "PUT", + "bodyPatterns" : [ { + "matchesJsonPath" : "\$[*][?(@.text == 'Gonna see you at Warsaw')]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 200 + }, + "priority" : 2 + } + """, generatedClientJsonStub) } def "tasks should be up-to-date when appropriate"() { diff --git a/accurest-testing-utils/src/main/groovy/io/codearte/accurest/util/AssertionUtil.groovy b/accurest-testing-utils/src/main/groovy/io/codearte/accurest/util/AssertionUtil.groovy new file mode 100644 index 0000000000..4c632a4de3 --- /dev/null +++ b/accurest-testing-utils/src/main/groovy/io/codearte/accurest/util/AssertionUtil.groovy @@ -0,0 +1,12 @@ +package io.codearte.accurest.util + +import org.skyscreamer.jsonassert.JSONAssert + +class AssertionUtil { + + private static boolean NON_STRICT = false + + public static void assertThatJsonsAreEqual(String expected, String actual) { + JSONAssert.assertEquals(expected, actual, NON_STRICT) + } +} diff --git a/build.gradle b/build.gradle index ed8eb470e7..7f78c6ad8a 100644 --- a/build.gradle +++ b/build.gradle @@ -74,7 +74,15 @@ project(':accurest-core') { compile 'com.blogspot.toomuchcoding:wiremock:0.0.1' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - testCompile 'org.skyscreamer:jsonassert:1.2.3' + testCompile project(':accurest-testing-utils') + } + +} + +project(':accurest-testing-utils') { + + dependencies { + compile 'org.skyscreamer:jsonassert:1.2.3' } } @@ -99,6 +107,7 @@ project(':accurest-gradle-plugin') { testCompile('com.netflix.nebula:nebula-test:2.2.1') { exclude(group: 'org.spockframework') } + testCompile project(':accurest-testing-utils') } test { diff --git a/settings.gradle b/settings.gradle index 148580177b..7a36841ba8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ -include "accurest-core", "accurest-gradle-plugin", 'accurest-converters' +include "accurest-core", "accurest-gradle-plugin", 'accurest-converters', 'accurest-testing-utils' rootProject.name = "accurest" From 7782d82ba43960a6319e01b7821645fd5450bf2a Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Thu, 3 Sep 2015 00:56:41 +0200 Subject: [PATCH 208/719] Release version: 0.9.0 [ci skip] From f824415523cf28a58cea042c3adac4a24f744ae8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 3 Sep 2015 14:17:59 +0200 Subject: [PATCH 209/719] [PPL-202] Fixed GString support in body with regex --- .../builder/SpockMethodBodyBuilder.groovy | 4 +-- .../dsl/WireMockRequestStubStrategy.groovy | 8 ++--- .../dsl/internal/RegexPatterns.groovy | 2 +- ...groovy => JsonToJsonPathsConverter.groovy} | 15 ++++++-- .../accurest/util/RegexpBuilders.groovy | 33 +++++++++++++---- .../MockMvcSpockMethodBuilderSpec.groovy | 35 +++++++++++++++++++ ...vy => JsonToJsonPathsConverterSpec.groovy} | 12 +++---- build.gradle | 3 +- 8 files changed, 88 insertions(+), 24 deletions(-) rename accurest-core/src/main/groovy/io/codearte/accurest/util/{JsonPathJsonConverter.groovy => JsonToJsonPathsConverter.groovy} (90%) rename accurest-core/src/test/groovy/io/codearte/accurest/util/{JsonPathJsonConverterSpec.groovy => JsonToJsonPathsConverterSpec.groovy} (89%) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 49df619015..dbd0663ac9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -6,7 +6,7 @@ import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.* import io.codearte.accurest.util.ContentType import io.codearte.accurest.util.MapConverter -import io.codearte.accurest.util.JsonPathJsonConverter +import io.codearte.accurest.util.JsonToJsonPathsConverter import io.codearte.accurest.util.JsonPaths import static io.codearte.accurest.util.ContentUtils.* @@ -86,7 +86,7 @@ abstract class SpockMethodBodyBuilder { } if (contentType == ContentType.JSON) { appendJsonPath(bb, responseAsString) - JsonPaths jsonPaths = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(responseBody) + JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) jsonPaths.each { it.buildJsonPathComparison('parsedJson').each { bb.addLine(it) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index 923b614f7a..c87a1cebac 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -9,14 +9,14 @@ import groovy.transform.TypeCheckingMode import io.codearte.accurest.dsl.internal.* import io.codearte.accurest.util.ContentType import io.codearte.accurest.util.ContentUtils -import io.codearte.accurest.util.JsonPathJsonConverter +import io.codearte.accurest.util.JsonToJsonPathsConverter import io.codearte.accurest.util.JsonPaths import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern import static io.codearte.accurest.util.ContentUtils.* -import static io.codearte.accurest.util.RegexpBuilders.buildGStringRegexpMatch +import static io.codearte.accurest.util.RegexpBuilders.buildGStringRegexpForStubSide import static io.codearte.accurest.util.RegexpBuilders.buildJSONRegexpMatch @TypeChecked @@ -53,7 +53,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { } ContentType contentType = tryToGetContentType() if (contentType == ContentType.JSON) { - JsonPaths values = JsonPathJsonConverter.transformToJsonPathWithStubsSideValues(getMatchingStrategyFromBody(request.body)?.clientValue) + JsonPaths values = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValues(getMatchingStrategyFromBody(request.body)?.clientValue) if (values.empty) { requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT, equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ] @@ -183,7 +183,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { case ContentType.JSON: return new MatchingStrategy(buildJSONRegexpMatch(value), MatchingStrategy.Type.MATCHING) case ContentType.UNKNOWN: - return new MatchingStrategy(buildGStringRegexpMatch(value), MatchingStrategy.Type.MATCHING) + return new MatchingStrategy(buildGStringRegexpForStubSide(value), MatchingStrategy.Type.MATCHING) case ContentType.XML: throw new IllegalStateException("XML pattern matching is not implemented yet") } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy index 210668a2a9..432dee266d 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy @@ -9,7 +9,7 @@ class RegexPatterns { private static final Pattern IP_ADDRESS = Pattern.compile('([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])'); private static final Pattern HOSTNAME_PATTERN = Pattern.compile('((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?'); - private static final Pattern EMAIL = Pattern.compile('[_]*([a-z0-9]+(\\.|_*)?)+@([a-z][a-z0-9-]+(\\.|-*\\.))+[a-z]{2,6}'); + private static final Pattern EMAIL = Pattern.compile('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'); private static final Pattern URL = Pattern.compile('((www\\.|(http|https|ftp|news|file)+\\:\\/\\/)[_.a-z0-9-]+\\.[a-z0-9\\/_:@=.+?,##%&~-]*[^.|\\\'|\\# |!|\\(|?|,| |>|<|;|\\)])'); String ipAddress() { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathJsonConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy similarity index 90% rename from accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathJsonConverter.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 28625a1cbf..6a749346a7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathJsonConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -8,7 +8,7 @@ import java.util.regex.Pattern /** * @author Marcin Grzejszczak */ -class JsonPathJsonConverter { +class JsonToJsonPathsConverter { private static final Boolean SERVER_SIDE = false private static final Boolean CLIENT_SIDE = true @@ -42,11 +42,18 @@ class JsonPathJsonConverter { private static Object getClientOrServerSideValues(json, boolean clientSide) { return MapConverter.transformValues(json) { - boolean dslProp = it instanceof DslProperty - if (dslProp) { + if (it instanceof DslProperty) { DslProperty dslProperty = ((DslProperty) it) return clientSide ? getClientOrServerSideValues(dslProperty.clientValue, clientSide) : getClientOrServerSideValues(dslProperty.serverValue, clientSide) + } else if (it instanceof GString) { + return ContentUtils.extractValue(it , null, { + if (it instanceof DslProperty) { + return clientSide ? + getClientOrServerSideValues((it as DslProperty).clientValue, clientSide) : getClientOrServerSideValues((it as DslProperty).serverValue, clientSide) + } + return it + }) } return it } @@ -142,6 +149,8 @@ class JsonPathJsonConverter { protected static String compareWith(Object value) { if (value instanceof Pattern) { return """=~ /${(value as Pattern).pattern()}/""" + } else if (value instanceof GString) { + return """=~ /${RegexpBuilders.buildGStringRegexpForTestSide(value)}/""" } return """== ${potentiallyWrappedWithQuotesValue(value)}""" } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy index 47cb595220..6c8b703fca 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy @@ -10,29 +10,48 @@ import static org.apache.commons.lang3.StringEscapeUtils.escapeJson public class RegexpBuilders { - public static String buildGStringRegexpMatch(GString gString) { + public static String buildGStringRegexpForStubSide(GString gString) { new GStringImpl( - gString.values.collect(this.&buildGStringRegexpMatch) as Object[], + gString.values.collect(this.&buildGStringRegexpForStubSide) as Object[], gString.strings.collect(this.&escapeSpecialRegexChars) as String[] ) } - public static String buildGStringRegexpMatch(Pattern pattern) { + public static String buildGStringRegexpForStubSide(Pattern pattern) { return pattern.pattern() } - public static String buildGStringRegexpMatch(DslProperty dslProperty) { - return buildGStringRegexpMatch(dslProperty.clientValue) + public static String buildGStringRegexpForStubSide(DslProperty dslProperty) { + return buildGStringRegexpForStubSide(dslProperty.clientValue) } - public static String buildGStringRegexpMatch(Object o) { + public static String buildGStringRegexpForStubSide(Object o) { return escapeSpecialRegexChars(o.toString()) } + public static String buildGStringRegexpForTestSide(GString gString) { + new GStringImpl( + gString.values.collect(this.&buildGStringRegexpForTestSide) as Object[], + gString.strings.collect(this.&escapeSpecialRegexChars) as String[] + ) + } + + public static String buildGStringRegexpForTestSide(Pattern pattern) { + return pattern.pattern() + } + + public static String buildGStringRegexpForTestSide(DslProperty dslProperty) { + return buildGStringRegexpForTestSide(dslProperty.clientValue) + } + + public static String buildGStringRegexpForTestSide(Object o) { + return o.toString().replaceAll('\\\\', '\\\\\\\\') + } + private final static Pattern SPECIAL_REGEX_CHARS = Pattern.compile('[{}()\\[\\].+*?^$\\\\|]') private static String escapeSpecialRegexChars(String str) { - return SPECIAL_REGEX_CHARS.matcher(str).replaceAll('\\\\$0') + return SPECIAL_REGEX_CHARS.matcher(str).replaceAll('\\\\\\\\$0') } private final static String WS = /\s*/ diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index dcbf988168..5d25d94874 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -429,4 +429,39 @@ class MockMvcSpockMethodBuilderSpec extends Specification { spockTest.contains('''$.errors[*][?(@.property == 'bank_account_number')]''') spockTest.contains('''$.errors[*][?(@.message == 'incorrect_format')]''') } + + def "should resolve properties in GString with regular expression"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(client(regex(email())), server('not.existing@user.com')), + callback_url: $(client(regex(hostname())), server('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: 4, + message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + ) + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''') + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonPathJsonConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy similarity index 89% rename from accurest-core/src/test/groovy/io/codearte/accurest/util/JsonPathJsonConverterSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index a7e9f621d7..5348c77fd5 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonPathJsonConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -11,12 +11,12 @@ import spock.lang.Unroll import java.util.regex.Pattern -class JsonPathJsonConverterSpec extends Specification { +class JsonToJsonPathsConverterSpec extends Specification { @Unroll def 'should convert a json with list as root to a map of path to value'() { when: - JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value' pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4 @@ -94,7 +94,7 @@ class JsonPathJsonConverterSpec extends Specification { } ''' when: - JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues['''$.some.nested[?(@.json == 'with value')]'''] == 'with value' pathAndValues['''$.some.nested[?(@.anothervalue == 4)]'''] == 4 @@ -112,7 +112,7 @@ class JsonPathJsonConverterSpec extends Specification { } ''' when: - JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues['''$.items[?(@ == 'HOP')]'''] == 'HOP' and: @@ -131,7 +131,7 @@ class JsonPathJsonConverterSpec extends Specification { } ''' when: - JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email' pathAndValues['''$.errors[*][?(@.message == 'inconsistent value')]'''] == 'inconsistent value' @@ -175,7 +175,7 @@ class JsonPathJsonConverterSpec extends Specification { ] ] when: - JsonPaths pathAndValues = JsonPathJsonConverter.transformToJsonPathWithTestsSideValues(json) + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) then: pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value' pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4 diff --git a/build.gradle b/build.gradle index 7f78c6ad8a..c1739aa58c 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,8 @@ scmVersion { } allprojects { - project.version = scmVersion.version + //project.version = scmVersion.version + project.version = '0.9.1-SNAPSHOT' } apply plugin: 'io.codearte.nexus-staging' From 052068db462de79c2388aadf78a49af8182a7790 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Wed, 2 Sep 2015 22:46:30 +0200 Subject: [PATCH 210/719] Simplify release mechanism --- gradle/release.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/gradle/release.gradle b/gradle/release.gradle index 32e134b828..e3f5159bb1 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -37,3 +37,4 @@ modifyPom { } uploadArchives.dependsOn { check } + From f9c7ebc64450e7e21022dde9c61828ff967cd546 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 3 Sep 2015 14:17:59 +0200 Subject: [PATCH 211/719] Fixed issues with GString and Regex --- .../MockMvcSpockMethodBodyBuilder.groovy | 7 +- .../builder/SpockMethodBodyBuilder.groovy | 5 + .../dsl/BaseWireMockStubStrategy.groovy | 20 +++- .../dsl/WireMockRequestStubStrategy.groovy | 28 ++--- .../util/JsonToJsonPathsConverter.groovy | 22 +--- .../accurest/util/MapConverter.groovy | 18 +++ .../JaxRsClientSpockMethodBuilderSpec.groovy | 33 +++++- .../MockMvcSpockMethodBuilderSpec.groovy | 63 ++++++++++- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 106 +++++++++++++++++- ...pec.groovy => WireMockStubVerifier.groovy} | 5 +- 10 files changed, 260 insertions(+), 47 deletions(-) rename accurest-core/src/test/groovy/io/codearte/accurest/dsl/{WireMockSpec.groovy => WireMockStubVerifier.groovy} (82%) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index d686bcc54e..1b2e9a9d24 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -1,5 +1,4 @@ package io.codearte.accurest.builder - import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode @@ -23,7 +22,7 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { bb.addLine('def request = given()') bb.indent() request.headers?.collect { Header header -> - bb.addLine(".header('${header.name}', '${header.serverValue}')") + bb.addLine(".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')") } if (request.body) { bb.addLine(".body('$bodyAsString')") @@ -67,9 +66,9 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { protected String buildUrl(Request request) { if (request.url) - return request.url.serverValue; + return getTestSideValue(request.url.serverValue) if (request.urlPath) - return buildUrlFromUrlPath(request.urlPath) + return getTestSideValue(buildUrlFromUrlPath(request.urlPath)) throw new IllegalStateException("URL is not set!") } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index dbd0663ac9..2789e52a2d 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -17,6 +17,8 @@ import static io.codearte.accurest.util.ContentUtils.* @TypeChecked abstract class SpockMethodBodyBuilder { + private static final Boolean TEST_SIDE = false + protected final Request request protected final Response response @@ -200,4 +202,7 @@ abstract class SpockMethodBodyBuilder { return contentType } + protected String getTestSideValue(Object object) { + return MapConverter.getClientOrServerSideValues(object, TEST_SIDE).toString() + } } 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 index c69e5539fa..c485285281 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy @@ -6,6 +6,8 @@ import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.Headers import io.codearte.accurest.util.ContentType +import io.codearte.accurest.util.ContentUtils +import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern @@ -15,6 +17,12 @@ import static io.codearte.accurest.util.MapConverter.transformValues @TypeChecked abstract class BaseWireMockStubStrategy { + private static final Boolean STUB_SIDE = true + + protected getStubSideValue(Object object) { + return MapConverter.getClientOrServerSideValues(object, STUB_SIDE) + } + private static Closure transform = { it instanceof DslProperty ? transformValues(it.clientValue, transform) : it } @@ -58,7 +66,7 @@ abstract class BaseWireMockStubStrategy { } public String parseBody(Map map, ContentType contentType) { - def transformedMap = transformValues(map, transform) + def transformedMap = MapConverter.getClientOrServerSideValues(map, true) return parseBody(toJson(transformedMap), contentType) } @@ -82,4 +90,14 @@ abstract class BaseWireMockStubStrategy { return new JsonBuilder(value).toString() } + protected ContentType tryToGetContentType(Object body, Headers headers) { + ContentType contentType = ContentUtils.recognizeContentTypeFromHeader(headers) + if (contentType == ContentType.UNKNOWN) { + if (!body) { + return ContentType.UNKNOWN + } + return ContentUtils.getClientContentType(body) + } + return contentType + } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index c87a1cebac..cf69737c95 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -51,7 +51,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { if (!request.body) { return } - ContentType contentType = tryToGetContentType() + ContentType contentType = tryToGetContentType(request.body.clientValue, request.headers) if (contentType == ContentType.JSON) { JsonPaths values = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValues(getMatchingStrategyFromBody(request.body)?.clientValue) if (values.empty) { @@ -70,17 +70,6 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { } } - private ContentType tryToGetContentType() { - ContentType contentType = recognizeContentTypeFromHeader(request.headers) - if (contentType == ContentType.UNKNOWN) { - if (!request.body.clientValue) { - return ContentType.UNKNOWN - } - return ContentUtils.getClientContentType(request.body.clientValue) - } - return contentType - } - private void appendHeaders(RequestPattern requestPattern) { if(!request.headers) { return @@ -93,12 +82,12 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { private void appendUrl(RequestPattern requestPattern) { Object urlPath = request?.urlPath?.clientValue if (urlPath) { - requestPattern.setUrlPath(urlPath.toString()) + requestPattern.setUrlPath(getStubSideValue(urlPath.toString()).toString()) } if(!request.url) { return } - Object url = request?.url?.clientValue + Object url = getUrlIfGstring(request?.url?.clientValue) if(url instanceof Pattern) { requestPattern.setUrlPattern(url.pattern()) } else { @@ -106,6 +95,17 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { } } + private Object getUrlIfGstring(Object clientSide) { + if (clientSide instanceof GString) { + if (clientSide.values.any { getStubSideValue(it) instanceof Pattern }) { + return Pattern.compile(getStubSideValue(clientSide).toString()) + } else { + return getStubSideValue(clientSide).toString() + } + } + return clientSide + } + private void appendQueryParameters(RequestPattern requestPattern) { QueryParameters queryParameters = request?.urlPath?.queryParameters ?: request?.url?.queryParameters queryParameters?.parameters?.each { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 6a749346a7..32affecef2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -1,7 +1,6 @@ package io.codearte.accurest.util import groovy.json.JsonSlurper -import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.ExecutionProperty import java.util.regex.Pattern @@ -29,7 +28,7 @@ class JsonToJsonPathsConverter { return new JsonPaths() } JsonPaths pathsAndValues = [] as Set - Object convertedJson = getClientOrServerSideValues(json, clientSide) + Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide) traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value -> if (value instanceof ExecutionProperty) { return @@ -40,25 +39,6 @@ class JsonToJsonPathsConverter { return pathsAndValues } - private static Object getClientOrServerSideValues(json, boolean clientSide) { - return MapConverter.transformValues(json) { - if (it instanceof DslProperty) { - DslProperty dslProperty = ((DslProperty) it) - return clientSide ? - getClientOrServerSideValues(dslProperty.clientValue, clientSide) : getClientOrServerSideValues(dslProperty.serverValue, clientSide) - } else if (it instanceof GString) { - return ContentUtils.extractValue(it , null, { - if (it instanceof DslProperty) { - return clientSide ? - getClientOrServerSideValues((it as DslProperty).clientValue, clientSide) : getClientOrServerSideValues((it as DslProperty).serverValue, clientSide) - } - return it - }) - } - return it - } - } - protected static def traverseRecursively(Class parentType, String key, def value, Closure closure) { if (value instanceof String && value) { try { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy index 14568e7584..ca0717ba68 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy @@ -43,4 +43,22 @@ class MapConverter { } } + static Object getClientOrServerSideValues(json, boolean clientSide) { + return transformValues(json) { + if (it instanceof DslProperty) { + DslProperty dslProperty = ((DslProperty) it) + return clientSide ? + getClientOrServerSideValues(dslProperty.clientValue, clientSide) : getClientOrServerSideValues(dslProperty.serverValue, clientSide) + } else if (it instanceof GString) { + return ContentUtils.extractValue(it , null, { + if (it instanceof DslProperty) { + return clientSide ? + getClientOrServerSideValues((it as DslProperty).clientValue, clientSide) : getClientOrServerSideValues((it as DslProperty).serverValue, clientSide) + } + return it + }) + } + return it + } + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index 8bd272b7ac..f2ae54c6cf 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -1,10 +1,12 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.WireMockStubStrategy +import io.codearte.accurest.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Specification -class JaxRsClientSpockMethodBuilderSpec extends Specification { +class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMockStubVerifier { def "should generate assertions for simple response body"() { given: @@ -28,6 +30,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#79") @@ -57,6 +61,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#82") @@ -80,6 +86,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains("entity('{\"items\":[\"HOP\"]}', 'application/json')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#88") @@ -103,6 +111,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains("entity('property1=VAL1', 'application/octet-stream')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for array in response body"() { @@ -130,6 +140,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for array inside response body element"() { @@ -156,6 +168,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for nested objects in response body"() { @@ -182,6 +196,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate regex assertions for map objects in response body"() { @@ -214,6 +230,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { @@ -240,6 +258,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should ignore 'Accept' header and use 'request' method"() { @@ -262,6 +282,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains("request('text/plain')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should ignore 'Content-Type' header and use 'entity' method"() { @@ -288,7 +310,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("entity('', 'text/plain')") blockBuilder.toString().contains("header('Timer', '123')") !blockBuilder.toString().contains("header('Content-Type'") - + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate a call with an url path and query parameters"() { @@ -337,6 +360,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { spockTest.contains("queryParam('email', 'bob@email.com'") spockTest.contains('$[?(@.property2 == \'b\')]') spockTest.contains('$[?(@.property1 == \'a\')]') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate test for empty body"() { @@ -358,6 +383,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { def spockTest = blockBuilder.toString() then: spockTest.contains("entity('', 'application/octet-stream')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate test for String in response body"() { @@ -380,6 +407,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification { then: spockTest.contains('def responseBody = (response.body.asString())') spockTest.contains('responseBody == "test"') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 5d25d94874..a56df6014b 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -1,13 +1,15 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.WireMockStubStrategy +import io.codearte.accurest.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Specification /** * @author Jakub Kubrynski */ -class MockMvcSpockMethodBuilderSpec extends Specification { +class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStubVerifier { def "should generate assertions for simple response body"() { given: @@ -31,6 +33,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#79") @@ -60,6 +64,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#82") @@ -83,6 +89,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains(".body('{\"items\":[\"HOP\"]}')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue("#88") @@ -106,6 +114,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { builder.appendTo(blockBuilder) then: blockBuilder.toString().contains(".body('property1=VAL1')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for array in response body"() { @@ -133,6 +143,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for array inside response body element"() { @@ -159,6 +171,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate assertions for nested objects in response body"() { @@ -185,6 +199,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate regex assertions for map objects in response body"() { @@ -217,6 +233,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { @@ -243,6 +261,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate a call with an url path and query parameters"() { @@ -284,6 +304,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') spockTest.contains('$[?(@.property2 == \'b\')]') spockTest.contains('$[?(@.property1 == \'a\')]') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate test for empty body"() { @@ -305,6 +327,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { def spockTest = blockBuilder.toString() then: spockTest.contains(".body('')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should generate test for String in response body"() { @@ -327,6 +351,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: spockTest.contains('def responseBody = (response.body.asString())') spockTest.contains('responseBody == "test"') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue('113') @@ -360,6 +386,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { def spockTest = blockBuilder.toString() then: spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @Issue('115') @@ -393,6 +421,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification { def spockTest = blockBuilder.toString() then: spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should work with more complex stuff and jsonpaths"() { @@ -428,6 +458,37 @@ class MockMvcSpockMethodBuilderSpec extends Specification { then: spockTest.contains('''$.errors[*][?(@.property == 'bank_account_number')]''') spockTest.contains('''$.errors[*][?(@.message == 'incorrect_format')]''') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + + def "should work properly with GString url"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + + request { + method 'PUT' + url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" + headers { + header 'Content-Type': 'application/json' + } + body( + first_name: 'Josef', + ) + } + response { + status 422 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('''/partners/11/agents/11/customers/09665703Z''') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } def "should resolve properties in GString with regular expression"() { 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 548f309b00..2188321374 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 @@ -4,8 +4,9 @@ import groovy.json.JsonBuilder import groovy.json.JsonSlurper import io.codearte.accurest.util.AssertionUtil import spock.lang.Issue +import spock.lang.Specification -class WireMockGroovyDslSpec extends WireMockSpec { +class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifier { def 'should convert groovy dsl stub to wireMock stub for the client side'() { given: @@ -1189,6 +1190,109 @@ class WireMockGroovyDslSpec extends WireMockSpec { stubMappingIsValidWireMockStub(wireMockStub) } + def 'should generate stub properly resolving GString with regular expression'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(client(regex(email())), server('not.existing@user.com')), + callback_url: $(client(regex(hostname())), server('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: 4, + message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + ) + } + } + when: + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "url" : "/users/password", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]" + }, { + "matchesJsonPath" : "$[?(@.email =~ /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 404, + "body" : "{\\"code\\":4,\\"message\\":\\"User not found by email = [not.existing@user.com]\\"}", + "headers" : { + "Content-Type" : "application/json" + } + }, + "priority" : 1 + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + } + + def 'should generate stub properly resolving GString with regular expression in url'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + + request { + method 'PUT' + url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" + headers { + header 'Content-Type': 'application/json' + } + body( + first_name: 'Josef', + ) + } + response { + status 422 + } + } + when: + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "urlPattern" : "/partners/^[0-9]*$/agents/11/customers/09665703Z", + "method" : "PUT", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.first_name == 'Josef')]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 422 + } + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + } + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy similarity index 82% rename from accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy index aad0fa879e..a970434c05 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy @@ -1,17 +1,16 @@ package io.codearte.accurest.dsl - import com.github.tomakehurst.wiremock.stubbing.StubMapping -import spock.lang.Specification import java.util.regex.Pattern -abstract class WireMockSpec extends Specification { +trait WireMockStubVerifier { void stubMappingIsValidWireMockStub(String mappingDefinition) { StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) stubMapping.request.bodyPatterns.findAll { it.matches }.every { Pattern.compile(it.matches) } + assert !mappingDefinition.contains('DslProperty') } } From 5181608ee9ac0613c0e66116175b2b19cddbb2f8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 3 Sep 2015 17:20:48 +0200 Subject: [PATCH 212/719] Added tabs instead of spaces --- .../DslToWireMockClientConverterSpec.groovy | 118 ++--- .../io/codearte/accurest/TestGenerator.groovy | 8 +- .../JaxRsClientSpockMethodBodyBuilder.groovy | 136 +++--- .../MockMvcSpockMethodBodyBuilder.groovy | 114 ++--- .../dsl/internal/ExecutionProperty.groovy | 16 +- .../accurest/dsl/internal/Header.groovy | 18 +- .../dsl/internal/QueryParameter.groovy | 32 +- .../dsl/internal/QueryParameters.groovy | 16 +- .../accurest/dsl/internal/UrlPath.groovy | 12 +- .../codearte/accurest/util/ContentType.groovy | 14 +- .../accurest/util/ValidateUtils.groovy | 48 +- .../JaxRsClientSpockMethodBuilderSpec.groovy | 20 +- .../MockMvcSpockMethodBuilderSpec.groovy | 20 +- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 434 +++++++++--------- .../accurest/dsl/WireMockStubVerifier.groovy | 14 +- .../dsl/internal/ExecutionPropertySpec.groovy | 22 +- .../test/resources/dsl/basic/sampleDsl.groovy | 20 +- .../functionalTest/bootSimple/build.gradle | 80 ++-- .../pairId/colleratePlacesFromTweet.groovy | 28 +- .../pairId/moreComplexVersion.groovy | 36 +- .../ofg/twitter/place/PairIdController.groovy | 34 +- .../groovy/com/ofg/twitter/place/Tweet.java | 14 +- .../ofg/twitter/places/AcceptanceSpec.groovy | 18 +- .../ofg/twitter/places/BaseMockMvcSpec.groovy | 12 +- .../shouldMarkClientAsFraud.groovy | 48 +- .../shouldMarkClientAsNotFraud.groovy | 52 +-- .../frauddetection/FraudRestApplication.java | 8 +- .../shouldMarkClientAsFraud.json | 42 +- .../shouldMarkClientAsNotFraud.json | 42 +- .../shouldMarkClientAsFraud.groovy | 48 +- .../shouldMarkClientAsNotFraud.groovy | 52 +-- .../shouldMarkClientAsFraud.json | 42 +- .../shouldMarkClientAsNotFraud.json | 42 +- build.gradle | 3 +- 34 files changed, 831 insertions(+), 832 deletions(-) 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 22fc850efe..61c6b7c29b 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,15 +10,15 @@ class DslToWireMockClientConverterSpec extends Specification { def converter = new DslToWireMockClientConverter() and: String dslBody = """ - io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - url \$(client(~/\\/[0-9]{2}/), server('/12')) - } - response { - status 200 - } - } + io.codearte.accurest.dsl.GroovyDsl.make { + request { + method('PUT') + url \$(client(~/\\/[0-9]{2}/), server('/12')) + } + response { + status 200 + } + } """ when: String json = converter.convertContent(dslBody) @@ -34,7 +34,7 @@ class DslToWireMockClientConverterSpec extends Specification { def converter = new DslToWireMockClientConverter() and: String dslBody = """ - io.codearte.accurest.dsl.GroovyDsl.make { + io.codearte.accurest.dsl.GroovyDsl.make { request { method 'PUT' url '/api/12' @@ -84,57 +84,57 @@ class DslToWireMockClientConverterSpec extends Specification { JSONAssert.assertEquals(''' { "request" : { - "url" : "/api/12", - "method" : "PUT", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" - }, { - "matchesJsonPath" : "$[*].place[?(@.country == 'United States')]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" - }, { - "matchesJsonPath" : "$[*].place[?(@.name == 'Washington')]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box[?(@.type == 'Polygon')]" - }, { - "matchesJsonPath" : "$[*][?(@.id_str == '492967299297845248')]" - }, { - "matchesJsonPath" : "$[*].place[?(@.country_code == 'US')]" - }, { - "matchesJsonPath" : "$[*][?(@.id == 492967299297845248)]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" - }, { - "matchesJsonPath" : "$[*].place[?(@.id == '01fbe706f872cb32')]" - }, { - "matchesJsonPath" : "$[*].place[?(@.url == 'http://api.twitter.com/1/geo/id/01fbe706f872cb32.json')]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" - }, { - "matchesJsonPath" : "$[*][?(@.text == 'Gonna see you at Warsaw')]" - }, { - "matchesJsonPath" : "$[*].place[?(@.place_type == 'city')]" - }, { - "matchesJsonPath" : "$[*][?(@.created_at == 'Sat Jul 26 09:38:57 +0000 2014')]" - }, { - "matchesJsonPath" : "$[*].place[?(@.full_name == 'Washington, DC')]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/vnd.com.ofg.twitter-places-analyzer.v1+json" - } - } + "url" : "/api/12", + "method" : "PUT", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.country == 'United States')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.name == 'Washington')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box[?(@.type == 'Polygon')]" + }, { + "matchesJsonPath" : "$[*][?(@.id_str == '492967299297845248')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.country_code == 'US')]" + }, { + "matchesJsonPath" : "$[*][?(@.id == 492967299297845248)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.id == '01fbe706f872cb32')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.url == 'http://api.twitter.com/1/geo/id/01fbe706f872cb32.json')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" + }, { + "matchesJsonPath" : "$[*][?(@.text == 'Gonna see you at Warsaw')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.place_type == 'city')]" + }, { + "matchesJsonPath" : "$[*][?(@.created_at == 'Sat Jul 26 09:38:57 +0000 2014')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.full_name == 'Washington, DC')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/vnd.com.ofg.twitter-places-analyzer.v1+json" + } + } }, "response" : { - "status" : 200 + "status" : 200 } } ''', json, false) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index fb612cebd1..63e2047217 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -68,8 +68,8 @@ class TestGenerator { } } } - - private String normalizePath(String path) { - return FilenameUtils.separatorsToUnix(path) - } + + private String normalizePath(String path) { + return FilenameUtils.separatorsToUnix(path) + } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy index d3e07d7942..91ba58e4f0 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy @@ -10,86 +10,86 @@ import io.codearte.accurest.dsl.internal.QueryParameter @TypeChecked class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { - JaxRsClientSpockMethodBodyBuilder(GroovyDsl stubDefinition) { - super(stubDefinition) - } + JaxRsClientSpockMethodBodyBuilder(GroovyDsl stubDefinition) { + super(stubDefinition) + } - @Override - protected void givenBlock(BlockBuilder bb) { - } + @Override + protected void givenBlock(BlockBuilder bb) { + } - @Override - protected void when(BlockBuilder bb) { - bb.addLine("def response = webTarget") - bb.indent() + @Override + protected void when(BlockBuilder bb) { + bb.addLine("def response = webTarget") + bb.indent() - appendUrlPathAndQueryParameters(bb) - appendRequestWithRequiredResponseContentType(bb) - appendHeaders(bb) - appendMethodAndBody(bb) + appendUrlPathAndQueryParameters(bb) + appendRequestWithRequiredResponseContentType(bb) + appendHeaders(bb) + appendMethodAndBody(bb) - bb.unindent() + bb.unindent() - bb.addEmptyLine() - bb.addLine("String responseAsString = response.readEntity(String)") - } + bb.addEmptyLine() + bb.addLine("String responseAsString = response.readEntity(String)") + } - protected void appendRequestWithRequiredResponseContentType(BlockBuilder bb) { - String acceptHeader = getHeader("Accept") - if (acceptHeader) { - bb.addLine(".request('$acceptHeader')") - } else { - bb.addLine(".request()") - } - } + protected void appendRequestWithRequiredResponseContentType(BlockBuilder bb) { + String acceptHeader = getHeader("Accept") + if (acceptHeader) { + bb.addLine(".request('$acceptHeader')") + } else { + bb.addLine(".request()") + } + } - protected void appendUrlPathAndQueryParameters(BlockBuilder bb) { - if (request.url) { - bb.addLine(".path('$request.url.serverValue')") - } else if (request.urlPath) { - bb.addLine(".path('$request.urlPath.serverValue')") - request.urlPath.queryParameters?.parameters.findAll(this.&allowedQueryParameter).each { QueryParameter param -> - bb.addLine(".queryParam('$param.name', '${resolveParamValue(param).toString()}')") - } - } - } + protected void appendUrlPathAndQueryParameters(BlockBuilder bb) { + if (request.url) { + bb.addLine(".path('$request.url.serverValue')") + } else if (request.urlPath) { + bb.addLine(".path('$request.urlPath.serverValue')") + request.urlPath.queryParameters?.parameters.findAll(this.&allowedQueryParameter).each { QueryParameter param -> + bb.addLine(".queryParam('$param.name', '${resolveParamValue(param).toString()}')") + } + } + } - protected void appendMethodAndBody(BlockBuilder bb) { - String method = request.method.serverValue.toString().toLowerCase() - if (request.body) { - String contentType = getHeader('Content-Type') ?: getRequestContentType().mimeType - bb.addLine(".method('$method', entity('$bodyAsString', '$contentType'))") - } else { - bb.addLine(".method('$method')") - } - } + protected void appendMethodAndBody(BlockBuilder bb) { + String method = request.method.serverValue.toString().toLowerCase() + if (request.body) { + String contentType = getHeader('Content-Type') ?: getRequestContentType().mimeType + bb.addLine(".method('$method', entity('$bodyAsString', '$contentType'))") + } else { + bb.addLine(".method('$method')") + } + } - protected appendHeaders(BlockBuilder bb) { - request.headers?.collect { Header header -> - if (header.name == 'Content-Type' || header.name == 'Accept') return // Particular headers are set via 'request' / 'entity' methods - bb.addLine(".header('${header.name}', '${header.serverValue}')") - } - } + protected appendHeaders(BlockBuilder bb) { + request.headers?.collect { Header header -> + if (header.name == 'Content-Type' || header.name == 'Accept') return // Particular headers are set via 'request' / 'entity' methods + bb.addLine(".header('${header.name}', '${header.serverValue}')") + } + } - protected String getHeader(String name) { - return request.headers?.entries.find { it.name == name }?.serverValue - } + protected String getHeader(String name) { + return request.headers?.entries.find { it.name == name }?.serverValue + } - @Override - protected void validateResponseCodeBlock(BlockBuilder bb) { - bb.addLine("response.status == $response.status.serverValue") - } + @Override + protected void validateResponseCodeBlock(BlockBuilder bb) { + bb.addLine("response.status == $response.status.serverValue") + } - @Override - protected void validateResponseHeadersBlock(BlockBuilder bb) { - response.headers?.collect { Header header -> - bb.addLine("response.getHeaderString('$header.name') == '$header.serverValue'") - } - } + @Override + protected void validateResponseHeadersBlock(BlockBuilder bb) { + response.headers?.collect { Header header -> + bb.addLine("response.getHeaderString('$header.name') == '$header.serverValue'") + } + } - @Override - protected String getResponseAsString() { - return 'responseAsString' - } + @Override + protected String getResponseAsString() { + return 'responseAsString' + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index 1b2e9a9d24..fed69dc27b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -14,73 +14,73 @@ import java.util.regex.Pattern @TypeChecked class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { - MockMvcSpockMethodBodyBuilder(GroovyDsl stubDefinition) { - super(stubDefinition) - } + MockMvcSpockMethodBodyBuilder(GroovyDsl stubDefinition) { + super(stubDefinition) + } - protected void given(BlockBuilder bb) { - bb.addLine('def request = given()') - bb.indent() - request.headers?.collect { Header header -> - bb.addLine(".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')") - } - if (request.body) { - bb.addLine(".body('$bodyAsString')") - } - bb.unindent() - } + protected void given(BlockBuilder bb) { + bb.addLine('def request = given()') + bb.indent() + request.headers?.collect { Header header -> + bb.addLine(".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')") + } + if (request.body) { + bb.addLine(".body('$bodyAsString')") + } + bb.unindent() + } - protected void when(BlockBuilder bb) { - bb.addLine('def response = given().spec(request)') - bb.indent() + protected void when(BlockBuilder bb) { + bb.addLine('def response = given().spec(request)') + bb.indent() - String url = buildUrl(request) - String method = request.method.serverValue.toString().toLowerCase() + String url = buildUrl(request) + String method = request.method.serverValue.toString().toLowerCase() - bb.addLine(/.${method}("$url")/) - bb.unindent() - } + bb.addLine(/.${method}("$url")/) + bb.unindent() + } - protected void validateResponseCodeBlock(BlockBuilder bb) { - bb.addLine("response.statusCode == $response.status.serverValue") - } + protected void validateResponseCodeBlock(BlockBuilder bb) { + bb.addLine("response.statusCode == $response.status.serverValue") + } - protected void validateResponseHeadersBlock(BlockBuilder bb) { - response.headers?.collect { Header header -> - bb.addLine("response.header('$header.name') ${convertHeaderComparison(header.serverValue)}") - } - } + protected void validateResponseHeadersBlock(BlockBuilder bb) { + response.headers?.collect { Header header -> + bb.addLine("response.header('$header.name') ${convertHeaderComparison(header.serverValue)}") + } + } - private String convertHeaderComparison(Object headerValue) { - return " == '$headerValue'" - } + private String convertHeaderComparison(Object headerValue) { + return " == '$headerValue'" + } - private String convertHeaderComparison(Pattern headerValue) { - return "==~ java.util.regex.Pattern.compile('$headerValue')" - } + private String convertHeaderComparison(Pattern headerValue) { + return "==~ java.util.regex.Pattern.compile('$headerValue')" + } - @Override - protected String getResponseAsString() { - return 'response.body.asString()' - } + @Override + protected String getResponseAsString() { + return 'response.body.asString()' + } - protected String buildUrl(Request request) { - if (request.url) - return getTestSideValue(request.url.serverValue) - if (request.urlPath) - return getTestSideValue(buildUrlFromUrlPath(request.urlPath)) - throw new IllegalStateException("URL is not set!") - } + protected String buildUrl(Request request) { + if (request.url) + return getTestSideValue(request.url.serverValue) + if (request.urlPath) + return getTestSideValue(buildUrlFromUrlPath(request.urlPath)) + throw new IllegalStateException("URL is not set!") + } - @TypeChecked(TypeCheckingMode.SKIP) - protected String buildUrlFromUrlPath(UrlPath urlPath) { - String params = urlPath.queryParameters.parameters - .findAll(this.&allowedQueryParameter) - .inject([] as List) { List result, QueryParameter param -> - result << "${param.name}=${resolveParamValue(param).toString()}" - } - .join('&') - return "$urlPath.serverValue?$params" - } + @TypeChecked(TypeCheckingMode.SKIP) + protected String buildUrlFromUrlPath(UrlPath urlPath) { + String params = urlPath.queryParameters.parameters + .findAll(this.&allowedQueryParameter) + .inject([] as List) { List result, QueryParameter param -> + result << "${param.name}=${resolveParamValue(param).toString()}" + } + .join('&') + return "$urlPath.serverValue?$params" + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy index ccc7037575..866afdc18c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy @@ -5,15 +5,15 @@ import groovy.transform.CompileStatic @CompileStatic class ExecutionProperty { - private static final String PLACEHOLDER_VALUE = '\\$it' + private static final String PLACEHOLDER_VALUE = '\\$it' - final String executionCommand + final String executionCommand - ExecutionProperty(String executionCommand) { - this.executionCommand = executionCommand - } + ExecutionProperty(String executionCommand) { + this.executionCommand = executionCommand + } - String insertValue(String valueToInsert) { - return executionCommand.replaceAll(PLACEHOLDER_VALUE, valueToInsert) - } + String insertValue(String valueToInsert) { + return executionCommand.replaceAll(PLACEHOLDER_VALUE, valueToInsert) + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy index a7eefa180a..b72037cd03 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy @@ -8,16 +8,16 @@ import groovy.transform.ToString @CompileStatic class Header extends DslProperty { - String name + String name - Header(String name, DslProperty dslProperty) { - super(dslProperty.clientValue, dslProperty.serverValue) - this.name = name - } + Header(String name, DslProperty dslProperty) { + super(dslProperty.clientValue, dslProperty.serverValue) + this.name = name + } - Header(String name, Object value) { - super(value) - this.name = name - } + Header(String name, Object value) { + super(value) + this.name = name + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy index 042da081f2..153fa6f297 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy @@ -11,24 +11,24 @@ import static io.codearte.accurest.util.ValidateUtils.validateServerValueIsAvail @CompileStatic class QueryParameter extends DslProperty { - String name + String name - QueryParameter(String name, DslProperty dslProperty) { - super(dslProperty.clientValue, dslProperty.serverValue) - validateServerValueIsAvailable(dslProperty.serverValue, "Query parameter '$name'") - this.name = name - } + QueryParameter(String name, DslProperty dslProperty) { + super(dslProperty.clientValue, dslProperty.serverValue) + validateServerValueIsAvailable(dslProperty.serverValue, "Query parameter '$name'") + this.name = name + } - QueryParameter(String name, MatchingStrategy matchingStrategy) { - super(matchingStrategy) - validateServerValueIsAvailable(matchingStrategy, "Query parameter '$name'") - this.name = name - } + QueryParameter(String name, MatchingStrategy matchingStrategy) { + super(matchingStrategy) + validateServerValueIsAvailable(matchingStrategy, "Query parameter '$name'") + this.name = name + } - QueryParameter(String name, Object value) { - super(value) - validateServerValueIsAvailable(value, "Query parameter '$name'") - this.name = name - } + QueryParameter(String name, Object value) { + super(value) + validateServerValueIsAvailable(value, "Query parameter '$name'") + this.name = name + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy index 0a5d6233f2..b4cc1d74c4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy @@ -9,15 +9,15 @@ import groovy.transform.TypeChecked @TypeChecked class QueryParameters { - List parameters = [] + List parameters = [] - void parameter(Map singleParameter) { - Map.Entry first = singleParameter.entrySet().first() - parameters << new QueryParameter(first?.key, first?.value) - } + void parameter(Map singleParameter) { + Map.Entry first = singleParameter.entrySet().first() + parameters << new QueryParameter(first?.key, first?.value) + } - void parameter(String parameterName, Object parameterValue) { - parameters << new QueryParameter(parameterName, parameterValue) - } + void parameter(String parameterName, Object parameterValue) { + parameters << new QueryParameter(parameterName, parameterValue) + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy index ee1d3eed98..68d9bc0f7d 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy @@ -9,12 +9,12 @@ import groovy.transform.ToString; @CompileStatic class UrlPath extends Url { - UrlPath(String path) { - super(path) - } + UrlPath(String path) { + super(path) + } - UrlPath(DslProperty path) { - super(path) - } + UrlPath(DslProperty path) { + super(path) + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy index 7b9e402985..a9243058af 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy @@ -2,14 +2,14 @@ package io.codearte.accurest.util enum ContentType { - JSON("application/json"), - XML("application/xml"), - UNKNOWN("application/octet-stream") + JSON("application/json"), + XML("application/xml"), + UNKNOWN("application/octet-stream") - final String mimeType + final String mimeType - ContentType(String mimeType) { - this.mimeType = mimeType - } + ContentType(String mimeType) { + this.mimeType = mimeType + } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy index 7cb6e0f0ef..46e9706cfe 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy @@ -12,35 +12,35 @@ import static io.codearte.accurest.dsl.internal.MatchingStrategy.Type.EQUAL_TO @TypeChecked class ValidateUtils { - static Object validateServerValueIsAvailable(Object value) { - validateServerValueIsAvailable(value, "Server value") - return value - } + static Object validateServerValueIsAvailable(Object value) { + validateServerValueIsAvailable(value, "Server value") + return value + } - static Object validateServerValueIsAvailable(Object value, String msg) { - validateServerValue(value, msg) - return value - } + static Object validateServerValueIsAvailable(Object value, String msg) { + validateServerValue(value, msg) + return value + } - static void validateServerValue(Pattern pattern, String msg) { - throw new IllegalStateException("$msg can't be a pattern for the server side") - } + static void validateServerValue(Pattern pattern, String msg) { + throw new IllegalStateException("$msg can't be a pattern for the server side") + } - static List ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE = [EQUAL_TO, ABSENT] + static List ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE = [EQUAL_TO, ABSENT] - static void validateServerValue(MatchingStrategy matchingStrategy, String msg) { - if (!ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE.contains(matchingStrategy.type)) { - throw new IllegalStateException("$msg can't be of a matching type: $matchingStrategy.type for the server side") - } - validateServerValue(matchingStrategy.serverValue, msg) - } + static void validateServerValue(MatchingStrategy matchingStrategy, String msg) { + if (!ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE.contains(matchingStrategy.type)) { + throw new IllegalStateException("$msg can't be of a matching type: $matchingStrategy.type for the server side") + } + validateServerValue(matchingStrategy.serverValue, msg) + } - static void validateServerValue(DslProperty value, String msg) { - validateServerValue(value.serverValue, msg) - } + static void validateServerValue(DslProperty value, String msg) { + validateServerValue(value.serverValue, msg) + } - static void validateServerValue(Object value, String msg) { - // OK - } + static void validateServerValue(Object value, String msg) { + // OK + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index f2ae54c6cf..aa5a26cb5d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -18,8 +18,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc response { status 200 body """{ - "property1": "a", - "property2": "b" + "property1": "a", + "property2": "b" }""" } } @@ -126,10 +126,10 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc status 200 body """[ { - "property1": "a" + "property1": "a" }, { - "property2": "b" + "property2": "b" }]""" } } @@ -154,10 +154,10 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc response { status 200 body """{ - "property1": [ - { "property2": "test1"}, - { "property3": "test2"} - ] + "property1": [ + { "property2": "test1"}, + { "property3": "test2"} + ] }""" } } @@ -183,8 +183,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc status 200 body '''\ { - "property1": "a", - "property2": {"property3": "b"} + "property1": "a", + "property2": {"property3": "b"} } ''' } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index a56df6014b..e3e4120e0d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -21,8 +21,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu response { status 200 body """{ - "property1": "a", - "property2": "b" + "property1": "a", + "property2": "b" }""" } } @@ -129,10 +129,10 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu status 200 body """[ { - "property1": "a" + "property1": "a" }, { - "property2": "b" + "property2": "b" }]""" } } @@ -157,10 +157,10 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu response { status 200 body """{ - "property1": [ - { "property2": "test1"}, - { "property3": "test2"} - ] + "property1": [ + { "property2": "test1"}, + { "property3": "test2"} + ] }""" } } @@ -186,8 +186,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu status 200 body '''\ { - "property1": "a", - "property2": {"property3": "b"} + "property1": "a", + "property2": {"property3": "b"} } ''' } 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 2188321374..053d33217b 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 @@ -85,17 +85,17 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual(''' { "request" : { - "url" : "/ingredients", - "method" : "GET", - "headers" : { - "Content-Type" : { - "equalTo" : "application/vnd.pl.devoxx.aggregatr.v1+json" - } - } + "url" : "/ingredients", + "method" : "GET", + "headers" : { + "Content-Type" : { + "equalTo" : "application/vnd.pl.devoxx.aggregatr.v1+json" + } + } }, "response" : { - "status" : 200, - "body" : "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}" + "status" : 200, + "body" : "{\\"ingredients\\":[{\\"type\\":\\"MALT\\",\\"quantity\\":100},{\\"type\\":\\"WATER\\",\\"quantity\\":200},{\\"type\\":\\"HOP\\",\\"quantity\\":300},{\\"type\\":\\"YIEST\\",\\"quantity\\":400}]}" } } ''', wireMockStub) @@ -132,24 +132,24 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie then: AssertionUtil.assertThatJsonsAreEqual(''' { - "request": { - "method": "POST", - "headers": { - "Content-Type": { - "equalTo": "application/x-www-form-urlencoded" - } - }, - "url": "/ws/payments", - "bodyPatterns": [ - { - "matches": "paymentType=INCOMING&transferType=BANK&amount=[0-9]{3}\\\\.[0-9]{2}&bookingDate=[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])" - } - ] - }, - "response": { - "status": 204, - "body": "{\\"paymentId\\":\\"4\\",\\"foundExistingPayment\\":false}" - } + "request": { + "method": "POST", + "headers": { + "Content-Type": { + "equalTo": "application/x-www-form-urlencoded" + } + }, + "url": "/ws/payments", + "bodyPatterns": [ + { + "matches": "paymentType=INCOMING&transferType=BANK&amount=[0-9]{3}\\\\.[0-9]{2}&bookingDate=[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])" + } + ] + }, + "response": { + "status": 204, + "body": "{\\"paymentId\\":\\"4\\",\\"foundExistingPayment\\":false}" + } } ''', wireMockStub) and: @@ -166,13 +166,13 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie response { status 200 body("""\ - { - "id": "${value(client('123'), server('321'))}", - "surname": "${value(client('Kowalsky'), server('Lewandowski'))}", - "name": "Jan", - "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" - } - """ + { + "id": "${value(client('123'), server('321'))}", + "surname": "${value(client('Kowalsky'), server('Lewandowski'))}", + "name": "Jan", + "created" : "${$(client('2014-02-02 12:23:43'), server('2999-09-09 01:23:45'))}" + } + """ ) headers { header 'Content-Type': 'text/plain' @@ -185,15 +185,15 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { - "urlPattern" : "/[0-9]{2}", - "method" : "GET" + "urlPattern" : "/[0-9]{2}", + "method" : "GET" }, "response" : { - "status" : 200, - "body" : "{\\"created\\":\\"2014-02-02 12:23:43\\",\\"id\\":\\"123\\",\\"name\\":\\"Jan\\",\\"surname\\":\\"Kowalsky\\"}", - "headers" : { - "Content-Type" : "text/plain" - } + "status" : 200, + "body" : "{\\"created\\":\\"2014-02-02 12:23:43\\",\\"id\\":\\"123\\",\\"name\\":\\"Jan\\",\\"surname\\":\\"Kowalsky\\"}", + "headers" : { + "Content-Type" : "text/plain" + } } } '''), wireMockStub) @@ -216,10 +216,10 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie response { status 200 body("""\ - { - "name": "Jan" - } - """ + { + "name": "Jan" + } + """ ) headers { header 'Content-Type': 'text/plain' @@ -232,18 +232,18 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual(''' { "request" : { - "urlPattern" : "/[0-9]{2}", - "method" : "GET", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.name == 'Jan')]" - } ] + "urlPattern" : "/[0-9]{2}", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.name == 'Jan')]" + } ] }, "response" : { - "status" : 200, - "body" : "{\\"name\\":\\"Jan\\"}", - "headers" : { - "Content-Type" : "text/plain" - } + "status" : 200, + "body" : "{\\"name\\":\\"Jan\\"}", + "headers" : { + "Content-Type" : "text/plain" + } } } ''', wireMockStub) @@ -280,20 +280,20 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { - "urlPattern" : "/[0-9]{2}", - "method" : "GET", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.created == '2014-02-02 12:23:43')]" - }, { - "matchesJsonPath" : "$[?(@.surname == 'Kowalsky')]" - }, { - "matchesJsonPath" : "$[?(@.name == 'Jan')]" - }, { - "matchesJsonPath" : "$[?(@.id == '123')]" - } ] + "urlPattern" : "/[0-9]{2}", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.created == '2014-02-02 12:23:43')]" + }, { + "matchesJsonPath" : "$[?(@.surname == 'Kowalsky')]" + }, { + "matchesJsonPath" : "$[?(@.name == 'Jan')]" + }, { + "matchesJsonPath" : "$[?(@.id == '123')]" + } ] }, "response" : { - "status" : 200 + "status" : 200 } } '''), wireMockStub) @@ -326,19 +326,19 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { - "url" : "/users", - "method" : "GET", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.name == 'Jan')]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "customtype/json" - } - } + "url" : "/users", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.name == 'Jan')]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "customtype/json" + } + } }, "response" : { - "status" : 200 + "status" : 200 } } '''), json) @@ -548,10 +548,10 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie response { status 200 body("""\ - { - "name": "Jan" - } - """ + { + "name": "Jan" + } + """ ) headers { header 'Content-Type': 'text/plain' @@ -564,18 +564,18 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { - "urlPattern" : "/[0-9]{2}", - "method" : "GET", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.personalId =~ /^[0-9]{11}$/)]" - } ] + "urlPattern" : "/[0-9]{2}", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.personalId =~ /^[0-9]{11}$/)]" + } ] }, "response" : { - "status" : 200, - "body" : "{\\"name\\":\\"Jan\\"}", - "headers" : { - "Content-Type" : "text/plain" - } + "status" : 200, + "body" : "{\\"name\\":\\"Jan\\"}", + "headers" : { + "Content-Type" : "text/plain" + } } } '''), wireMockStub) @@ -590,11 +590,11 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie method 'PUT' url '/fraudcheck' body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') @@ -619,25 +619,25 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { - "url" : "/fraudcheck", - "method" : "PUT", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.loanAmount == 123.123)]" - }, { - "matchesJsonPath" : "$[?(@.clientPesel =~ /[0-9]{10}/)]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/vnd.fraud.v1+json" - } - } + "url" : "/fraudcheck", + "method" : "PUT", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.loanAmount == 123.123)]" + }, { + "matchesJsonPath" : "$[?(@.clientPesel =~ /[0-9]{10}/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/vnd.fraud.v1+json" + } + } }, "response" : { - "status" : 200, - "body" : "{\\"fraudCheckStatus\\":\\"OK\\",\\"rejectionReason\\":null}", - "headers" : { - "Content-Type" : "application/vnd.fraud.v1+json" - } + "status" : 200, + "body" : "{\\"fraudCheckStatus\\":\\"OK\\",\\"rejectionReason\\":null}", + "headers" : { + "Content-Type" : "application/vnd.fraud.v1+json" + } } } '''), wireMockStub) @@ -686,20 +686,20 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie "equalTo": "email" }, "sort": { - "matches": "^[0-9]{10}$" - }, - "search": { - "doesNotMatch": "^/[0-9]{2}$" - }, - "age": { - "doesNotMatch": "^\\\\w*$" - }, - "name": { - "matches": "Denis.*" - }, - "credit": { - "absent": true - } + "matches": "^[0-9]{10}$" + }, + "search": { + "doesNotMatch": "^/[0-9]{2}$" + }, + "age": { + "doesNotMatch": "^\\\\w*$" + }, + "name": { + "matches": "Denis.*" + }, + "credit": { + "absent": true + } } }, "response": { @@ -967,32 +967,32 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { - "urlPattern" : "/[0-9]{2}", - "method" : "GET", - "bodyPatterns" : [ { - "matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]" - }, { - "matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]" - }, { - "matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]" - }, { - "matchesJsonPath" : "$[?(@.lastName =~ /.*/)]" - }, { - "matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]" - }, { - "matchesJsonPath" : "$[?(@.birthDate =~ /[0-9]{4}-[0-9]{2}-[0-9]{2}/)]" - }, { - "matchesJsonPath" : "$[?(@.personalId =~ /[0-9]{11}/)]" - }, { - "matchesJsonPath" : "$[?(@.firstName =~ /.*/)]" - } ] + "urlPattern" : "/[0-9]{2}", + "method" : "GET", + "bodyPatterns" : [ { + "matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]" + }, { + "matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]" + }, { + "matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]" + }, { + "matchesJsonPath" : "$[?(@.lastName =~ /.*/)]" + }, { + "matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]" + }, { + "matchesJsonPath" : "$[?(@.birthDate =~ /[0-9]{4}-[0-9]{2}-[0-9]{2}/)]" + }, { + "matchesJsonPath" : "$[?(@.personalId =~ /[0-9]{11}/)]" + }, { + "matchesJsonPath" : "$[?(@.firstName =~ /.*/)]" + } ] }, "response" : { - "status" : 200, - "body" : "{\\"name\\":\\"Jan\\"}", - "headers" : { - "Content-Type" : "text/plain" - } + "status" : 200, + "body" : "{\\"name\\":\\"Jan\\"}", + "headers" : { + "Content-Type" : "text/plain" + } } } '''), wireMockStub) @@ -1031,28 +1031,28 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { - "url" : "/reissue-payment-order", - "method" : "POST", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.loanNumber == '999997001')]" - }, { - "matchesJsonPath" : "$[?(@.username =~ /.*/)]" - }, { - "matchesJsonPath" : "$[?(@.amount =~ /[0-9.]+/)]" - }, { - "matchesJsonPath" : "$[?(@.cardId == 1)]" - }, { - "matchesJsonPath" : "$[?(@.currency == 'DKK')]" - }, { - "matchesJsonPath" : "$[?(@.applicationName =~ /.*/)]" - } ] + "url" : "/reissue-payment-order", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.loanNumber == '999997001')]" + }, { + "matchesJsonPath" : "$[?(@.username =~ /.*/)]" + }, { + "matchesJsonPath" : "$[?(@.amount =~ /[0-9.]+/)]" + }, { + "matchesJsonPath" : "$[?(@.cardId == 1)]" + }, { + "matchesJsonPath" : "$[?(@.currency == 'DKK')]" + }, { + "matchesJsonPath" : "$[?(@.applicationName =~ /.*/)]" + } ] }, "response" : { - "status" : 200, - "body" : "{\\"status\\":\\"OK\\"}", - "headers" : { - "Content-Type" : "application/json" - } + "status" : 200, + "body" : "{\\"status\\":\\"OK\\"}", + "headers" : { + "Content-Type" : "application/json" + } } } '''), json) @@ -1075,50 +1075,50 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie then: AssertionUtil.assertThatJsonsAreEqual((''' { - "request": { - "method": "POST", - "url": "test", - "bodyPatterns": [ - { - "equalTo": "" - } - ] - }, - "response": { - "status": 406 - } + "request": { + "method": "POST", + "url": "test", + "bodyPatterns": [ + { + "equalTo": "" + } + ] + }, + "response": { + "status": 406 + } } '''), json) } - def "should generate stub with priority"() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - priority 9 - request { - method('POST') - url("test") - } - response { - status 406 - } - } - when: - def json = toWireMockClientJsonStub(groovyDsl) - then: + def "should generate stub with priority"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + priority 9 + request { + method('POST') + url("test") + } + response { + status 406 + } + } + when: + def json = toWireMockClientJsonStub(groovyDsl) + then: AssertionUtil.assertThatJsonsAreEqual((''' - { - "priority": 9, - "request": { - "method": "POST", - "url": "test" - }, - "response": { - "status": 406 - } - } - '''), json) - } + { + "priority": 9, + "request": { + "method": "POST", + "url": "test" + }, + "response": { + "status": 406 + } + } + '''), json) + } @Issue("#127") def 'should use "test" as an alias for "server"'() { @@ -1140,16 +1140,16 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie AssertionUtil.assertThatJsonsAreEqual((''' { "request" : { - "method" : "POST", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.property == 'value')]" - } ] + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.property == 'value')]" + } ] }, "response" : { - "status" : 200 + "status" : 200 } } - '''), wireMockStub) + '''), wireMockStub) and: stubMappingIsValidWireMockStub(wireMockStub) } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy index a970434c05..241380062f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy @@ -5,12 +5,12 @@ import java.util.regex.Pattern trait WireMockStubVerifier { - void stubMappingIsValidWireMockStub(String mappingDefinition) { - StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) - stubMapping.request.bodyPatterns.findAll { it.matches }.every { - Pattern.compile(it.matches) - } - assert !mappingDefinition.contains('DslProperty') - } + void stubMappingIsValidWireMockStub(String mappingDefinition) { + StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) + stubMapping.request.bodyPatterns.findAll { it.matches }.every { + Pattern.compile(it.matches) + } + assert !mappingDefinition.contains('DslProperty') + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy index d8660a8433..35e0fbe83a 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy @@ -4,16 +4,16 @@ import spock.lang.Specification class ExecutionPropertySpec extends Specification { - def 'should insert passed value in place of $it placeholder'() { - given: - String commandToExecute = 'commandToExecute($it)' - ExecutionProperty executionProperty = new ExecutionProperty(commandToExecute) - and: - String valueToInsert = 'someObject.itsValue' - when: - String commandWithInsertedValue = executionProperty.insertValue(valueToInsert) - then: - 'commandToExecute(someObject.itsValue)' == commandWithInsertedValue - } + def 'should insert passed value in place of $it placeholder'() { + given: + String commandToExecute = 'commandToExecute($it)' + ExecutionProperty executionProperty = new ExecutionProperty(commandToExecute) + and: + String valueToInsert = 'someObject.itsValue' + when: + String commandWithInsertedValue = executionProperty.insertValue(valueToInsert) + then: + 'commandToExecute(someObject.itsValue)' == commandWithInsertedValue + } } diff --git a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy index 95d19e6b87..4405a9920e 100644 --- a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy +++ b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy @@ -5,23 +5,23 @@ io.codearte.accurest.dsl.GroovyDsl.make { header 'Content-Type': 'application/json' } body("""\ - { - "name": "Jan", - "id": "${value(client('abc'), server('def'))}", - } - """ + { + "name": "Jan", + "id": "${value(client('abc'), server('def'))}", + } + """ ) url $(client('/[0-9]{2}'), server('/12')) } response { status 200 body("""\ - { - "name": "Jan", - "id": "${value(client('123'), server('321'))}", + { + "name": "Jan", + "id": "${value(client('123'), server('321'))}", "surname": "${value(client('Kowalsky'), server('$checkIfSurnameValid($value)'))}" - } - """ + } + """ ) headers { header 'Content-Type': 'text/plain' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 48929c705b..52e2415869 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -1,71 +1,71 @@ buildscript { - repositories { - mavenCentral() - } + repositories { + mavenCentral() + } } apply plugin: 'groovy' apply plugin: 'accurest' ext { - contractsDir = file("${project.rootDir}/repository/mappings/com/ofg/twitter-places-analyzer") - wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'repository/mappings/') + contractsDir = file("${project.rootDir}/repository/mappings/com/ofg/twitter-places-analyzer") + wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") + wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'repository/mappings/') } 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}") - } - } - } - } + 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() + mavenCentral() } dependencies { - compile "org.springframework:spring-web:$springVersion" - compile "org.springframework:spring-context-support:$springVersion" - compile "org.codehaus.groovy:groovy-all:2.4.1" - compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' - compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonMapper" - compile "org.codehaus.jackson:jackson-core-asl:$jacksonMapper" - compile 'com.jayway.jsonpath:json-path-assert:1.2.0' + compile "org.springframework:spring-web:$springVersion" + compile "org.springframework:spring-context-support:$springVersion" + compile "org.codehaus.groovy:groovy-all:2.4.1" + compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' + compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonMapper" + compile "org.codehaus.jackson:jackson-core-asl:$jacksonMapper" + compile 'com.jayway.jsonpath:json-path-assert:1.2.0' - testCompile('com.github.tomakehurst:wiremock:1.53') { - exclude group: 'org.mortbay.jetty', module: 'servlet-api' - } - testCompile "org.spockframework:spock-spring:0.7-groovy-2.0" - testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" - testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" - testCompile "javax.servlet:javax.servlet-api:3.0.1" //provided - testCompile "ch.qos.logback:logback-classic:1.1.2" + testCompile('com.github.tomakehurst:wiremock:1.53') { + exclude group: 'org.mortbay.jetty', module: 'servlet-api' + } + testCompile "org.spockframework:spock-spring:0.7-groovy-2.0" + testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" + testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" + testCompile "javax.servlet:javax.servlet-api:3.0.1" //provided + testCompile "ch.qos.logback:logback-classic:1.1.2" } accurest { - baseClassForTests = 'com.ofg.twitter.places.BaseMockMvcSpec' - basePackageForTests = 'accurest' - contractsDslDir = contractsDir -// generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/") - stubsOutputDir = wireMockStubsOutputDir + baseClassForTests = 'com.ofg.twitter.places.BaseMockMvcSpec' + basePackageForTests = 'accurest' + contractsDslDir = contractsDir +// generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/") + stubsOutputDir = wireMockStubsOutputDir } //TODO: Put it into the plugin task createWireMockStubsOutputDir << { - wireMockStubsOutputDir.mkdirs() + wireMockStubsOutputDir.mkdirs() } generateWireMockClientStubs.dependsOn { createWireMockStubsOutputDir } generateAccurest.dependsOn generateWireMockClientStubs wrapper { - gradleVersion '2.2.1' + gradleVersion '2.2.1' } 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 6fe36c6a89..826f71b791 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,18 +1,18 @@ io.codearte.accurest.dsl.GroovyDsl.make { priority 2 - request { - method 'PUT' - url '/api/12' - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] + request { + method 'PUT' + url '/api/12' + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] ''' - } - response { - status 200 - } + } + response { + status 200 + } } \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy index fdeb658215..943fbc23b9 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy @@ -1,21 +1,21 @@ io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] + request { + method 'PUT' + url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] ''' - } - response { - body ( - path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), - correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) - ) - status 200 - } + } + response { + body ( + path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), + correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) + ) + status 200 + } } \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy index 4f49f1ed3b..3a7671793c 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy @@ -16,21 +16,21 @@ import static org.springframework.web.bind.annotation.RequestMethod.PUT @TypeChecked class PairIdController { - @RequestMapping( - value = '{pairId}', - method = PUT, - consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { - log.info("Inside PairIdController, doing very important logic") - if (tweets?.text != ["Gonna see you at Warsaw"]) { - throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") - } - return """ - { - "path" : "/api/$pairId", - "correlationId" : 123456 - } - """ - } + @RequestMapping( + value = '{pairId}', + method = PUT, + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { + log.info("Inside PairIdController, doing very important logic") + if (tweets?.text != ["Gonna see you at Warsaw"]) { + throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") + } + return """ + { + "path" : "/api/$pairId", + "correlationId" : 123456 + } + """ + } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java index 96fdd52262..5d1e9c2835 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java @@ -1,13 +1,13 @@ package com.ofg.twitter.place; public class Tweet { - private String text; + private String text; - public String getText() { - return text; - } + public String getText() { + return text; + } - public void setText(String text) { - this.text = text; - } + public void setText(String text) { + this.text = text; + } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy index 6a3bef53d7..458e275daf 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy @@ -11,13 +11,13 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. class AcceptanceSpec extends Specification { - def "should have controller up and running"() { - given: - MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PairIdController()).build() - expect: - mockMvc.perform(put("/api/${1}"). - contentType(MediaType.APPLICATION_JSON). - content("""[{"text":"Gonna see you at Warsaw"}]""")). - andExpect(status().isOk()) - } + def "should have controller up and running"() { + given: + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PairIdController()).build() + expect: + mockMvc.perform(put("/api/${1}"). + contentType(MediaType.APPLICATION_JSON). + content("""[{"text":"Gonna see you at Warsaw"}]""")). + andExpect(status().isOk()) + } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy index cade991eaa..6b8e7e630e 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy @@ -6,11 +6,11 @@ import spock.lang.Specification abstract class BaseMockMvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new PairIdController()) - } + def setup() { + RestAssuredMockMvc.standaloneSetup(new PairIdController()) + } - void isProperCorrelationId(Integer correlationId) { - assert correlationId == 123456 - } + void isProperCorrelationId(Integer correlationId) { + assert correlationId == 123456 + } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy index a47dff32e4..44b1c08604 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy @@ -1,27 +1,27 @@ io.codearte.accurest.dsl.GroovyDsl.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":99999} - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status 200 - body( """{ - "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", - "rejectionReason": "Amount too high" + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" }""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy index fa8cd88ade..7bc64d0dac 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy @@ -1,28 +1,28 @@ io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java index ce70aa1050..83e15edc59 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java @@ -5,9 +5,9 @@ import java.util.Set; public class FraudRestApplication extends javax.ws.rs.core.Application { - @Override - public Set> getClasses() { - return Collections.>singleton(FraudDetectionController.class); - } + @Override + public Set> getClasses() { + return Collections.>singleton(FraudDetectionController.class); + } } \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json index 90383f2ce1..7229872299 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json @@ -1,23 +1,23 @@ { - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "\\s*\\{\\s*\"clientPesel\"\\s*:\\s*\"?[0-9]{10}\"?\\s*,\\s*\"loanAmount\"\\s*:\\s*\"?99999\"?\\s*\\}\\s*" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" - } + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "\\s*\\{\\s*\"clientPesel\"\\s*:\\s*\"?[0-9]{10}\"?\\s*,\\s*\"loanAmount\"\\s*:\\s*\"?99999\"?\\s*\\}\\s*" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" + } } \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json index 2f47855910..5a251171c7 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json @@ -1,23 +1,23 @@ { - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "\\s*\\{\\s*\"clientPesel\"\\s*:\\s*\"?[0-9]{10}\"?\\s*,\\s*\"loanAmount\"\\s*:\\s*\"?123.123\"?\\s*\\}\\s*" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" - } + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "\\s*\\{\\s*\"clientPesel\"\\s*:\\s*\"?[0-9]{10}\"?\\s*,\\s*\"loanAmount\"\\s*:\\s*\"?123.123\"?\\s*\\}\\s*" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" + } } \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy index a47dff32e4..44b1c08604 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy @@ -1,27 +1,27 @@ io.codearte.accurest.dsl.GroovyDsl.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":99999} - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status 200 - body( """{ - "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", - "rejectionReason": "Amount too high" + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" }""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy index fa8cd88ade..7bc64d0dac 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy @@ -1,28 +1,28 @@ io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json index 610b4ae1b1..157726ca2e 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json @@ -1,23 +1,23 @@ { - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"99999\"}" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" - } + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"99999\"}" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" + } } \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json index af5792092c..afa27159d9 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json @@ -1,23 +1,23 @@ { - "request": { - "method": "PUT", - "headers": { - "Content-Type": { - "equalTo": "application/vnd.fraud.v1+json" - } - }, - "url": "/fraudcheck", - "bodyPatterns": [ - { - "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"123.123\"}" - } - ] - }, - "response": { - "status": 200, - "headers": { - "Content-Type": "application/vnd.fraud.v1+json" - }, - "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" - } + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"123.123\"}" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" + } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index c1739aa58c..7f78c6ad8a 100644 --- a/build.gradle +++ b/build.gradle @@ -24,8 +24,7 @@ scmVersion { } allprojects { - //project.version = scmVersion.version - project.version = '0.9.1-SNAPSHOT' + project.version = scmVersion.version } apply plugin: 'io.codearte.nexus-staging' From 9d0976e23de9635811669d1b9f16f6dda94971e1 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 3 Sep 2015 17:38:09 +0200 Subject: [PATCH 213/719] Release version: 0.9.1 [ci skip] From b4689efd363a531635afd1b12254f8671ba622c8 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 9 Sep 2015 20:01:26 +0200 Subject: [PATCH 214/719] Migration to wiremock 2.0 --- .../dsl/WireMockResponseStubStrategy.groovy | 38 ++++++++++--------- build.gradle | 4 +- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy index 5af5898257..3f63e6433c 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy @@ -1,4 +1,6 @@ package io.codearte.accurest.dsl + +import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder import com.github.tomakehurst.wiremock.http.HttpHeader import com.github.tomakehurst.wiremock.http.HttpHeaders import com.github.tomakehurst.wiremock.http.ResponseDefinition @@ -25,30 +27,30 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { @PackageScope ResponseDefinition buildClientResponseContent() { - ResponseDefinition responseDefinition = new ResponseDefinition() - responseDefinition.setStatus(response.status.clientValue as Integer) - appendHeaders(responseDefinition) - appendBody(responseDefinition) - return responseDefinition + ResponseDefinitionBuilder builder = new ResponseDefinitionBuilder() + .withStatus(response.status.clientValue as Integer) + appendHeaders(builder) + appendBody(builder) + return builder.build() } - private void appendHeaders(ResponseDefinition responseDefinition) { - if(!(response.headers)) { - return + private void appendHeaders(ResponseDefinitionBuilder builder) { + if (response.headers) { + builder.withHeaders(new HttpHeaders(response.headers.entries?.collect { + new HttpHeader(it.name, it.clientValue.toString()) + })) } - responseDefinition.setHeaders(new HttpHeaders(response.headers.entries?.collect { new HttpHeader(it.name, it.clientValue.toString()) })) } - private void appendBody(ResponseDefinition responseDefinition) { - if (!response.body) { - return + private void appendBody(ResponseDefinitionBuilder builder) { + if (response.body) { + Object body = response.body.clientValue + ContentType contentType = recognizeContentTypeFromHeader(response.headers) + if (contentType == ContentType.UNKNOWN) { + contentType = recognizeContentTypeFromContent(body) + } + builder.withBody(parseBody(body, contentType)) } - Object body = response.body.clientValue - ContentType contentType = recognizeContentTypeFromHeader(response.headers) - if (contentType == ContentType.UNKNOWN) { - contentType = recognizeContentTypeFromContent(body) - } - responseDefinition.setBody(parseBody(body, contentType)) } diff --git a/build.gradle b/build.gradle index 7f78c6ad8a..efabdd6b36 100644 --- a/build.gradle +++ b/build.gradle @@ -71,7 +71,7 @@ project(':accurest-core') { compile 'com.google.code.gson:gson:2.3.1' compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' compile 'asm:asm:3.3.1' - compile 'com.blogspot.toomuchcoding:wiremock:0.0.1' + compile 'com.github.tomakehurst:wiremock:2.0.2-beta' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') @@ -93,7 +93,7 @@ project(':accurest-converters') { compile 'org.apache.commons:commons-lang3:[3.0,)' compile 'commons-io:commons-io:[2.0,)' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger - testCompile 'com.blogspot.toomuchcoding:wiremock:0.0.1' + testCompile 'com.github.tomakehurst:wiremock:2.0.2-beta' testCompile 'org.hamcrest:hamcrest-all:1.3' } } From 06bf6a39099210f79b98aa92b10b187a3c5a4665 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 10 Sep 2015 12:31:23 +0200 Subject: [PATCH 215/719] gradle plugin update to wiremock 2 --- .../accurest/plugin/AccurestGradlePlugin.groovy | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) 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 e7c9feafde..8a6b55ac23 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 @@ -30,20 +30,7 @@ class AccurestGradlePlugin implements Plugin { createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() - project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:wiremock:0.0.1") - project.repositories { jcenter() } - project.configurations { - all { - resolutionStrategy { - eachDependency { DependencyResolveDetails details -> - if (details.requested.group == 'com.github.tomakehurst' && details.requested.name == "wiremock") { - details.useTarget("com.blogspot.toomuchcoding:wiremock:0.0.1") - } - } - } - } - } - + project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.2-beta") project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) From fe1aa54be5d400f2ef324b9f8e3f1766289f46bf Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 17 Sep 2015 13:38:01 +0200 Subject: [PATCH 216/719] Fixes #146 - NPE on queryParametrs --- .../builder/MockMvcSpockMethodBodyBuilder.groovy | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index fed69dc27b..af84103be2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.builder + import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode @@ -74,12 +75,15 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { @TypeChecked(TypeCheckingMode.SKIP) protected String buildUrlFromUrlPath(UrlPath urlPath) { - String params = urlPath.queryParameters.parameters - .findAll(this.&allowedQueryParameter) - .inject([] as List) { List result, QueryParameter param -> - result << "${param.name}=${resolveParamValue(param).toString()}" - } - .join('&') + String params = "" + if (urlPath.queryParameters) { + params = urlPath.queryParameters.parameters + .findAll(this.&allowedQueryParameter) + .inject([] as List) { List result, QueryParameter param -> + result << "${param.name}=${resolveParamValue(param).toString()}" + } + .join('&') + } return "$urlPath.serverValue?$params" } From 1ba1e4f5ea8b4ae06e12b79f3c97f6b3ba63809e Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Thu, 17 Sep 2015 13:38:44 +0200 Subject: [PATCH 217/719] Release version: 0.9.2 [ci skip] From f3d097fb276e11b458418f09f463e6289a6683d8 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Sep 2015 20:04:51 +0200 Subject: [PATCH 218/719] wiremock update --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index efabdd6b36..fda2787073 100644 --- a/build.gradle +++ b/build.gradle @@ -71,7 +71,7 @@ project(':accurest-core') { compile 'com.google.code.gson:gson:2.3.1' compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' compile 'asm:asm:3.3.1' - compile 'com.github.tomakehurst:wiremock:2.0.2-beta' + compile 'com.github.tomakehurst:wiremock:2.0.4-beta' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') From ac3b87bd06d25d4959f67712d53197c72199aed1 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 30 Sep 2015 10:36:33 +0200 Subject: [PATCH 219/719] configuration update --- .../accurest/plugin/AccurestGradlePlugin.groovy | 2 +- .../functionalTest/bootSimple/build.gradle | 12 +++++------- .../functionalTest/bootSimple/gradle.properties | 2 +- .../sampleJerseyProject/build.gradle | 15 ++++++--------- .../functionalTest/sampleProject/build.gradle | 8 +++----- build.gradle | 9 ++++----- gradle.properties | 4 +++- 7 files changed, 23 insertions(+), 29 deletions(-) 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 8a6b55ac23..efd3f76e92 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 @@ -30,7 +30,7 @@ class AccurestGradlePlugin implements Plugin { createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() - project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.2-beta") + project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.4-beta") project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 52e2415869..e392e694c3 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -34,19 +34,17 @@ repositories { dependencies { compile "org.springframework:spring-web:$springVersion" compile "org.springframework:spring-context-support:$springVersion" - compile "org.codehaus.groovy:groovy-all:2.4.1" + compile "org.codehaus.groovy:groovy-all:2.4.4" compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonMapper" compile "org.codehaus.jackson:jackson-core-asl:$jacksonMapper" - compile 'com.jayway.jsonpath:json-path-assert:1.2.0' + compile 'com.jayway.jsonpath:json-path-assert:2.0.0' - testCompile('com.github.tomakehurst:wiremock:1.53') { - exclude group: 'org.mortbay.jetty', module: 'servlet-api' - } - testCompile "org.spockframework:spock-spring:0.7-groovy-2.0" + testCompile "com.github.tomakehurst:wiremock:2.0.4-beta" + testCompile "org.spockframework:spock-spring:1.0-groovy-2.4" testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" - testCompile "javax.servlet:javax.servlet-api:3.0.1" //provided + testCompile 'javax.servlet:javax.servlet-api:3.1.0' testCompile "ch.qos.logback:logback-classic:1.1.2" } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties index 71fcc0538e..c484dce638 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties @@ -1,4 +1,4 @@ groupId=com.ofg jacksonMapper=1.9.13 restAssuredVersion=2.4.0 -springVersion=4.1.4.RELEASE \ No newline at end of file +springVersion=4.1.7.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index 0ae605c532..ee3e5ea354 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -9,8 +9,8 @@ buildscript { } ext { - spockVersion = '0.7-groovy-2.0' restAssuredVersion = '2.4.0' + spockVersion = '1.0-groovy-2.4' accurestStubsBaseDirectory = 'src/test/resources/stubs' } @@ -18,19 +18,16 @@ ext { subprojects { apply plugin: 'groovy' - repositories { mavenCentral() mavenLocal() } dependencies { - testCompile "org.codehaus.groovy:groovy-all:2.3.7" + testCompile 'org.codehaus.groovy:groovy-all:2.4.4' testCompile "org.spockframework:spock-core:$spockVersion" - testCompile("junit:junit:4.12") - testCompile('com.github.tomakehurst:wiremock:1.52') { - exclude group: 'org.mortbay.jetty', module: 'servlet-api' - } + testCompile 'junit:junit:4.12' + testCompile 'com.github.tomakehurst:wiremock:2.0.4-beta' } } @@ -59,10 +56,10 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') dependencies { compile "javax.ws.rs:javax.ws.rs-api:2.0.1" compile 'org.glassfish.jersey.containers:jersey-container-jetty-http:2.15' - compile('org.springframework.boot:spring-boot-starter-jersey:1.2.5.RELEASE') { + compile('org.springframework.boot:spring-boot-starter-jersey:1.2.6.RELEASE') { exclude module: "spring-boot-starter-tomcat" } - compile 'org.springframework.boot:spring-boot-starter-jetty:1.2.5.RELEASE' + compile 'org.springframework.boot:spring-boot-starter-jetty:1.2.6.RELEASE' testRuntime "org.spockframework:spock-spring:$spockVersion" diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index aa4e17339c..7a88858a51 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -9,8 +9,8 @@ buildscript { } ext { - spockVersion = '0.7-groovy-2.0' restAssuredVersion = '2.4.0' + spockVersion = '1.0-groovy-2.4' accurestStubsBaseDirectory = 'src/test/resources/stubs' } @@ -24,12 +24,10 @@ subprojects { } dependencies { - testCompile "org.codehaus.groovy:groovy-all:2.3.7" + testCompile "org.codehaus.groovy:groovy-all:2.4.4" testCompile "org.spockframework:spock-core:$spockVersion" testCompile("junit:junit:4.12") - testCompile('com.github.tomakehurst:wiremock:1.52') { - exclude group: 'org.mortbay.jetty', module: 'servlet-api' - } + testCompile "com.github.tomakehurst:wiremock:2.0.4-beta" } } diff --git a/build.gradle b/build.gradle index fda2787073..42d265f044 100644 --- a/build.gradle +++ b/build.gradle @@ -18,8 +18,8 @@ scmVersion { releaseCommitMessage { version, position -> "Release version: ${version}\n\n[ci skip]" } hooks { pre "fileUpdate", [file : "README.md", - pattern : { v, p -> /'io\.codearte\.accurest:accurest-gradle-plugin:.*'/ }, - replacement: { v, p -> "'io.codearte.accurest:accurest-gradle-plugin:$v'" }] + pattern : { v, p -> /'io\.codearte\.accurest:accurest-gradle-plugin:.*'/ }, + replacement: { v, p -> "'io.codearte.accurest:accurest-gradle-plugin:$v'" }] } } @@ -71,7 +71,7 @@ project(':accurest-core') { compile 'com.google.code.gson:gson:2.3.1' compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' compile 'asm:asm:3.3.1' - compile 'com.github.tomakehurst:wiremock:2.0.4-beta' + compile "com.github.tomakehurst:wiremock:$wiremockVersion" testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') @@ -93,7 +93,7 @@ project(':accurest-converters') { compile 'org.apache.commons:commons-lang3:[3.0,)' compile 'commons-io:commons-io:[2.0,)' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger - testCompile 'com.github.tomakehurst:wiremock:2.0.2-beta' + testCompile "com.github.tomakehurst:wiremock:$wiremockVersion" testCompile 'org.hamcrest:hamcrest-all:1.3' } } @@ -103,7 +103,6 @@ project(':accurest-gradle-plugin') { compile project(':accurest-core') compile project(':accurest-converters') compile gradleApi() - testCompile('com.netflix.nebula:nebula-test:2.2.1') { exclude(group: 'org.spockframework') } diff --git a/gradle.properties b/gradle.properties index fe3cdf2fd8..8ab8e8bf7b 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,4 @@ nexusUsername = -nexusPassword = \ No newline at end of file +nexusPassword = + +wiremockVersion = 2.0.4-beta From bf43ca3c7429b7ed652e9557bc4964037422bad3 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 2 Oct 2015 17:07:00 +0200 Subject: [PATCH 220/719] Ugly fix for escaping bug #143 #126 --- .../accurest/util/ContentUtils.groovy | 4 +-- .../MockMvcSpockMethodBuilderSpec.groovy | 36 ++++++++++++++++--- 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index a7e66f9ec3..8aae7a832f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -131,7 +131,7 @@ class ContentUtils { bodyAsValue.values.collect { transformJSONStringValue(it, valueProvider) } as String[], bodyAsValue.strings.clone() as String[] ) - def parsedJson = new JsonSlurper().parseText(transformedString.toString()) + def parsedJson = new JsonSlurper().parseText(transformedString.toString().replace('\\', '\\\\')) return convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) } @@ -166,7 +166,7 @@ class ContentUtils { MapConverter.transformValues(parsedJson, { Object value -> if (value instanceof String) { String string = (String) value - Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string) + Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string.trim()) if (matcher.matches()) { List val = matcher[0] as List String pattern = val[1] diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index e3e4120e0d..9267dfb559 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -238,6 +238,35 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } def "should generate regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + headers { + header('Content-Type': 'application/json') + + } + + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") + blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + + @Issue(["#126", "#143"]) + def "should generate escaped regex assertions for string objects in response body"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -246,12 +275,10 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } response { status 200 - body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + body("""{"property":" ${value(client('123'), server(regex('\\d+')))}"}""") headers { header('Content-Type': 'application/json') - } - } } MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) @@ -259,8 +286,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("\$[?(@.property =~ /\\d+/)]") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } From f21e4512ab470a3ce4b855178930125442e948c1 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 2 Oct 2015 20:33:14 +0200 Subject: [PATCH 221/719] size assertion causes invalid specs for some arrays #151 --- .../main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy index 0e0f928f22..be1638027e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy @@ -17,8 +17,7 @@ class JsonPathEntry { if (optionalSuffix) { return ["!${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).empty"] } else if (traversesOverCollections()) { - return ["${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).size() == 1", - "${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).get(0) ${operator()} ${potentiallyWrappedWithQuotesValue()}"] + return ["${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).get(0) ${operator()} ${potentiallyWrappedWithQuotesValue()}"] } return ["${parsedJsonVariable}.read('''${jsonPath}''') ${operator()} ${potentiallyWrappedWithQuotesValue()}"] } From 450b785501a4dc2b3ea562f03a0f2a98b8c95329 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 2 Oct 2015 21:28:32 +0200 Subject: [PATCH 222/719] Release version: 0.9.3 [ci skip] From 390c1ae2fbf10c25c91c04a1325b2ab193b46eea Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 3 Oct 2015 10:49:43 +0200 Subject: [PATCH 223/719] [#72] Make execution method work with GString, closes #71, closes #72, closes #101 --- .../accurest/util/ContentUtils.groovy | 31 ++++++++++--- .../MockMvcSpockMethodBuilderSpec.groovy | 43 +++++++++++++++++++ 2 files changed, 67 insertions(+), 7 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 8aae7a832f..87b940c663 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -5,6 +5,7 @@ import groovy.json.JsonSlurper import groovy.transform.TypeChecked import groovy.util.logging.Slf4j import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Headers import io.codearte.accurest.dsl.internal.MatchingStrategy import org.codehaus.groovy.runtime.GStringImpl @@ -24,7 +25,9 @@ class ContentUtils { } private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') + private static final Pattern TEMPORARY_EXECUTION_PATTERN_HOLDER = Pattern.compile('EXECUTION>>(.*)<<') private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' + private static final String JSON_VALUE_PATTERN_FOR_EXECUTION = '"EXECUTION>>%s<<"' /** * Due to the fact that we allow users to have a body with GString and different values inside @@ -154,6 +157,10 @@ class ContentUtils { return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern()) } + private static String transformJSONStringValue(ExecutionProperty property, Closure valueProvider) { + return String.format(JSON_VALUE_PATTERN_FOR_EXECUTION, property.executionCommand) + } + private static String transformXMLStringValue(Object obj, Closure valueProvider) { return escapeXml11(obj.toString()) } @@ -166,18 +173,28 @@ class ContentUtils { MapConverter.transformValues(parsedJson, { Object value -> if (value instanceof String) { String string = (String) value - Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string.trim()) - if (matcher.matches()) { - List val = matcher[0] as List - String pattern = val[1] - return Pattern.compile(pattern) - } - return value + return returnParsedObject(string) } return value }) } + static Object returnParsedObject(String string) { + Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string.trim()) + if (matcher.matches()) { + List val = matcher[0] as List + String pattern = val[1] + return Pattern.compile(pattern) + } + Matcher executionMatcher = TEMPORARY_EXECUTION_PATTERN_HOLDER.matcher(string.trim()) + if (executionMatcher.matches()) { + List val = executionMatcher[0] as List + String pattern = val[1] + return new ExecutionProperty(pattern) + } + return string + } + public static ContentType recognizeContentTypeFromHeader(Headers headers) { String content = headers?.entries.find { it.name == "Content-Type" } ?.clientValue?.toString() if (content?.endsWith("json")) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 9267dfb559..7c16b662d7 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -551,4 +551,47 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: spockTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''') } + + @Issue('72') + def "should make the execute method work"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "OK", + "rejectionReason": ${value(client(null), server(execute('assertThatRejectionReasonIsNull($it)')))} +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + + } + + } + + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''') + } } From e84ceedd582a9a0b2e6370a586c1f4c2ac7f2365 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 5 Oct 2015 21:21:02 +0200 Subject: [PATCH 224/719] [#72] Added explanation to matchers --- .../accurest/util/ContentUtils.groovy | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 87b940c663..c18a918c8b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -179,6 +179,30 @@ class ContentUtils { }) } + /** + *

+ * If you wonder why there is val[1] without null-check then take a look at this: + *

+ *

+ * Example: + *

+ *

+ * Our string equals: {@code EXECUTION>>assertThatRejectionReasonIsNull($it)<<} + * The matcher matches this group with the pattern {@code EXECUTION>>(.*)<<} + *

+ *

+ * So {@code executionMatcher[0]} returns 2 elements: + *

    + *
  • index0: EXECUTION>>assertThatRejectionReasonIsNull($it)<<
  • + *
  • index1: assertThatRejectionReasonIsNull($it)<<
  • + *
+ *

+ *

+ * Thus one can safely write {@code executionMatcher[0][1]} to retrieve the matched group + *

+ * @param string to match the regexps against + * @return object converted from temporary holders + */ static Object returnParsedObject(String string) { Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string.trim()) if (matcher.matches()) { From 9550a9ff08f99cdfcd3d51d6a12c929252135b89 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 4 Oct 2015 22:16:25 +0200 Subject: [PATCH 225/719] [#42] Optional parameter --- .../accurest/dsl/internal/Common.groovy | 22 +++-- .../accurest/dsl/internal/Optional.groovy | 7 ++ .../accurest/util/ContentUtils.groovy | 13 ++- .../util/JsonToJsonPathsConverter.groovy | 2 +- .../MockMvcSpockMethodBuilderSpec.groovy | 84 +++++++++++++++++++ 5 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Optional.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 6cb78b67ba..531dbec5ce 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -16,16 +16,20 @@ class Common { @Delegate private final RegexPatterns regexPatterns = new RegexPatterns() Map convertObjectsToDslProperties(Map body) { - return body.collectEntries { + return (body.collectEntries { Map.Entry entry -> [(entry.key): toDslProperty(entry.value)] - } as Map + } as Map).findAll { + !(it.value.clientValue instanceof Optional || it.value.serverValue instanceof Optional) + } } - List convertObjectsToDslProperties(List body) { - return body.collect { + Collection convertObjectsToDslProperties(List body) { + return (body.collect { Object element -> toDslProperty(element) - } as List + } as List).findAll { + !(it instanceof Optional) + } } DslProperty toDslProperty(Object property) { @@ -53,6 +57,10 @@ class Common { return new DslProperty(client.clientValue, server.serverValue) } + DslProperty value(Object value) { + return new DslProperty(value) + } + DslProperty value(ServerDslProperty server, ClientDslProperty client) { assertThatSidesMatch(client.clientValue, server.serverValue) return new DslProperty(client.clientValue, server.serverValue) @@ -90,6 +98,10 @@ class Common { return new ServerDslProperty(serverValue) } + Optional optional() { + return new Optional() + } + void assertThatSidesMatch(Pattern pattern, String value) { assert value ==~ pattern } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Optional.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Optional.groovy new file mode 100644 index 0000000000..02e7a16323 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Optional.groovy @@ -0,0 +1,7 @@ +package io.codearte.accurest.dsl.internal + +/** + * Marker class to show that an element of message is optional + */ +class Optional { +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index c18a918c8b..c5261b43be 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -8,6 +8,7 @@ import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Headers import io.codearte.accurest.dsl.internal.MatchingStrategy +import io.codearte.accurest.dsl.internal.Optional import org.codehaus.groovy.runtime.GStringImpl import java.util.regex.Matcher @@ -24,9 +25,11 @@ class ContentUtils { it instanceof DslProperty ? it.clientValue : it } - private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('REGEXP>>(.*)<<') + private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('.*REGEXP>>(.*)<<.*') private static final Pattern TEMPORARY_EXECUTION_PATTERN_HOLDER = Pattern.compile('EXECUTION>>(.*)<<') private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' + private static final String JSON_VALUE_OPTIONAL = 'OPTIONAL>><<' + private static final Pattern OPTIONAL_PATTERN_HOLDER = Pattern.compile(JSON_VALUE_OPTIONAL) private static final String JSON_VALUE_PATTERN_FOR_EXECUTION = '"EXECUTION>>%s<<"' /** @@ -157,6 +160,10 @@ class ContentUtils { return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern()) } + private static String transformJSONStringValue(Optional optional, Closure valueProvider) { + return JSON_VALUE_OPTIONAL + } + private static String transformJSONStringValue(ExecutionProperty property, Closure valueProvider) { return String.format(JSON_VALUE_PATTERN_FOR_EXECUTION, property.executionCommand) } @@ -216,6 +223,10 @@ class ContentUtils { String pattern = val[1] return new ExecutionProperty(pattern) } + Matcher optionalMatcher = OPTIONAL_PATTERN_HOLDER.matcher(string.trim()) + if (optionalMatcher.matches()) { + return new Optional() + } return string } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 32affecef2..db8f264e30 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -30,7 +30,7 @@ class JsonToJsonPathsConverter { JsonPaths pathsAndValues = [] as Set Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide) traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value -> - if (value instanceof ExecutionProperty) { + if (value instanceof ExecutionProperty || value instanceof io.codearte.accurest.dsl.internal.Optional) { return } JsonPathEntry entry = getValueToInsert(key, value) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 7c16b662d7..2eb45c0475 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -552,6 +552,90 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu spockTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''') } + def "should omit an optional field from body resolution"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: optional(), + callback_url: $(client(regex(hostname())), server('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: optional(), + message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + ) + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + !spockTest.contains('''body('{"email":''') + !spockTest.contains('''parsedJson.read(\'\'\'$[?(@.email''') + !spockTest.contains('''REGEXP''') + !spockTest.contains('''OPTIONAL''') + !spockTest.contains('''Optional''') + } + + def "should omit an optional field from body resolution with GString"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "email" : "${value(optional())}", + "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" + } + """ + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "code" : "${value(optional())}", + "message" : "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + } + """ + ) + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + !spockTest.contains('''body('{"email":''') + !spockTest.contains('''parsedJson.read(\'\'\'$[?(@.code''') + !spockTest.contains('''REGEXP''') + !spockTest.contains('''OPTIONAL''') + !spockTest.contains('''Optional''') + } + @Issue('72') def "should make the execute method work"() { given: From bb73cdd4b0de3ee4b756c10bdad0ba4320aeb4f5 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 4 Oct 2015 22:37:49 +0200 Subject: [PATCH 226/719] [#42] Fixed wiremock stubs generation --- .../accurest/util/MapConverter.groovy | 3 + .../MockMvcSpockMethodBuilderSpec.groovy | 2 + .../accurest/dsl/WireMockGroovyDslSpec.groovy | 122 ++++++++++++++++++ 3 files changed, 127 insertions(+) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy index ca0717ba68..c4a6eed44b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.util import groovy.json.JsonSlurper import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.dsl.internal.Optional /** * @author Marcin Grzejszczak @@ -40,6 +41,8 @@ class MapConverter { return map.collectEntries { key, value -> [key, transformValues(value, closure)] + }.findAll { + !(it.value instanceof Optional) } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 2eb45c0475..f3ee4bd99a 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -552,6 +552,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu spockTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''') } + @Issue('42') def "should omit an optional field from body resolution"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -591,6 +592,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu !spockTest.contains('''Optional''') } + @Issue('42') def "should omit an optional field from body resolution with GString"() { given: GroovyDsl contractDsl = GroovyDsl.make { 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 053d33217b..cbceb49f80 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 @@ -1293,6 +1293,128 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie stubMappingIsValidWireMockStub(wireMockStub) } + @Issue('42') + def 'should generate stub without optional parameters with GString'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "email" : "${value(optional())}", + "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" + } + """ + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "code" : "${value(optional())}", + "message" : "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + } + """ + ) + } + } + when: + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "url" : "/users/password", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 404, + "body" : "{\\"message\\":\\"User not found by email = [not.existing@user.com]\\"}", + "headers" : { + "Content-Type" : "application/json" + } + }, + "priority" : 1 + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + } + + @Issue('42') + def 'should generate stub without optional parameters'() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: optional(), + callback_url: $(client(regex(hostname())), server('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: optional(), + message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + ) + } + } + when: + String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "url" : "/users/password", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 404, + "body" : "{\\"message\\":\\"User not found by email = [not.existing@user.com]\\"}", + "headers" : { + "Content-Type" : "application/json" + } + }, + "priority" : 1 + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + } + String toJsonString(value) { new JsonBuilder(value).toPrettyString() } From b0bb4cb75fdbd12de4237a12361d23aea1e3c239 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 5 Oct 2015 22:38:12 +0200 Subject: [PATCH 227/719] [#42] Modified the optional functionality --- .../accurest/dsl/internal/Common.groovy | 18 +- .../accurest/dsl/internal/Optional.groovy | 7 - .../dsl/internal/OptionalProperty.groovy | 13 ++ .../accurest/dsl/internal/Request.groovy | 5 +- .../accurest/dsl/internal/Response.groovy | 3 + .../accurest/util/ContentUtils.groovy | 28 +-- .../util/JsonToJsonPathsConverter.groovy | 14 +- .../accurest/util/MapConverter.groovy | 5 - .../MockMvcSpockMethodBuilderSpec.groovy | 119 +++++------ .../accurest/dsl/WireMockGroovyDslSpec.groovy | 190 ++++++++---------- .../accurest/dsl/WireMockStubVerifier.groovy | 2 +- 11 files changed, 190 insertions(+), 214 deletions(-) delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Optional.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OptionalProperty.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 531dbec5ce..c96ff4b2d4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -16,20 +16,16 @@ class Common { @Delegate private final RegexPatterns regexPatterns = new RegexPatterns() Map convertObjectsToDslProperties(Map body) { - return (body.collectEntries { + return body.collectEntries { Map.Entry entry -> [(entry.key): toDslProperty(entry.value)] - } as Map).findAll { - !(it.value.clientValue instanceof Optional || it.value.serverValue instanceof Optional) - } + } as Map } Collection convertObjectsToDslProperties(List body) { return (body.collect { Object element -> toDslProperty(element) - } as List).findAll { - !(it instanceof Optional) - } + } as List) } DslProperty toDslProperty(Object property) { @@ -78,6 +74,10 @@ class Common { return Pattern.compile(regex) } + OptionalProperty optional(Object object) { + return new OptionalProperty(object) + } + ExecutionProperty execute(String commandToExecute) { return new ExecutionProperty(commandToExecute) } @@ -98,8 +98,8 @@ class Common { return new ServerDslProperty(serverValue) } - Optional optional() { - return new Optional() + void assertThatSidesMatch(OptionalProperty stubSide, Object testSide) { + assert testSide ==~ Pattern.compile(stubSide.optionalPattern()) } void assertThatSidesMatch(Pattern pattern, String value) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Optional.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Optional.groovy deleted file mode 100644 index 02e7a16323..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Optional.groovy +++ /dev/null @@ -1,7 +0,0 @@ -package io.codearte.accurest.dsl.internal - -/** - * Marker class to show that an element of message is optional - */ -class Optional { -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OptionalProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OptionalProperty.groovy new file mode 100644 index 0000000000..877c31c661 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OptionalProperty.groovy @@ -0,0 +1,13 @@ +package io.codearte.accurest.dsl.internal + +class OptionalProperty { + final Object value + + OptionalProperty(Object value) { + this.value = value + } + + String optionalPattern() { + return "($value)?" + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 9be791488a..9adf7048a8 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -3,7 +3,6 @@ import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked -import groovy.xml.MarkupBuilder @TypeChecked @EqualsAndHashCode @@ -129,6 +128,10 @@ class Request extends Common { return new MatchingStrategy(true, MatchingStrategy.Type.ABSENT) } + void assertThatSidesMatch(Object stubSide, OptionalProperty testSide) { + throw new IllegalStateException("Optional can be used only for the stub side of the request!") + } + } @CompileStatic diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy index 3715f0c243..b2546cd5c8 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy @@ -49,6 +49,9 @@ class Response extends Common { this.body = new Body(bodyAsValue) } + void assertThatSidesMatch(OptionalProperty stubSide, Object testSide) { + throw new IllegalStateException("Optional can be used only in the test side of the response!") + } } @CompileStatic diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index c5261b43be..1b370b7126 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -8,7 +8,7 @@ import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Headers import io.codearte.accurest.dsl.internal.MatchingStrategy -import io.codearte.accurest.dsl.internal.Optional +import io.codearte.accurest.dsl.internal.OptionalProperty import org.codehaus.groovy.runtime.GStringImpl import java.util.regex.Matcher @@ -27,9 +27,9 @@ class ContentUtils { private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('.*REGEXP>>(.*)<<.*') private static final Pattern TEMPORARY_EXECUTION_PATTERN_HOLDER = Pattern.compile('EXECUTION>>(.*)<<') + private static final Pattern TEMPORARY_OPTIONAL_PATTERN_HOLDER = Pattern.compile('OPTIONAL>>(.*)<<') private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' - private static final String JSON_VALUE_OPTIONAL = 'OPTIONAL>><<' - private static final Pattern OPTIONAL_PATTERN_HOLDER = Pattern.compile(JSON_VALUE_OPTIONAL) + private static final String JSON_VALUE_PATTERN_FOR_OPTIONAL = 'OPTIONAL>>%s<<' private static final String JSON_VALUE_PATTERN_FOR_EXECUTION = '"EXECUTION>>%s<<"' /** @@ -160,8 +160,8 @@ class ContentUtils { return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern()) } - private static String transformJSONStringValue(Optional optional, Closure valueProvider) { - return JSON_VALUE_OPTIONAL + private static String transformJSONStringValue(OptionalProperty optional, Closure valueProvider) { + return String.format(JSON_VALUE_PATTERN_FOR_OPTIONAL, optional.value) } private static String transformJSONStringValue(ExecutionProperty property, Closure valueProvider) { @@ -213,23 +213,25 @@ class ContentUtils { static Object returnParsedObject(String string) { Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string.trim()) if (matcher.matches()) { - List val = matcher[0] as List - String pattern = val[1] - return Pattern.compile(pattern) + return Pattern.compile(patternFromMatchingGroup(matcher)) } Matcher executionMatcher = TEMPORARY_EXECUTION_PATTERN_HOLDER.matcher(string.trim()) if (executionMatcher.matches()) { - List val = executionMatcher[0] as List - String pattern = val[1] - return new ExecutionProperty(pattern) + return new ExecutionProperty(patternFromMatchingGroup(executionMatcher)) } - Matcher optionalMatcher = OPTIONAL_PATTERN_HOLDER.matcher(string.trim()) + Matcher optionalMatcher = TEMPORARY_OPTIONAL_PATTERN_HOLDER.matcher(string.trim()) if (optionalMatcher.matches()) { - return new Optional() + String patternToMatch = patternFromMatchingGroup(optionalMatcher) + return Pattern.compile(new OptionalProperty(patternToMatch).optionalPattern()) } return string } + private static String patternFromMatchingGroup(Matcher matcher) { + List val = matcher[0] as List + return val[1] + } + public static ContentType recognizeContentTypeFromHeader(Headers headers) { String content = headers?.entries.find { it.name == "Content-Type" } ?.clientValue?.toString() if (content?.endsWith("json")) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index db8f264e30..319e7ab660 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -1,9 +1,9 @@ package io.codearte.accurest.util - +import java.util.regex.Pattern import groovy.json.JsonSlurper import io.codearte.accurest.dsl.internal.ExecutionProperty +import io.codearte.accurest.dsl.internal.OptionalProperty -import java.util.regex.Pattern /** * @author Marcin Grzejszczak */ @@ -30,7 +30,7 @@ class JsonToJsonPathsConverter { JsonPaths pathsAndValues = [] as Set Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide) traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value -> - if (value instanceof ExecutionProperty || value instanceof io.codearte.accurest.dsl.internal.Optional) { + if (value instanceof ExecutionProperty) { return } JsonPathEntry entry = getValueToInsert(key, value) @@ -128,13 +128,19 @@ class JsonToJsonPathsConverter { protected static String compareWith(Object value) { if (value instanceof Pattern) { - return """=~ /${(value as Pattern).pattern()}/""" + return patternComparison((value as Pattern).pattern()) + } else if (value instanceof OptionalProperty) { + return patternComparison((value as OptionalProperty).optionalPattern()) } else if (value instanceof GString) { return """=~ /${RegexpBuilders.buildGStringRegexpForTestSide(value)}/""" } return """== ${potentiallyWrappedWithQuotesValue(value)}""" } + protected static String patternComparison(String pattern){ + return """=~ /$pattern/""" + } + protected static String potentiallyWrappedWithQuotesValue(Object value) { return value instanceof Number ? value : "'$value'" } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy index c4a6eed44b..22896d8308 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy @@ -1,9 +1,6 @@ package io.codearte.accurest.util - import groovy.json.JsonSlurper import io.codearte.accurest.dsl.internal.DslProperty -import io.codearte.accurest.dsl.internal.Optional - /** * @author Marcin Grzejszczak */ @@ -41,8 +38,6 @@ class MapConverter { return map.collectEntries { key, value -> [key, transformValues(value, closure)] - }.findAll { - !(it.value instanceof Optional) } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index f3ee4bd99a..44cb4e235f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -5,6 +5,7 @@ import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Specification +import spock.lang.Unroll /** * @author Jakub Kubrynski @@ -553,89 +554,77 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } @Issue('42') - def "should omit an optional field from body resolution"() { + @Unroll + def "should not omit the optional field in the test creation"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - email: optional(), - callback_url: $(client(regex(hostname())), server('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: optional(), - message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" - ) - } - } MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - !spockTest.contains('''body('{"email":''') - !spockTest.contains('''parsedJson.read(\'\'\'$[?(@.email''') + spockTest.contains('''"email":"abc@abc.com"''') + spockTest.contains('''parsedJson.read(\'\'\'$[?(@.code =~ /(123123)?/)]''') !spockTest.contains('''REGEXP''') !spockTest.contains('''OPTIONAL''') - !spockTest.contains('''Optional''') - } - - @Issue('42') - def "should omit an optional field from body resolution with GString"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' + !spockTest.contains('''OptionalProperty''') + where: + contractDsl << [ + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) } - body( - """ { - "email" : "${value(optional())}", + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: value(stub("123123"), test(optional("123123"))), + message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) + } + }, + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" } """ - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' + ) } - body( - """ { - "code" : "${value(optional())}", + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "code" : "${value(stub(123123), test(optional(123123)))}", "message" : "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" } """ - ) + ) + } } - } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() - then: - !spockTest.contains('''body('{"email":''') - !spockTest.contains('''parsedJson.read(\'\'\'$[?(@.code''') - !spockTest.contains('''REGEXP''') - !spockTest.contains('''OPTIONAL''') - !spockTest.contains('''Optional''') + ] } @Issue('72') 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 cbceb49f80..7502ada771 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 @@ -5,6 +5,7 @@ import groovy.json.JsonSlurper import io.codearte.accurest.util.AssertionUtil import spock.lang.Issue import spock.lang.Specification +import spock.lang.Unroll class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifier { @@ -1294,125 +1295,96 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } @Issue('42') - def 'should generate stub without optional parameters with GString'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' + @Unroll + def 'should generate stub without optional parameters'() { + when: + String wireMockStub = new WireMockStubStrategy(contractDsl).toWireMockClientStub() + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "url" : "/users/password", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]" + }, { + "matchesJsonPath" : "$[?(@.email =~ /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4})?/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 404, + "body" : "{\\"code\\":\\"123123\\",\\"message\\":\\"User not found by email = [not.existing@user.com]\\"}", + "headers" : { + "Content-Type" : "application/json" + } + }, + "priority" : 1 + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + where: + contractDsl << [ + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) } - body( - """ { - "email" : "${value(optional())}", + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: $(stub("123123"), test(optional("123123"))), + message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) + } + }, + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" } """ - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' + ) } - body( - """ { - "code" : "${value(optional())}", + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "code" : "${value(stub(123123), test(optional(123123)))}", "message" : "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" } """ - ) - } - } - when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() - then: - AssertionUtil.assertThatJsonsAreEqual((''' - { - "request" : { - "url" : "/users/password", - "method" : "POST", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - } - }, - "response" : { - "status" : 404, - "body" : "{\\"message\\":\\"User not found by email = [not.existing@user.com]\\"}", - "headers" : { - "Content-Type" : "application/json" - } - }, - "priority" : 1 - } - '''), wireMockStub) - and: - stubMappingIsValidWireMockStub(wireMockStub) - } - - @Issue('42') - def 'should generate stub without optional parameters'() { - given: - GroovyDsl groovyDsl = GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' + ) } - body( - email: optional(), - callback_url: $(client(regex(hostname())), server('http://partners.com')) - ) } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: optional(), - message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" - ) - } - } - when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() - then: - AssertionUtil.assertThatJsonsAreEqual((''' - { - "request" : { - "url" : "/users/password", - "method" : "POST", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - } - }, - "response" : { - "status" : 404, - "body" : "{\\"message\\":\\"User not found by email = [not.existing@user.com]\\"}", - "headers" : { - "Content-Type" : "application/json" - } - }, - "priority" : 1 - } - '''), wireMockStub) - and: - stubMappingIsValidWireMockStub(wireMockStub) + ] } String toJsonString(value) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy index 241380062f..537fb78ea2 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy @@ -10,7 +10,7 @@ trait WireMockStubVerifier { stubMapping.request.bodyPatterns.findAll { it.matches }.every { Pattern.compile(it.matches) } - assert !mappingDefinition.contains('DslProperty') + assert !mappingDefinition.contains('io.codearte.accurest.dsl.internal') } } From 10835c1fcbe116c03301183892cf5f1bde70c526 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 6 Oct 2015 13:06:11 +0200 Subject: [PATCH 228/719] wiremock update to 2.0.5-beta and cleanup --- .../plugin/AccurestGradlePlugin.groovy | 2 +- .../functionalTest/bootSimple/build.gradle | 7 ++---- .../sampleJerseyProject/build.gradle | 22 ++++++++++--------- .../functionalTest/sampleProject/build.gradle | 9 ++++---- gradle.properties | 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) 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 efd3f76e92..11a86d33c9 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 @@ -30,7 +30,7 @@ class AccurestGradlePlugin implements Plugin { createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() - project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.4-beta") + project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.5-beta") project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index e392e694c3..e7565e3efe 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -34,17 +34,14 @@ repositories { dependencies { compile "org.springframework:spring-web:$springVersion" compile "org.springframework:spring-context-support:$springVersion" - compile "org.codehaus.groovy:groovy-all:2.4.4" + compile "org.codehaus.groovy:groovy-all:2.4.5" compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' - compile "org.codehaus.jackson:jackson-mapper-asl:$jacksonMapper" - compile "org.codehaus.jackson:jackson-core-asl:$jacksonMapper" compile 'com.jayway.jsonpath:json-path-assert:2.0.0' - testCompile "com.github.tomakehurst:wiremock:2.0.4-beta" + testCompile "com.github.tomakehurst:wiremock:2.0.5-beta" testCompile "org.spockframework:spock-spring:1.0-groovy-2.4" testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" - testCompile 'javax.servlet:javax.servlet-api:3.1.0' testCompile "ch.qos.logback:logback-classic:1.1.2" } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index ee3e5ea354..f33b17b5a6 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -4,13 +4,14 @@ buildscript { mavenCentral() } dependencies { - classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE" + classpath "org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE" } } ext { - restAssuredVersion = '2.4.0' + restAssuredVersion = '2.5.0' spockVersion = '1.0-groovy-2.4' + wiremockVersion = '2.0.5-beta' accurestStubsBaseDirectory = 'src/test/resources/stubs' } @@ -24,10 +25,10 @@ subprojects { } dependencies { - testCompile 'org.codehaus.groovy:groovy-all:2.4.4' + testCompile 'org.codehaus.groovy:groovy-all:2.4.5' testCompile "org.spockframework:spock-core:$spockVersion" testCompile 'junit:junit:4.12' - testCompile 'com.github.tomakehurst:wiremock:2.0.4-beta' + testCompile "com.github.tomakehurst:wiremock:$wiremockVersion" } } @@ -53,18 +54,19 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') version = '0.0.1' } + configurations { + compile.exclude module: "spring-boot-starter-tomcat" + } + dependencies { - compile "javax.ws.rs:javax.ws.rs-api:2.0.1" compile 'org.glassfish.jersey.containers:jersey-container-jetty-http:2.15' - compile('org.springframework.boot:spring-boot-starter-jersey:1.2.6.RELEASE') { - exclude module: "spring-boot-starter-tomcat" - } - compile 'org.springframework.boot:spring-boot-starter-jetty:1.2.6.RELEASE' + compile 'org.springframework.boot:spring-boot-starter-jersey' + compile 'org.springframework.boot:spring-boot-starter-jetty' testRuntime "org.spockframework:spock-spring:$spockVersion" compile 'org.glassfish.jersey.connectors:jersey-apache-connector:2.15' - testCompile 'org.springframework:spring-test:4.1.7.RELEASE' + testCompile 'org.springframework:spring-test' } task cleanup(type: Delete) { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 7a88858a51..25ca064fc4 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -4,13 +4,14 @@ buildscript { mavenLocal() } dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.1.RELEASE") + classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE") } } ext { - restAssuredVersion = '2.4.0' + restAssuredVersion = '2.5.0' spockVersion = '1.0-groovy-2.4' + wiremockVersion = '2.0.5-beta' accurestStubsBaseDirectory = 'src/test/resources/stubs' } @@ -24,10 +25,10 @@ subprojects { } dependencies { - testCompile "org.codehaus.groovy:groovy-all:2.4.4" + testCompile "org.codehaus.groovy:groovy-all:2.4.5" testCompile "org.spockframework:spock-core:$spockVersion" testCompile("junit:junit:4.12") - testCompile "com.github.tomakehurst:wiremock:2.0.4-beta" + testCompile "com.github.tomakehurst:wiremock:$wiremockVersion" } } diff --git a/gradle.properties b/gradle.properties index 8ab8e8bf7b..27a71580f7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ nexusUsername = nexusPassword = -wiremockVersion = 2.0.4-beta +wiremockVersion = 2.0.5-beta From ed1cd6eab31271bacb1d2e2a992f8f015953b710 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Tue, 6 Oct 2015 17:36:10 +0200 Subject: [PATCH 229/719] Fix encoding issue --- .../src/main/groovy/io/codearte/accurest/TestGenerator.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index 63e2047217..78e414e929 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -4,6 +4,7 @@ import io.codearte.accurest.config.AccurestConfigProperties import org.apache.commons.io.FilenameUtils import org.codehaus.plexus.util.DirectoryScanner +import java.nio.charset.StandardCharsets import java.util.concurrent.atomic.AtomicInteger import static io.codearte.accurest.util.NamesUtil.afterLast @@ -62,7 +63,7 @@ class TestGenerator { } if (filesToClass.size()) { def className = afterLast(includedDirectoryRelativePath, File.separator) + configProperties.targetFramework.classNameSuffix - def classBytes = generator.buildClass(filesToClass, className, packageNameForClass).bytes + def classBytes = generator.buildClass(filesToClass, className, packageNameForClass).getBytes(StandardCharsets.UTF_8) saver.saveClassFile(className, packageNameForClass, classBytes) counter.incrementAndGet() } From 1ab57580a9b2761b0b6ecce813f754f6f8ec2b3d Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 6 Oct 2015 20:28:07 +0200 Subject: [PATCH 230/719] Release version: 0.9.4 [ci skip] From cbb39dbad6ddbaf67b432819f4042bac904ebb3c Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Wed, 7 Oct 2015 11:11:15 +0200 Subject: [PATCH 231/719] Fix encoding issue --- .../groovy/io/codearte/accurest/builder/MethodBuilder.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index c4e8da6d04..55a0f66f36 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -6,6 +6,7 @@ import io.codearte.accurest.config.TestFramework import io.codearte.accurest.config.TestMode import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.util.NamesUtil +import org.codehaus.groovy.control.CompilerConfiguration /** * @author Jakub Kubrynski @@ -25,7 +26,7 @@ class MethodBuilder { static MethodBuilder createTestMethod(File stubsFile, AccurestConfigProperties configProperties) { log.debug("Stub content from file [${stubsFile.text}]") - GroovyDsl stubContent = new GroovyShell(this.classLoader).evaluate(stubsFile) + GroovyDsl stubContent = new GroovyShell(this.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate(stubsFile) 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) From 9d16cc051fc3f04a71ac5e644a80198b90bb8bb7 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 7 Oct 2015 11:29:24 +0200 Subject: [PATCH 232/719] Revert "Set UTF-8 encoding when loading stubs" --- .../groovy/io/codearte/accurest/builder/MethodBuilder.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index 55a0f66f36..c4e8da6d04 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -6,7 +6,6 @@ import io.codearte.accurest.config.TestFramework import io.codearte.accurest.config.TestMode import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.util.NamesUtil -import org.codehaus.groovy.control.CompilerConfiguration /** * @author Jakub Kubrynski @@ -26,7 +25,7 @@ class MethodBuilder { static MethodBuilder createTestMethod(File stubsFile, AccurestConfigProperties configProperties) { log.debug("Stub content from file [${stubsFile.text}]") - GroovyDsl stubContent = new GroovyShell(this.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate(stubsFile) + GroovyDsl stubContent = new GroovyShell(this.classLoader).evaluate(stubsFile) 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) From f5da5c4278984a1503fd2c287c97e4d5b81b3ea2 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 7 Oct 2015 11:32:05 +0200 Subject: [PATCH 233/719] Revert "Merge pull request #159 from Codearte/revert-158-encoding-fix2" This reverts commit a85bb25b13a3a4396a96c9015ab26feae5a73db7, reversing changes made to c7a066bb364bfd24efe29710533a39197f357e3f. --- .../groovy/io/codearte/accurest/builder/MethodBuilder.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index c4e8da6d04..55a0f66f36 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -6,6 +6,7 @@ import io.codearte.accurest.config.TestFramework import io.codearte.accurest.config.TestMode import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.util.NamesUtil +import org.codehaus.groovy.control.CompilerConfiguration /** * @author Jakub Kubrynski @@ -25,7 +26,7 @@ class MethodBuilder { static MethodBuilder createTestMethod(File stubsFile, AccurestConfigProperties configProperties) { log.debug("Stub content from file [${stubsFile.text}]") - GroovyDsl stubContent = new GroovyShell(this.classLoader).evaluate(stubsFile) + GroovyDsl stubContent = new GroovyShell(this.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate(stubsFile) 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) From cf8ee61eb3a41499e344a7ea3e067c0538969073 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Thu, 8 Oct 2015 10:36:12 +0200 Subject: [PATCH 234/719] Support inner map and list --- .../dsl/internal/RegexPatterns.groovy | 11 ++++ .../accurest/util/MapConverter.groovy | 16 ++++- .../MockMvcSpockMethodBuilderSpec.groovy | 66 +++++++++++++++++++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy index 432dee266d..0f530bbf8f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy @@ -7,11 +7,22 @@ import java.util.regex.Pattern @CompileStatic class RegexPatterns { + private static final Pattern TRUE_OR_FALSE = Pattern.compile(/(true|false)/) + private static final Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) private static final Pattern IP_ADDRESS = Pattern.compile('([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])'); private static final Pattern HOSTNAME_PATTERN = Pattern.compile('((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?'); private static final Pattern EMAIL = Pattern.compile('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'); private static final Pattern URL = Pattern.compile('((www\\.|(http|https|ftp|news|file)+\\:\\/\\/)[_.a-z0-9-]+\\.[a-z0-9\\/_:@=.+?,##%&~-]*[^.|\\\'|\\# |!|\\(|?|,| |>|<|;|\\)])'); + + String onlyAlphaUnicode() { + return ONLY_ALPHA_UNICODE.pattern() + } + + String anyBoolean() { + return TRUE_OR_FALSE.pattern() + } + String ipAddress() { return IP_ADDRESS.pattern() } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy index 22896d8308..7087f9c1d7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy @@ -20,13 +20,27 @@ class MapConverter { return convert(json, closure) } } catch (Exception ignore) { - return closure(value) } + return extractValue(value, closure); } else if (value instanceof Map) { return convert(value as Map, closure) } else if (value instanceof List) { return value.collect({ transformValues(it, closure) }) } + return transformValue(closure, value) + } + + protected static Object transformValue(Closure closure, Object value) { + return extractValue(value, { Object val-> + Object newValue = closure(val) + if (newValue instanceof Map || newValue instanceof List || newValue instanceof String && value) { + return transformValues(newValue, closure) + } + return newValue; + }) + } + + private static extractValue(Object value, Closure closure) { try { return closure(value) } catch (Exception ignore) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 44cb4e235f..8d6bdbf343 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -7,6 +7,8 @@ import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll +import java.util.regex.Pattern + /** * @author Jakub Kubrynski */ @@ -669,4 +671,68 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: spockTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''') } + + def "should support inner map and list definitions"() { + given: + + Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) + Pattern ANYSTRING = Pattern.compile(/.*/) + Pattern NUMBERS = Pattern.compile(/[\d\.]*/) + Pattern DATETIME = ANYSTRING + + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" + headers { + header('Content-Type': 'application/json') + } + body( + client: [ + first_name: $(stub(regex(onlyAlphaUnicode())), test('Denis')), + last_name: $(stub(regex(onlyAlphaUnicode())), test('FakeName')), + email: $(stub(regex(email())), test('fakemail@fakegmail.com')), + fax: $(stub(PHONE_NUMBER), test('+xx001213214')), + phone: $(stub(PHONE_NUMBER), test('2223311')), + data_of_birth: $(stub(DATETIME), test('2002-10-22T00:00:00Z')) + ], + client_id_card: [ + id: $(stub(ANYSTRING), test('ABC12345')), + date_of_issue: $(stub(ANYSTRING), test('2002-10-02T00:00:00Z')), + address: [ + street: $(stub(ANYSTRING), test('Light Street')), + city: $(stub(ANYSTRING), test('Fire')), + region: $(stub(ANYSTRING), test('Skys')), + country: $(stub(ANYSTRING), test('HG')), + zip: $(stub(NUMBERS), test('658965')) + ] + ], + incomes_and_expenses: [ + monthly_income: $(stub(NUMBERS), test('0.0')), + monthly_loan_repayments: $(stub(NUMBERS), test('100')), + monthly_living_expenses: $(stub(NUMBERS), test('22')) + ], + additional_info: [ + allow_to_contact: $(stub(optional(regex(anyBoolean()))), test('true')) + ] + ) + } + response { + status 200 + headers { + header('Content-Type': 'application/json') + } + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains '"street":"Light Street"' + !spockTest.contains("clientValue") + !spockTest.contains("cursor") + } + } From 806ad6086fba7a089ff90d00abe7983bbcb4ccd2 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 9 Oct 2015 12:43:01 +0200 Subject: [PATCH 235/719] Release version: 0.9.6 [ci skip] From bfd72c1275d996d7dacf4e9736438a5b272ef0fb Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Wed, 7 Oct 2015 17:14:25 +0200 Subject: [PATCH 236/719] Fix encoding issue --- .../builder/SpockMethodBodyBuilder.groovy | 10 ++++- .../MockMvcSpockMethodBuilderSpec.groovy | 37 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 2789e52a2d..618398ad5b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,5 +1,7 @@ package io.codearte.accurest.builder + import groovy.json.JsonOutput +import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.GroovyDsl @@ -117,7 +119,13 @@ abstract class SpockMethodBodyBuilder { protected String getBodyAsString() { Object bodyValue = extractServerValueFromBody(request.body.serverValue) - return trimRepeatedQuotes(new JsonOutput().toJson(bodyValue)) + String json = new JsonOutput().toJson(bodyValue) + json = convertUnicodeEscapes(json) + return trimRepeatedQuotes(json) + } + + protected String convertUnicodeEscapes(String json) { + return StringEscapeUtils.unescapeJavaScript(json) } protected String trimRepeatedQuotes(String toTrim) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 44cb4e235f..fce1bdff84 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -7,6 +7,8 @@ import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll +import java.util.regex.Pattern + /** * @author Jakub Kubrynski */ @@ -669,4 +671,39 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: spockTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''') } + + def "shouldn't generate unicode escape characters"() { + given: + Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) + + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев" + headers { + header('Content-Type': 'application/json') + } + body( + client: [ + first_name: $(stub(ONLY_ALPHA_UNICODE), test('Пенева')), + last_name : $(stub(ONLY_ALPHA_UNICODE), test('Пенева')) + ] + ) + } + response { + status 200 + headers { + header('Content-Type': 'application/json') + } + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + !spockTest.contains("\\u041f") + } + } From 25ce3d7f71e273d705bc74c88f7d5a2a225fb9d9 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Tue, 13 Oct 2015 14:57:08 +0200 Subject: [PATCH 237/719] Add UTF-8 as Groovy DSL file format --- .../codearte/accurest/wiremock/DslToWireMockConverter.groovy | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 9163724610..89b2b381ce 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 @@ -2,6 +2,7 @@ package io.codearte.accurest.wiremock import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl +import org.codehaus.groovy.control.CompilerConfiguration @CompileStatic abstract class DslToWireMockConverter implements SingleFileConverter { @@ -17,6 +18,6 @@ abstract class DslToWireMockConverter implements SingleFileConverter { } protected GroovyDsl createGroovyDSLfromStringContent(String groovyDslAsString) { - return (GroovyDsl) new GroovyShell(this.class.classLoader).evaluate("$groovyDslAsString") + return (GroovyDsl) new GroovyShell(this.class.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate("$groovyDslAsString") } } From 1d6fe2291056fe2849c4a2ea653cc86efab8fba2 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 13 Oct 2015 15:55:57 +0200 Subject: [PATCH 238/719] Release version: 0.9.7 [ci skip] From be20569e4aca3383cfa88c22b91ac00e943456bd Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 15 Oct 2015 10:23:26 +0200 Subject: [PATCH 239/719] Updated readme with requirements for wiremock --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index b079b674a9..923a398c25 100644 --- a/README.md +++ b/README.md @@ -13,3 +13,9 @@ generating Spock's acceptance tests for the server - to verify if your API imple 2. moving TDD to an architecture level. For more information please go to the [Wiki](https://github.com/Codearte/accurest/wiki/1.-Introduction) + +## Requirements + +### Wiremock + +In order to use Accurest with Wiremock you have to have __Wiremock in version at least 2.0.0-beta__ . Of course the higher the better :) From e7a69c3d5b0e2d7b64ed60cd7b592c8fadedbb42 Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Thu, 15 Oct 2015 10:04:12 +0200 Subject: [PATCH 240/719] Set UTF-8 default encoding --- .../accurest/wiremock/RecursiveFilesConverter.groovy | 5 +++-- .../accurest/wiremock/WireMockToDslConverter.groovy | 6 ++++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy index 0f74866305..8f71f8955b 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy @@ -4,6 +4,7 @@ import groovy.io.FileType import groovy.transform.CompileStatic import groovy.util.logging.Slf4j +import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths @@ -28,10 +29,10 @@ class RecursiveFilesConverter { if (!singleFileConverter.canHandleFileName(sourceFile.name)) { return } - String convertedContent = singleFileConverter.convertContent(sourceFile.text) + String convertedContent = singleFileConverter.convertContent(sourceFile.getText(StandardCharsets.UTF_8.toString())) Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile) File newGroovyFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) - newGroovyFile.text = convertedContent + newGroovyFile.setText(convertedContent, StandardCharsets.UTF_8.toString()) } catch (Exception e) { throw new ConversionAccurestException("Unable to make convertion of ${sourceFile.name}", e) } 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 e7a2a45f97..4107d2dcdf 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 @@ -8,6 +8,8 @@ import groovy.xml.XmlUtil import io.codearte.accurest.dsl.GroovyDsl import nl.flotsam.xeger.Xeger +import java.nio.charset.StandardCharsets + import static org.apache.commons.lang3.StringEscapeUtils.escapeJava class WireMockToDslConverter { @@ -154,11 +156,11 @@ class WireMockToDslConverter { if (!it.name.endsWith('json')) { return } - String dslFromWireMockStub = fromWireMockStub(it.text) + String dslFromWireMockStub = fromWireMockStub(it.getText(StandardCharsets.UTF_8.toString())) String dslWrappedWithFactoryMethod = wrapWithFactoryMethod(dslFromWireMockStub) File newGroovyFile = new File(it.parent, it.name.replaceAll('json', 'groovy')) println("Creating new groovy file [$newGroovyFile.path]") - newGroovyFile.text = dslWrappedWithFactoryMethod + newGroovyFile.setText(dslWrappedWithFactoryMethod, StandardCharsets.UTF_8.toString()) } catch (Exception e) { System.err.println(e) } From dc90d82fd3bb7666c2e2813091529eaf05268c17 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 15 Oct 2015 11:00:21 +0200 Subject: [PATCH 241/719] Release version: 0.9.8 [ci skip] From 7a852e1e33b9cc6c79463095958edc8af0ef6a48 Mon Sep 17 00:00:00 2001 From: Adam Wojszczyk Date: Mon, 2 Nov 2015 11:37:14 +0100 Subject: [PATCH 242/719] Add regex to match numbers (integers and decimals) --- .../accurest/dsl/internal/RegexPatterns.groovy | 7 ++++++- .../accurest/dsl/internal/RegexPatternsSpec.groovy | 13 +++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy index 0f530bbf8f..5327bcff66 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy @@ -9,10 +9,11 @@ class RegexPatterns { private static final Pattern TRUE_OR_FALSE = Pattern.compile(/(true|false)/) private static final Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) + private static final Pattern NUMBER = Pattern.compile('-?\\d*(\\.\\d+)?') private static final Pattern IP_ADDRESS = Pattern.compile('([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])'); private static final Pattern HOSTNAME_PATTERN = Pattern.compile('((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?'); private static final Pattern EMAIL = Pattern.compile('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'); - private static final Pattern URL = Pattern.compile('((www\\.|(http|https|ftp|news|file)+\\:\\/\\/)[_.a-z0-9-]+\\.[a-z0-9\\/_:@=.+?,##%&~-]*[^.|\\\'|\\# |!|\\(|?|,| |>|<|;|\\)])'); + private static final Pattern URL = Pattern.compile('((www\\.|(http|https|ftp|news|file)+\\:\\/\\/)[_.a-z0-9-]+\\.[a-z0-9\\/_:@=.+?,##%&~-]*[^.|\\\'|\\# |!|\\(|?|,| |>|<|;|\\)])') String onlyAlphaUnicode() { @@ -38,4 +39,8 @@ class RegexPatterns { String url() { return URL.pattern() } + + String number() { + return NUMBER.pattern() + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy index 848ed8511d..bc217f336e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy @@ -52,4 +52,17 @@ class RegexPatternsSpec extends Specification { 'ftp://asd.com:9090/asd/a?a=b' || true 'a.b.' || false } + + @Unroll + def "should generate a regex for a number [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.number()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + '1' || true + '1.0' || true + '0.1' || true + '.1' || true + '1.' || false + } } From 5f42368810d84f87d302282fc23b6313762631d4 Mon Sep 17 00:00:00 2001 From: Adam Wojszczyk Date: Mon, 2 Nov 2015 11:38:58 +0100 Subject: [PATCH 243/719] Add regex to match numbers (integers and decimals) --- .../codearte/accurest/dsl/internal/RegexPatterns.groovy | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy index 5327bcff66..3daa34ec90 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy @@ -20,6 +20,10 @@ class RegexPatterns { return ONLY_ALPHA_UNICODE.pattern() } + String number() { + return NUMBER.pattern() + } + String anyBoolean() { return TRUE_OR_FALSE.pattern() } @@ -39,8 +43,4 @@ class RegexPatterns { String url() { return URL.pattern() } - - String number() { - return NUMBER.pattern() - } } From 943ff5b60813bd2da84f7ae9244dc2094e55cdc5 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 3 Nov 2015 13:34:30 +0100 Subject: [PATCH 244/719] Release version: 0.9.9 [ci skip] From 04721e13b14c5eaf69537a4ef78ab343ab2eaf1b Mon Sep 17 00:00:00 2001 From: mzielinski Date: Tue, 3 Nov 2015 23:07:26 +0100 Subject: [PATCH 245/719] #166 directory structure of dsl groovy scripts should be used in generated specifications --- .../io/codearte/accurest/TestGenerator.groovy | 17 +++++++++++++---- .../io/codearte/accurest/util/NamesUtil.groovy | 11 +++++++++++ .../accurest/GeneratorScannerSpec.groovy | 16 +++++++++++++++- .../stubs/package/v1/exceptions/testv1.groovy | 0 .../stubs/package/v2/exceptions/testv2.groovy | 0 5 files changed, 39 insertions(+), 5 deletions(-) create mode 100644 accurest-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy create mode 100644 accurest-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index fb612cebd1..a502448bc4 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -7,6 +7,9 @@ import org.codehaus.plexus.util.DirectoryScanner import java.util.concurrent.atomic.AtomicInteger import static io.codearte.accurest.util.NamesUtil.afterLast +import static io.codearte.accurest.util.NamesUtil.beforeLast +import static io.codearte.accurest.util.NamesUtil.directoryToPackage + /** * @author Jakub Kubrynski */ @@ -62,14 +65,20 @@ class TestGenerator { } if (filesToClass.size()) { def className = afterLast(includedDirectoryRelativePath, File.separator) + configProperties.targetFramework.classNameSuffix - def classBytes = generator.buildClass(filesToClass, className, packageNameForClass).bytes - saver.saveClassFile(className, packageNameForClass, classBytes) + def packageName = buildPackage(packageNameForClass, includedDirectoryRelativePath) + def classBytes = generator.buildClass(filesToClass, className, packageName).bytes + saver.saveClassFile(className, packageName, classBytes) counter.incrementAndGet() } } } - - private String normalizePath(String path) { + + private static String buildPackage(final String packageNameForClass, final String includedDirectoryRelativePath) { + String directory = beforeLast(includedDirectoryRelativePath, File.separator) + return "$packageNameForClass.${directoryToPackage(directory)}" + } + + private static String normalizePath(String path) { return FilenameUtils.separatorsToUnix(path) } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy index 4817cc4816..88172ca90b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy @@ -5,6 +5,13 @@ package io.codearte.accurest.util */ class NamesUtil { + static String beforeLast(String string, String separator) { + if (string?.indexOf(separator) > -1) { + return string.substring(0, string.lastIndexOf(separator)) + } + return string + } + static String afterLast(String string, String separator) { if (string?.indexOf(separator) > -1) { return string.substring(string.lastIndexOf(separator) + 1) @@ -42,4 +49,8 @@ class NamesUtil { static String packageToDirectory(String packageName) { return packageName.replaceAll('\\.', File.separator) } + + static String directoryToPackage(String directory) { + return directory.replace(File.separator, '.') + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy index 6a478e3d92..523dd5ba4f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy @@ -16,7 +16,7 @@ class GeneratorScannerSpec extends Specification { when: testGenerator.generateTestClasses("com.ofg") then: - 3 * classGenerator.buildClass(_, _, _) >> "qwerty" + 5 * classGenerator.buildClass(_, _, _) >> "qwerty" } def "should filter other directory"() { @@ -30,6 +30,7 @@ class GeneratorScannerSpec extends Specification { testGenerator.generateTestClasses("com.ofg") then: 1 * classGenerator.buildClass(_, 'differentSpec', _) >> "qwerty" + 2 * classGenerator.buildClass(_, 'exceptionsSpec', _) >> "qwerty" } def "should ignore file"() { @@ -45,4 +46,17 @@ class GeneratorScannerSpec extends Specification { then: 1 * classGenerator.buildClass({ it.size() == 1 }, 'otherSpec', _) >> "sample.groovy" } + + def "should create class with full package"() { + given: + AccurestConfigProperties properties = new AccurestConfigProperties() + properties.contractsDslDir = new File(this.getClass().getResource("/directory/with/stubs/package").toURI()) + TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) + when: + testGenerator.generateTestClasses("com.ofg") + then: + 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v1') >> "spec1" + 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v2') >> "spec2" + } + } diff --git a/accurest-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy b/accurest-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy b/accurest-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy new file mode 100644 index 0000000000..e69de29bb2 From 9b6451cdbee5b3b8ec986a9dd060dd71f9c0125c Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 4 Nov 2015 09:11:02 +0100 Subject: [PATCH 246/719] #168 add intends in "should create class with full package" test --- .../io/codearte/accurest/GeneratorScannerSpec.groovy | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy index 523dd5ba4f..fb573f7a1b 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy @@ -49,14 +49,14 @@ class GeneratorScannerSpec extends Specification { def "should create class with full package"() { given: - AccurestConfigProperties properties = new AccurestConfigProperties() - properties.contractsDslDir = new File(this.getClass().getResource("/directory/with/stubs/package").toURI()) - TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) + AccurestConfigProperties properties = new AccurestConfigProperties() + properties.contractsDslDir = new File(this.getClass().getResource("/directory/with/stubs/package").toURI()) + TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) when: - testGenerator.generateTestClasses("com.ofg") + testGenerator.generateTestClasses("com.ofg") then: - 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v1') >> "spec1" - 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v2') >> "spec2" + 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v1') >> "spec1" + 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v2') >> "spec2" } } From d4c59421660fdd15ae8f8ff967f7478080ea8044 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Wed, 4 Nov 2015 10:02:19 +0100 Subject: [PATCH 247/719] #168 fix bug when there is not subdirectories --- .../main/groovy/io/codearte/accurest/TestGenerator.groovy | 4 ++-- .../main/groovy/io/codearte/accurest/util/NamesUtil.groovy | 2 +- .../io/codearte/accurest/GeneratorScannerSpec.groovy | 7 ++++--- .../directory/with/stubs/package/exceptions/test.groovy | 0 4 files changed, 7 insertions(+), 6 deletions(-) create mode 100644 accurest-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index 719b5cadca..339def4b8c 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -76,8 +76,8 @@ class TestGenerator { private static String buildPackage(final String packageNameForClass, final String includedDirectoryRelativePath) { String directory = beforeLast(includedDirectoryRelativePath, File.separator) - return "$packageNameForClass.${directoryToPackage(directory)}" - } + return !directory.empty ? "$packageNameForClass.${directoryToPackage(directory)}" : packageNameForClass + } private static String normalizePath(String path) { return FilenameUtils.separatorsToUnix(path) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy index 5b19c72645..23e8c54479 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy @@ -9,7 +9,7 @@ class NamesUtil { if (string?.indexOf(separator) > -1) { return string.substring(0, string.lastIndexOf(separator)) } - return string + return '' } static String afterLast(String string, String separator) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy index fb573f7a1b..f11187e3d2 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy @@ -7,7 +7,7 @@ class GeneratorScannerSpec extends Specification { private SingleTestGenerator classGenerator = Mock(SingleTestGenerator) - def "should find all .json files and generate 3 classes for them"() { + def "should find all .json files and generate 6 classes for them"() { given: File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) AccurestConfigProperties properties = new AccurestConfigProperties() @@ -16,7 +16,7 @@ class GeneratorScannerSpec extends Specification { when: testGenerator.generateTestClasses("com.ofg") then: - 5 * classGenerator.buildClass(_, _, _) >> "qwerty" + 6 * classGenerator.buildClass(_, _, _) >> "qwerty" } def "should filter other directory"() { @@ -30,7 +30,7 @@ class GeneratorScannerSpec extends Specification { testGenerator.generateTestClasses("com.ofg") then: 1 * classGenerator.buildClass(_, 'differentSpec', _) >> "qwerty" - 2 * classGenerator.buildClass(_, 'exceptionsSpec', _) >> "qwerty" + 3 * classGenerator.buildClass(_, 'exceptionsSpec', _) >> "qwerty" } def "should ignore file"() { @@ -55,6 +55,7 @@ class GeneratorScannerSpec extends Specification { when: testGenerator.generateTestClasses("com.ofg") then: + 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg') >> "spec" 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v1') >> "spec1" 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v2') >> "spec2" } diff --git a/accurest-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy b/accurest-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy new file mode 100644 index 0000000000..e69de29bb2 From 12545af59c63cf8b673df75e3021997915bd4fae Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Nov 2015 10:13:06 +0100 Subject: [PATCH 248/719] [#169] Query params - fixes #169 --- .../MockMvcSpockMethodBodyBuilder.groovy | 21 +++++---- .../builder/SpockMethodBodyBuilder.groovy | 4 +- .../dsl/BaseWireMockStubStrategy.groovy | 6 +-- .../accurest/util/MapConverter.groovy | 12 +++++ .../MockMvcSpockMethodBuilderSpec.groovy | 44 +++++++++++++++++++ 5 files changed, 71 insertions(+), 16 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index af84103be2..36191035ef 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.builder +import java.util.regex.Pattern import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode @@ -7,9 +8,8 @@ import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.Request -import io.codearte.accurest.dsl.internal.UrlPath - -import java.util.regex.Pattern +import io.codearte.accurest.dsl.internal.Url +import io.codearte.accurest.util.MapConverter @PackageScope @TypeChecked @@ -67,24 +67,27 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { protected String buildUrl(Request request) { if (request.url) - return getTestSideValue(request.url.serverValue) + 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(UrlPath urlPath) { - String params = "" - if (urlPath.queryParameters) { - params = urlPath.queryParameters.parameters + protected String buildUrlFromUrlPath(Url url) { + if (hasQueryParams(url)) { + String params = url.queryParameters.parameters .findAll(this.&allowedQueryParameter) .inject([] as List) { List result, QueryParameter param -> result << "${param.name}=${resolveParamValue(param).toString()}" } .join('&') + return "${MapConverter.getTestSideValues(url.serverValue)}?$params" } - return "$urlPath.serverValue?$params" + return MapConverter.getTestSideValues(url.serverValue) } + private boolean hasQueryParams(Url url) { + return url.queryParameters + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 618398ad5b..192ec4a2ab 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -19,8 +19,6 @@ import static io.codearte.accurest.util.ContentUtils.* @TypeChecked abstract class SpockMethodBodyBuilder { - private static final Boolean TEST_SIDE = false - protected final Request request protected final Response response @@ -211,6 +209,6 @@ abstract class SpockMethodBodyBuilder { } protected String getTestSideValue(Object object) { - return MapConverter.getClientOrServerSideValues(object, TEST_SIDE).toString() + return MapConverter.getTestSideValues(object).toString() } } 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 index c485285281..985a7b8271 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy @@ -17,10 +17,8 @@ import static io.codearte.accurest.util.MapConverter.transformValues @TypeChecked abstract class BaseWireMockStubStrategy { - private static final Boolean STUB_SIDE = true - protected getStubSideValue(Object object) { - return MapConverter.getClientOrServerSideValues(object, STUB_SIDE) + return MapConverter.getStubSideValues(object) } private static Closure transform = { @@ -66,7 +64,7 @@ abstract class BaseWireMockStubStrategy { } public String parseBody(Map map, ContentType contentType) { - def transformedMap = MapConverter.getClientOrServerSideValues(map, true) + def transformedMap = MapConverter.getStubSideValues(map) return parseBody(toJson(transformedMap), contentType) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy index 7087f9c1d7..477f0fef78 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy @@ -6,6 +6,10 @@ import io.codearte.accurest.dsl.internal.DslProperty */ class MapConverter { + + public static final boolean STUB_SIDE = true + public static final boolean TEST_SIDE = false + static def transformToClientValues(def value) { return transformValues(value) { it instanceof DslProperty ? it.clientValue : it @@ -73,4 +77,12 @@ class MapConverter { return it } } + + static Object getStubSideValues(json) { + return getClientOrServerSideValues(json, STUB_SIDE) + } + + static Object getTestSideValues(json) { + return getClientOrServerSideValues(json, TEST_SIDE) + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 5e8139172f..a762d57045 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -337,6 +337,50 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } + @Issue('#169') + def "should generate a call with an url path and query parameters with url containing a pattern"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))){ + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + spockTest.contains('$[?(@.property2 == \'b\')]') + spockTest.contains('$[?(@.property1 == \'a\')]') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + def "should generate test for empty body"() { given: GroovyDsl contractDsl = GroovyDsl.make { From 91f0d2878b99d2394840c293658b012e5aead9c0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Nov 2015 16:55:10 +0100 Subject: [PATCH 249/719] [#169] Query params - fixes #169 for JaxRs --- .../JaxRsClientSpockMethodBodyBuilder.groovy | 16 ++++-- .../JaxRsClientSpockMethodBuilderSpec.groovy | 51 +++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy index 91ba58e4f0..d17b8a4b84 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy @@ -1,10 +1,10 @@ package io.codearte.accurest.builder - import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.QueryParameter +import io.codearte.accurest.dsl.internal.QueryParameters @PackageScope @TypeChecked @@ -46,11 +46,19 @@ class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { protected void appendUrlPathAndQueryParameters(BlockBuilder bb) { if (request.url) { bb.addLine(".path('$request.url.serverValue')") + appendQueryParams(request.url.queryParameters, bb) } else if (request.urlPath) { bb.addLine(".path('$request.urlPath.serverValue')") - request.urlPath.queryParameters?.parameters.findAll(this.&allowedQueryParameter).each { QueryParameter param -> - bb.addLine(".queryParam('$param.name', '${resolveParamValue(param).toString()}')") - } + appendQueryParams(request.urlPath.queryParameters, bb) + } + } + + private void appendQueryParams(QueryParameters queryParameters, BlockBuilder bb) { + if (!queryParameters?.parameters) { + return + } + queryParameters.parameters.findAll(this.&allowedQueryParameter).each { QueryParameter param -> + bb.addLine(".queryParam('$param.name', '${resolveParamValue(param).toString()}')") } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index aa5a26cb5d..e93e9e5035 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -364,6 +364,57 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } + @Issue('#169') + def "should generate a call with an url path and query parameters with url containing a pattern"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))){ + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains("queryParam('limit', '10'") + spockTest.contains("queryParam('offset', '20'") + spockTest.contains("queryParam('filter', 'email'") + spockTest.contains("queryParam('sort', 'name'") + spockTest.contains("queryParam('search', '55'") + spockTest.contains("queryParam('age', '99'") + spockTest.contains("queryParam('name', 'Denis.Stepanov'") + spockTest.contains("queryParam('email', 'bob@email.com'") + spockTest.contains('$[?(@.property2 == \'b\')]') + spockTest.contains('$[?(@.property1 == \'a\')]') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + def "should generate test for empty body"() { given: GroovyDsl contractDsl = GroovyDsl.make { From f6b716bad54bc32fb80f20d9681ad8ec74f9b723 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 13 Nov 2015 17:58:21 +0100 Subject: [PATCH 250/719] [#171] Added upercase method for JaxRs, fixes #171 --- .../JaxRsClientSpockMethodBodyBuilder.groovy | 4 +-- .../JaxRsClientSpockMethodBuilderSpec.groovy | 33 +++++++++++++++++-- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy index d17b8a4b84..abf43d77fc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy @@ -66,9 +66,9 @@ class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { String method = request.method.serverValue.toString().toLowerCase() if (request.body) { String contentType = getHeader('Content-Type') ?: getRequestContentType().mimeType - bb.addLine(".method('$method', entity('$bodyAsString', '$contentType'))") + bb.addLine(".method('${method.toUpperCase()}', entity('$bodyAsString', '$contentType'))") } else { - bb.addLine(".method('$method')") + bb.addLine(".method('${method.toUpperCase()}')") } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index e93e9e5035..d8d13e124f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -450,16 +450,45 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc body "test" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains('def responseBody = (response.body.asString())') + spockTest.contains('String responseAsString = response.readEntity(String)') spockTest.contains('responseBody == "test"') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } + @Issue('#171') + def "should generate test with uppercase method name"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "get" + url "/v1/some_cool_requests/e86df6f693de4b35ae648464c5b0dc08" + } + response { + status 200 + headers { + header('Content-Type': 'application/json;charset=UTF-8') + } + body """ +{"id":"789fgh","other_data":1268} +""" + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains(".method('GET')") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + } From 7c61c550dd3243f733737035697e231f7f80ca80 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 15 Nov 2015 19:11:58 +0100 Subject: [PATCH 251/719] [#147] Made tests use random ports. Fixes #147 --- .../frauddetection/LoanApplicationService.java | 8 +++++++- .../toomuchcoding/LoanApplicationServiceSpec.groovy | 8 +++++++- .../frauddetection/LoanApplicationService.java | 8 +++++++- .../toomuchcoding/LoanApplicationServiceSpec.groovy | 8 +++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java index 82476a3a46..bf622844d6 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java @@ -21,6 +21,8 @@ public class LoanApplicationService { private final RestTemplate restTemplate; + private Integer port = 8080; + public LoanApplicationService() { this.restTemplate = new RestTemplate(); } @@ -41,7 +43,7 @@ public class LoanApplicationService { httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1); ResponseEntity response = - restTemplate.exchange("http://localhost:8080/fraudcheck", HttpMethod.PUT, + restTemplate.exchange("http://localhost:" + port + "/fraudcheck", HttpMethod.PUT, new HttpEntity<>(request, httpHeaders), FraudServiceResponse.class); @@ -59,4 +61,8 @@ public class LoanApplicationService { return new LoanApplicationResult(applicationStatus, response.getRejectionReason()); } + public void setPort(Integer port) { + this.port = port; + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy index 58d17673ce..8c30c4e8c5 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy @@ -17,13 +17,19 @@ import spock.lang.Specification @ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) class LoanApplicationServiceSpec extends Specification { + public static Integer port = org.springframework.util.SocketUtils.findAvailableTcpPort() + @ClassRule @Shared - WireMockClassRule wireMockRule = new WireMockClassRule() + WireMockClassRule wireMockRule = new WireMockClassRule(port) @Autowired LoanApplicationService sut + def setup() { + sut.port = port + } + def 'should successfully apply for loan'() { given: LoanApplication application = diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java index 82476a3a46..bf622844d6 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java @@ -21,6 +21,8 @@ public class LoanApplicationService { private final RestTemplate restTemplate; + private Integer port = 8080; + public LoanApplicationService() { this.restTemplate = new RestTemplate(); } @@ -41,7 +43,7 @@ public class LoanApplicationService { httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1); ResponseEntity response = - restTemplate.exchange("http://localhost:8080/fraudcheck", HttpMethod.PUT, + restTemplate.exchange("http://localhost:" + port + "/fraudcheck", HttpMethod.PUT, new HttpEntity<>(request, httpHeaders), FraudServiceResponse.class); @@ -59,4 +61,8 @@ public class LoanApplicationService { return new LoanApplicationResult(applicationStatus, response.getRejectionReason()); } + public void setPort(Integer port) { + this.port = port; + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy index 58d17673ce..8c30c4e8c5 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy @@ -17,13 +17,19 @@ import spock.lang.Specification @ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) class LoanApplicationServiceSpec extends Specification { + public static Integer port = org.springframework.util.SocketUtils.findAvailableTcpPort() + @ClassRule @Shared - WireMockClassRule wireMockRule = new WireMockClassRule() + WireMockClassRule wireMockRule = new WireMockClassRule(port) @Autowired LoanApplicationService sut + def setup() { + sut.port = port + } + def 'should successfully apply for loan'() { given: LoanApplication application = From 7afd45805bc58e6105f718950411441398491bd5 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 15 Nov 2015 19:51:00 +0100 Subject: [PATCH 252/719] [#76] Added underscore as valid char in filename. Fixes #76 --- .../src/main/groovy/io/codearte/accurest/TestGenerator.groovy | 2 +- .../io/codearte/accurest/plugin/BasicFunctionalSpec.groovy | 4 ++-- ...acesFromTweet.groovy => collerate_PlacesFrom_Tweet.groovy} | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/{colleratePlacesFromTweet.groovy => collerate_PlacesFrom_Tweet.groovy} (100%) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index 339def4b8c..60f1b117d6 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -59,7 +59,7 @@ class TestGenerator { if (!includedDirectoryRelativePath.isEmpty()) { List filesToClass = directoryScanner.includedFiles. grep { String includedFile -> - return normalizePath(includedFile).matches(normalizePath(includedDirectoryRelativePath + File.separator) + "[A-Za-z0-9]*\\.groovy") + return normalizePath(includedFile).matches(normalizePath(includedDirectoryRelativePath + File.separator) + "[A-Za-z0-9_]*\\.groovy") } .collect { return new File(configProperties.contractsDslDir, it) 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 a54d20308e..2c1a485f31 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 @@ -8,8 +8,8 @@ import spock.lang.Stepwise class BasicFunctionalSpec extends IntegrationSpec { private static final String GENERATED_TEST = "build//generated-sources//accurest//accurest//PairIdSpec.groovy" - private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//pairId//colleratePlacesFromTweet.json" - private static final String GROOVY_DSL_CONTRACT = "repository//mappings//com//ofg//twitter-places-analyzer//pairId//colleratePlacesFromTweet.groovy" + private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//pairId//collerate_PlacesFrom_Tweet.json" + private static final String GROOVY_DSL_CONTRACT = "repository//mappings//com//ofg//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.groovy" private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.PairIdSpec.xml" void setup() { 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/collerate_PlacesFrom_Tweet.groovy similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/colleratePlacesFromTweet.groovy rename to accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy From d2431f4501c1391627d17b5f0305a3cfe0127186 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 15 Nov 2015 20:09:53 +0100 Subject: [PATCH 253/719] [#147] Converted big ints to small ints --- .../toomuchcoding/frauddetection/LoanApplicationService.java | 4 ++-- .../blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy | 2 +- .../toomuchcoding/frauddetection/LoanApplicationService.java | 4 ++-- .../blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java index bf622844d6..a2d8ce1e74 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java @@ -21,7 +21,7 @@ public class LoanApplicationService { private final RestTemplate restTemplate; - private Integer port = 8080; + private int port = 8080; public LoanApplicationService() { this.restTemplate = new RestTemplate(); @@ -61,7 +61,7 @@ public class LoanApplicationService { return new LoanApplicationResult(applicationStatus, response.getRejectionReason()); } - public void setPort(Integer port) { + public void setPort(int port) { this.port = port; } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy index 8c30c4e8c5..21ee7a4d39 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy @@ -17,7 +17,7 @@ import spock.lang.Specification @ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) class LoanApplicationServiceSpec extends Specification { - public static Integer port = org.springframework.util.SocketUtils.findAvailableTcpPort() + public static int port = org.springframework.util.SocketUtils.findAvailableTcpPort() @ClassRule @Shared diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java index bf622844d6..a2d8ce1e74 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java @@ -21,7 +21,7 @@ public class LoanApplicationService { private final RestTemplate restTemplate; - private Integer port = 8080; + private int port = 8080; public LoanApplicationService() { this.restTemplate = new RestTemplate(); @@ -61,7 +61,7 @@ public class LoanApplicationService { return new LoanApplicationResult(applicationStatus, response.getRejectionReason()); } - public void setPort(Integer port) { + public void setPort(int port) { this.port = port; } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy index 8c30c4e8c5..21ee7a4d39 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy @@ -17,7 +17,7 @@ import spock.lang.Specification @ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) class LoanApplicationServiceSpec extends Specification { - public static Integer port = org.springframework.util.SocketUtils.findAvailableTcpPort() + public static int port = org.springframework.util.SocketUtils.findAvailableTcpPort() @ClassRule @Shared From d8455cf6ddcc78a7b592a2e2fa4ef1be4f73cf1f Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 15 Nov 2015 20:12:42 +0100 Subject: [PATCH 254/719] Release version: 0.9.10 [ci skip] From d4873122508cd59d074e512674115d59aed1975d Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Fri, 20 Nov 2015 12:34:54 +0100 Subject: [PATCH 255/719] Fixes #176 - replace dash with underscore when building package name from directory --- .../groovy/io/codearte/accurest/FileSaver.groovy | 5 ++--- .../io/codearte/accurest/TestGenerator.groovy | 15 +++++++-------- .../io/codearte/accurest/util/NamesUtil.groovy | 6 +----- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy index a77aca416f..5c3aa07e76 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy @@ -3,7 +3,6 @@ package io.codearte.accurest import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import io.codearte.accurest.config.TestFramework -import io.codearte.accurest.util.NamesUtil import java.nio.file.Files import java.nio.file.Path @@ -24,9 +23,9 @@ class FileSaver { this.framework = framework } - void saveClassFile(String fileName, String packageName, byte[] classBytes) { + void saveClassFile(String fileName, String includedDirectoryRelativePath, byte[] classBytes) { - Path testBaseDir = Paths.get(targetDirectory.absolutePath, NamesUtil.packageToDirectory(packageName)) + Path testBaseDir = Paths.get(targetDirectory.absolutePath, includedDirectoryRelativePath) Files.createDirectories(testBaseDir) Path classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + framework.classExtension).toAbsolutePath() log.info("Creating new class file [$classPath]") diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index 60f1b117d6..d01f5edb9f 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest + import groovy.transform.PackageScope import io.codearte.accurest.config.AccurestConfigProperties import org.apache.commons.io.FilenameUtils @@ -7,9 +8,7 @@ import org.codehaus.plexus.util.DirectoryScanner import java.nio.charset.StandardCharsets import java.util.concurrent.atomic.AtomicInteger -import static io.codearte.accurest.util.NamesUtil.afterLast -import static io.codearte.accurest.util.NamesUtil.beforeLast -import static io.codearte.accurest.util.NamesUtil.directoryToPackage +import static io.codearte.accurest.util.NamesUtil.* /** * @author Jakub Kubrynski @@ -45,17 +44,17 @@ class TestGenerator { } @PackageScope - void generateTestClasses(final String packageName) { + void generateTestClasses(final String basePackageName) { directoryScanner.scan() directoryScanner.getIncludedDirectories() .each { String includedDirectoryRelativePath -> - processIncludedDirectory(includedDirectoryRelativePath, packageName) + processIncludedDirectory(includedDirectoryRelativePath, basePackageName) } } private void processIncludedDirectory( - final String includedDirectoryRelativePath, final String packageNameForClass) { + final String includedDirectoryRelativePath, final String basePackageNameForClass) { if (!includedDirectoryRelativePath.isEmpty()) { List filesToClass = directoryScanner.includedFiles. grep { String includedFile -> @@ -66,9 +65,9 @@ class TestGenerator { } if (filesToClass.size()) { def className = afterLast(includedDirectoryRelativePath, File.separator) + configProperties.targetFramework.classNameSuffix - def packageName = buildPackage(packageNameForClass, includedDirectoryRelativePath) + def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath) def classBytes = generator.buildClass(filesToClass, className, packageName).getBytes(StandardCharsets.UTF_8) - saver.saveClassFile(className, packageName, classBytes) + saver.saveClassFile(className, includedDirectoryRelativePath, classBytes) counter.incrementAndGet() } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy index 23e8c54479..8417beb4c3 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy @@ -46,11 +46,7 @@ class NamesUtil { return string } - static String packageToDirectory(String packageName) { - return packageName.replace('.' as char, File.separatorChar) - } - static String directoryToPackage(String directory) { - return directory.replace(File.separator, '.') + return directory.replace(File.separator, '.').replace('-', '_') } } From 41ffeaf9a93701fef71aee9f9c2f064931331394 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Fri, 20 Nov 2015 13:33:49 +0100 Subject: [PATCH 256/719] Fixes #176 - replace dash with underscore when building package name from directory - fix tests --- .../io/codearte/accurest/FileSaver.groovy | 7 ++++-- .../io/codearte/accurest/TestGenerator.groovy | 6 ++--- .../codearte/accurest/util/NamesUtil.groovy | 22 +++++++++++-------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy index 5c3aa07e76..2a9c730787 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy @@ -9,7 +9,9 @@ import java.nio.file.Path import java.nio.file.Paths import java.nio.file.StandardOpenOption +import static io.codearte.accurest.util.NamesUtil.beforeLast import static io.codearte.accurest.util.NamesUtil.capitalize +import static io.codearte.accurest.util.NamesUtil.packageToDirectory @CompileStatic @Slf4j @@ -23,9 +25,10 @@ class FileSaver { this.framework = framework } - void saveClassFile(String fileName, String includedDirectoryRelativePath, byte[] classBytes) { + void saveClassFile(String fileName, String basePackageClass, String includedDirectoryRelativePath, byte[] classBytes) { - Path testBaseDir = Paths.get(targetDirectory.absolutePath, includedDirectoryRelativePath) + Path testBaseDir = Paths.get(targetDirectory.absolutePath, packageToDirectory(basePackageClass), + beforeLast(includedDirectoryRelativePath, File.separator)) Files.createDirectories(testBaseDir) Path classPath = Paths.get(testBaseDir.toString(), capitalize(fileName) + framework.classExtension).toAbsolutePath() log.info("Creating new class file [$classPath]") diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index d01f5edb9f..65e96b8d8c 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -67,7 +67,7 @@ class TestGenerator { def className = afterLast(includedDirectoryRelativePath, File.separator) + configProperties.targetFramework.classNameSuffix def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath) def classBytes = generator.buildClass(filesToClass, className, packageName).getBytes(StandardCharsets.UTF_8) - saver.saveClassFile(className, includedDirectoryRelativePath, classBytes) + saver.saveClassFile(className, basePackageNameForClass, includedDirectoryRelativePath, classBytes) counter.incrementAndGet() } } @@ -75,8 +75,8 @@ class TestGenerator { private static String buildPackage(final String packageNameForClass, final String includedDirectoryRelativePath) { String directory = beforeLast(includedDirectoryRelativePath, File.separator) - return !directory.empty ? "$packageNameForClass.${directoryToPackage(directory)}" : packageNameForClass - } + return !directory.empty ? "$packageNameForClass.${directoryToPackage(directory)}" : packageNameForClass + } private static String normalizePath(String path) { return FilenameUtils.separatorsToUnix(path) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy index 8417beb4c3..713270ce06 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy @@ -5,12 +5,12 @@ package io.codearte.accurest.util */ class NamesUtil { - static String beforeLast(String string, String separator) { - if (string?.indexOf(separator) > -1) { - return string.substring(0, string.lastIndexOf(separator)) - } - return '' - } + static String beforeLast(String string, String separator) { + if (string?.indexOf(separator) > -1) { + return string.substring(0, string.lastIndexOf(separator)) + } + return '' + } static String afterLast(String string, String separator) { if (string?.indexOf(separator) > -1) { @@ -46,7 +46,11 @@ class NamesUtil { return string } - static String directoryToPackage(String directory) { - return directory.replace(File.separator, '.').replace('-', '_') - } + static String packageToDirectory(String packageName) { + return packageName.replace('.' as char, File.separatorChar) + } + + static String directoryToPackage(String directory) { + return directory.replace(File.separator, '.') + } } From 88c9400868b2c4a03e5f1b8fe366ffc4fd1d6fa7 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 23 Nov 2015 16:33:04 +0100 Subject: [PATCH 257/719] Fixes #176 - fix incorrect merge --- .../src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy index 713270ce06..1986d45a9a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy @@ -51,6 +51,6 @@ class NamesUtil { } static String directoryToPackage(String directory) { - return directory.replace(File.separator, '.') + return directory.replace(File.separator, '.').replace('-', '_') } } From 093b28b79df6a944de3f635334d3e9bd5c5c7306 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 23 Nov 2015 22:54:31 +0100 Subject: [PATCH 258/719] Fixes #176 - change also directory name --- .../main/groovy/io/codearte/accurest/TestGenerator.groovy | 4 ++-- .../main/groovy/io/codearte/accurest/util/NamesUtil.groovy | 6 +++++- .../io/codearte/accurest/plugin/BasicFunctionalSpec.groovy | 6 +++--- .../test/resources/functionalTest/bootSimple/build.gradle | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index 65e96b8d8c..990eada6f8 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -67,7 +67,7 @@ class TestGenerator { def className = afterLast(includedDirectoryRelativePath, File.separator) + configProperties.targetFramework.classNameSuffix def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath) def classBytes = generator.buildClass(filesToClass, className, packageName).getBytes(StandardCharsets.UTF_8) - saver.saveClassFile(className, basePackageNameForClass, includedDirectoryRelativePath, classBytes) + saver.saveClassFile(className, basePackageNameForClass, convertIllegalPackageChars(includedDirectoryRelativePath), classBytes) counter.incrementAndGet() } } @@ -75,7 +75,7 @@ class TestGenerator { private static String buildPackage(final String packageNameForClass, final String includedDirectoryRelativePath) { String directory = beforeLast(includedDirectoryRelativePath, File.separator) - return !directory.empty ? "$packageNameForClass.${directoryToPackage(directory)}" : packageNameForClass + return !directory.empty ? "$packageNameForClass.${directoryToPackage(convertIllegalPackageChars(directory))}" : packageNameForClass } private static String normalizePath(String path) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy index 1986d45a9a..8e4d9037ee 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy @@ -51,6 +51,10 @@ class NamesUtil { } static String directoryToPackage(String directory) { - return directory.replace(File.separator, '.').replace('-', '_') + return directory.replace(File.separator, '.') + } + + static String convertIllegalPackageChars(String packageName) { + return packageName.replace('-', '_') } } 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 2c1a485f31..7457760cf9 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 @@ -7,10 +7,10 @@ import spock.lang.Stepwise @Stepwise class BasicFunctionalSpec extends IntegrationSpec { - private static final String GENERATED_TEST = "build//generated-sources//accurest//accurest//PairIdSpec.groovy" - private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//pairId//collerate_PlacesFrom_Tweet.json" + private static final String GENERATED_TEST = "build//generated-sources//accurest//accurest//twitter_places_analyzer//PairIdSpec.groovy" + private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.json" private static final String GROOVY_DSL_CONTRACT = "repository//mappings//com//ofg//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.groovy" - private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.PairIdSpec.xml" + private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.twitter_places_analyzer.PairIdSpec.xml" void setup() { copyResources("functionalTest/bootSimple", "") diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index e7565e3efe..c6c08c4b0b 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -8,7 +8,7 @@ apply plugin: 'groovy' apply plugin: 'accurest' ext { - contractsDir = file("${project.rootDir}/repository/mappings/com/ofg/twitter-places-analyzer") + contractsDir = file("${project.rootDir}/repository/mappings/com/ofg") wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'repository/mappings/') } From 86118095a7821b1223d17efb229648f31e26d14e Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 23 Nov 2015 23:31:16 +0100 Subject: [PATCH 259/719] Fixes #14 - class name suffix is configurable via plugin settings --- .../main/groovy/io/codearte/accurest/TestGenerator.groovy | 6 +++++- .../accurest/config/AccurestConfigProperties.groovy | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index 990eada6f8..bcd7ac3350 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -64,7 +64,7 @@ class TestGenerator { return new File(configProperties.contractsDslDir, it) } if (filesToClass.size()) { - def className = afterLast(includedDirectoryRelativePath, File.separator) + configProperties.targetFramework.classNameSuffix + def className = afterLast(includedDirectoryRelativePath, File.separator) + resolveNameSuffix() def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath) def classBytes = generator.buildClass(filesToClass, className, packageName).getBytes(StandardCharsets.UTF_8) saver.saveClassFile(className, basePackageNameForClass, convertIllegalPackageChars(includedDirectoryRelativePath), classBytes) @@ -73,6 +73,10 @@ class TestGenerator { } } + private String resolveNameSuffix() { + return configProperties.nameSuffixForTests ?: configProperties.targetFramework.classNameSuffix + } + private static String buildPackage(final String packageNameForClass, final String includedDirectoryRelativePath) { String directory = beforeLast(includedDirectoryRelativePath, File.separator) return !directory.empty ? "$packageNameForClass.${directoryToPackage(convertIllegalPackageChars(directory))}" : packageNameForClass diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy index 9d69c3ee8e..cc94fb39e9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy @@ -7,6 +7,7 @@ class AccurestConfigProperties { TestMode testMode = TestMode.MOCKMVC String basePackageForTests String baseClassForTests + String nameSuffixForTests String ruleClassForTests List ignoredFiles = [] String[] imports = [] From 4823658b24514c612e5d407e84cd9d2b835d24b0 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 24 Nov 2015 13:09:00 +0100 Subject: [PATCH 260/719] Release version: 0.9.11 [ci skip] From 545abbb9b55227229471e2ec9df55e0c51b896a6 Mon Sep 17 00:00:00 2001 From: Milosz Rembisz Date: Wed, 25 Nov 2015 10:31:47 +0100 Subject: [PATCH 261/719] modified generation of test method body to allow for multiline body requests --- .../MockMvcSpockMethodBodyBuilder.groovy | 2 +- .../MockMvcSpockMethodBuilderSpec.groovy | 32 +++++++++++++++++-- build.gradle | 1 + 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index 36191035ef..c913d97acf 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -26,7 +26,7 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { bb.addLine(".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')") } if (request.body) { - bb.addLine(".body('$bodyAsString')") + bb.addLine(".body('''$bodyAsString''')") } bb.unindent() } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index a762d57045..7a87a965d0 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier +import org.codehaus.groovy.control.CompilationFailedException import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll @@ -91,7 +92,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains(".body('{\"items\":[\"HOP\"]}')") + blockBuilder.toString().contains(".body('''{\"items\":[\"HOP\"]}''')") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @@ -116,7 +117,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains(".body('property1=VAL1')") + blockBuilder.toString().contains(".body('''property1=VAL1''')") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @@ -399,7 +400,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains(".body('')") + spockTest.contains(".body('''''')") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } @@ -814,4 +815,29 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu !spockTest.contains("\\u041f") } + @Issue('177') + def "should generate proper test code when having multiline body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multiline" + body('''hello, +World.''') + } + response { + status 200 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def spockTest = blockBuilder.toString() + new GroovyShell(this.class.classLoader).evaluate("""import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.* +$spockTest""") + then: + notThrown(CompilationFailedException) + } + } diff --git a/build.gradle b/build.gradle index 42d265f044..4b59672fc8 100644 --- a/build.gradle +++ b/build.gradle @@ -74,6 +74,7 @@ project(':accurest-core') { compile "com.github.tomakehurst:wiremock:$wiremockVersion" testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' + testCompile 'com.jayway.restassured:spring-mock-mvc:2.5.0' testCompile project(':accurest-testing-utils') } From 7bffbf6c7293570e991fc7657ccf778bb4bf0b4b Mon Sep 17 00:00:00 2001 From: Milosz Rembisz Date: Wed, 25 Nov 2015 13:10:08 +0100 Subject: [PATCH 262/719] removed test with GroovyShell.evaluate in favor of simple string checking --- .../accurest/builder/MockMvcSpockMethodBuilderSpec.groovy | 8 ++------ build.gradle | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 7a87a965d0..56da904a8e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -1,15 +1,12 @@ package io.codearte.accurest.builder - import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier -import org.codehaus.groovy.control.CompilationFailedException import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll import java.util.regex.Pattern - /** * @author Jakub Kubrynski */ @@ -834,10 +831,9 @@ World.''') when: builder.given(blockBuilder) def spockTest = blockBuilder.toString() - new GroovyShell(this.class.classLoader).evaluate("""import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.* -$spockTest""") then: - notThrown(CompilationFailedException) + spockTest.contains("""'''hello, +World.'''""") } } diff --git a/build.gradle b/build.gradle index 4b59672fc8..42d265f044 100644 --- a/build.gradle +++ b/build.gradle @@ -74,7 +74,6 @@ project(':accurest-core') { compile "com.github.tomakehurst:wiremock:$wiremockVersion" testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - testCompile 'com.jayway.restassured:spring-mock-mvc:2.5.0' testCompile project(':accurest-testing-utils') } From ced19c2c8a918116349dedaa164aba21147ee428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Fejzer?= Date: Mon, 30 Nov 2015 15:53:19 +0100 Subject: [PATCH 263/719] Add Multipart and NamedProperty --- .../MockMvcSpockMethodBodyBuilder.groovy | 6 ++- .../builder/SpockMethodBodyBuilder.groovy | 12 ++++++ .../accurest/dsl/internal/Common.groovy | 4 ++ .../accurest/dsl/internal/Multipart.groovy | 41 +++++++++++++++++++ .../dsl/internal/NamedProperty.groovy | 19 +++++++++ .../accurest/dsl/internal/Request.groovy | 22 ++++++++++ .../MockMvcSpockMethodBuilderSpec.groovy | 25 +++++++++++ 7 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index c913d97acf..a80ce77f89 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -1,6 +1,5 @@ package io.codearte.accurest.builder -import java.util.regex.Pattern import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode @@ -11,6 +10,8 @@ import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.dsl.internal.Url import io.codearte.accurest.util.MapConverter +import java.util.regex.Pattern + @PackageScope @TypeChecked class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { @@ -28,6 +29,9 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { if (request.body) { bb.addLine(".body('''$bodyAsString''')") } + if (request.multipart) { + bb.addLine(".multiPart('''$fileAsString''', '''$filenameAsString''', '''$fileContentAsString'''.bytes)") + } bb.unindent() } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 192ec4a2ab..ddd905e711 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -122,6 +122,18 @@ abstract class SpockMethodBodyBuilder { return trimRepeatedQuotes(json) } + protected String getFileContentAsString() { + return request.multipart.serverValue //TODO replace to working extraction + } + + protected String getFilenameAsString() { + return request.multipart.serverValue //TODO replace to working extraction + } + + protected String getFileAsString() { + return request.multipart.serverValue //TODO replace to working extraction + } + protected String convertUnicodeEscapes(String json) { return StringEscapeUtils.unescapeJavaScript(json) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index c96ff4b2d4..89ab8252d2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -48,6 +48,10 @@ class Common { return property } + NamedProperty named(DslProperty name, DslProperty value){ + return new NamedProperty(name, value) + } + DslProperty value(ClientDslProperty client, ServerDslProperty server) { assertThatSidesMatch(client.clientValue, server.serverValue) return new DslProperty(client.clientValue, server.serverValue) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy new file mode 100644 index 0000000000..b11bd85db2 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy @@ -0,0 +1,41 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +@CompileStatic +class Multipart extends DslProperty { + + Multipart(Map multipart) { + super(extractValue(multipart, { DslProperty p -> p.clientValue}), extractValue(multipart, {DslProperty p -> p.serverValue})) + } + + private static Map extractValue(Map multipart, Closure valueProvider) { + multipart.collectEntries { Map.Entry entry -> + [(entry.key): valueProvider(entry.value)] + } as Map + } + + Multipart(List multipartAsList) { + super(multipartAsList.collect { DslProperty p -> p.clientValue }, multipartAsList.collect { DslProperty p -> p.serverValue }) + } + + Multipart(Object multipartAsValue) { + this("${multipartAsValue}") + } + + Multipart(GString multipartAsValue) { + super(multipartAsValue, multipartAsValue) + } + + Multipart(DslProperty multipartAsValue) { + super(multipartAsValue.clientValue, multipartAsValue.serverValue) + } + + Multipart(MatchingStrategy matchingStrategy) { + super(matchingStrategy, matchingStrategy) + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy new file mode 100644 index 0000000000..b02a6a2c3f --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy @@ -0,0 +1,19 @@ +package io.codearte.accurest.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +@CompileStatic +class NamedProperty { + + DslProperty name + DslProperty value + + NamedProperty(DslProperty name, DslProperty value) { + this.name = name + this.value = value + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 9adf7048a8..0ddff73bdc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -14,6 +14,7 @@ class Request extends Common { UrlPath urlPath Headers headers Body body + Multipart multipart Request() { } @@ -24,6 +25,7 @@ class Request extends Common { this.urlPath = request.urlPath this.headers = request.headers this.body = request.body + this.multipart = request.multipart } void method(String method) { @@ -100,6 +102,26 @@ class Request extends Common { return body } + void multipart(Map body) { + this.multipart = new Multipart(convertObjectsToDslProperties(body)) + } + + void multipart(List multipartAsList) { + this.multipart = new Multipart(convertObjectsToDslProperties(multipartAsList)) + } + + void multipart(DslProperty dslProperty) { + this.multipart = new Multipart(dslProperty) + } + + void multipart(Object multipartAsValue) { + this.multipart = new Multipart(multipartAsValue) + } + + Multipart getMultipart() { + return multipart + } + MatchingStrategy equalTo(Object value) { return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO) } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 56da904a8e..d98b2b1e64 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -836,4 +836,29 @@ World.''') World.'''""") } + def "should generate proper test code when having multipart parameters"(){ + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + multipart( + formParameter: value(client(regex('".+"')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named(value(client(regex('.+')), server('filename.csv')), value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('.multiPart') + } + } From c481572c32a4d75731182304fca0f1291c212f74 Mon Sep 17 00:00:00 2001 From: Milosz Rembisz Date: Tue, 1 Dec 2015 10:51:58 +0100 Subject: [PATCH 264/719] generating client stub from multipart dsl --- .../dsl/WireMockRequestStubStrategy.groovy | 32 +++++++++++-- .../accurest/dsl/internal/Common.groovy | 4 ++ .../dsl/internal/RegexPatterns.groovy | 8 ++++ .../MockMvcSpockMethodBuilderSpec.groovy | 30 ++++++++++++ .../accurest/dsl/WireMockGroovyDslSpec.groovy | 46 +++++++++++++++++++ 5 files changed, 117 insertions(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index cf69737c95..03304bdbc3 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -6,16 +6,25 @@ import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode -import io.codearte.accurest.dsl.internal.* +import io.codearte.accurest.dsl.internal.Body +import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.dsl.internal.MatchingStrategy +import io.codearte.accurest.dsl.internal.NamedProperty +import io.codearte.accurest.dsl.internal.QueryParameters +import io.codearte.accurest.dsl.internal.RegexPatterns +import io.codearte.accurest.dsl.internal.Request import io.codearte.accurest.util.ContentType import io.codearte.accurest.util.ContentUtils -import io.codearte.accurest.util.JsonToJsonPathsConverter import io.codearte.accurest.util.JsonPaths +import io.codearte.accurest.util.JsonToJsonPathsConverter import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.* +import static io.codearte.accurest.util.ContentUtils.getEqualsTypeFromContentType +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromMatchingStrategy import static io.codearte.accurest.util.RegexpBuilders.buildGStringRegexpForStubSide import static io.codearte.accurest.util.RegexpBuilders.buildJSONRegexpMatch @@ -37,6 +46,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { appendUrl(requestPattern) appendQueryParameters(requestPattern) appendBody(requestPattern) + appendMultipart(requestPattern) return requestPattern } @@ -69,6 +79,22 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { requestPattern.bodyPatterns = [convertToValuePattern(getMatchingStrategy(request.body.clientValue))] } } + + private void appendMultipart(RequestPattern requestPattern) { + if (!request.multipart) { + return + } + + if (request.multipart.clientValue instanceof Map) { + List multipartPatterns = (request.multipart.clientValue as Map).collect { + (it.value instanceof NamedProperty + ? ValuePattern.matches(RegexPatterns.multipartFile(it.key, (it.value as NamedProperty).name.clientValue, (it.value as NamedProperty).value.clientValue)) + : ValuePattern.matches(RegexPatterns.multipartParam(it.key, it.value)) ) + } + + requestPattern.bodyPatterns ? requestPattern.bodyPatterns.addAll(multipartPatterns) : (requestPattern.bodyPatterns = multipartPatterns) + } + } private void appendHeaders(RequestPattern requestPattern) { if(!request.headers) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index 89ab8252d2..cdf6d3db1f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -52,6 +52,10 @@ class Common { return new NamedProperty(name, value) } + NamedProperty named(Map namedMap){ + return new NamedProperty(namedMap.get('name'), namedMap.get('content')) + } + DslProperty value(ClientDslProperty client, ServerDslProperty server) { assertThatSidesMatch(client.clientValue, server.serverValue) return new DslProperty(client.clientValue, server.serverValue) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy index 3daa34ec90..1c18226fd9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy @@ -43,4 +43,12 @@ class RegexPatterns { String url() { return URL.pattern() } + + static String multipartParam(Object name, Object value) { + return ".*--(.*)\r\nContent-Disposition: form-data; name=\"$name\"\r\n(Content-Type: .*\r\n)?(Content-Length: \\d+\r\n)?\r\n$value\r\n--\\1.*" + } + + static String multipartFile(Object name, Object filename, Object content) { + return ".*--(.*)\r\nContent-Disposition: form-data; name=\"$name\"; filename=\"$filename\"\r\n(Content-Type: .*\r\n)?(Content-Length: \\d+\r\n)?\r\n$content\r\n--\\1.*"; + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index d98b2b1e64..195886ce0e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.builder + import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier @@ -7,6 +8,7 @@ import spock.lang.Specification import spock.lang.Unroll import java.util.regex.Pattern + /** * @author Jakub Kubrynski */ @@ -861,4 +863,32 @@ World.'''""") spockTest.contains('.multiPart') } + def "should generate proper test code when having multipart parameters with named as map"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + multipart( + formParameter: value(client(regex('".+"')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named( + name: value(client(regex('.+')), server('filename.csv')), + content: value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('.multiPart') + } + + } 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 7502ada771..866a451f47 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 @@ -1398,4 +1398,50 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie String toWireMockClientJsonStub(groovyDsl) { new WireMockStubStrategy(groovyDsl).toWireMockClientStub() } + + @Issue('180') + @Unroll + def 'should generate stub with multipart parameters'() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + multipart( + formParameter: value(client(regex('".+"')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named( + name: value(client(regex('.+')), server('filename.csv')), + content: value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + when: + String wireMockStub = new WireMockStubStrategy(contractDsl).toWireMockClientStub() + then: + println wireMockStub + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "url" : "/multipart", + "method" : "PUT", + "bodyPatterns" : [ { + "matches" : ".*--(.*)\\r\\nContent-Disposition: form-data; name=\\"formParameter\\"\\r\\n(Content-Type: .*\\r\\n)?(Content-Length: \\\\d+\\r\\n)?\\r\\n\\".+\\"\\r\\n--\\\\1.*" + }, { + "matches" : ".*--(.*)\\r\\nContent-Disposition: form-data; name=\\"someBooleanParameter\\"\\r\\n(Content-Type: .*\\r\\n)?(Content-Length: \\\\d+\\r\\n)?\\r\\n(true|false)\\r\\n--\\\\1.*" + }, { + "matches" : ".*--(.*)\\r\\nContent-Disposition: form-data; name=\\"file\\"; filename=\\".+\\"\\r\\n(Content-Type: .*\\r\\n)?(Content-Length: \\\\d+\\r\\n)?\\r\\n.+\\r\\n--\\\\1.*" + } ] + }, + "response" : { + "status" : 200 + } + } + '''), wireMockStub) + and: + stubMappingIsValidWireMockStub(wireMockStub) + } } From 683fb9b732a43d558c1a3ffd24c94c31a0055217 Mon Sep 17 00:00:00 2001 From: Wiktor Szwechowicz Date: Tue, 1 Dec 2015 11:38:00 +0100 Subject: [PATCH 265/719] Add support for multipart on server side --- .../builder/MockMvcSpockMethodBodyBuilder.groovy | 2 +- .../builder/SpockMethodBodyBuilder.groovy | 15 +++++++-------- .../io/codearte/accurest/util/ContentUtils.groovy | 5 +++++ .../builder/MockMvcSpockMethodBuilderSpec.groovy | 12 ++++++++++-- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index a80ce77f89..8e8b7a9f4b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -30,7 +30,7 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { bb.addLine(".body('''$bodyAsString''')") } if (request.multipart) { - bb.addLine(".multiPart('''$fileAsString''', '''$filenameAsString''', '''$fileContentAsString'''.bytes)") + multipartParameters.each { entry -> bb.addLine(getMultipartParameterLine(entry)) } } bb.unindent() } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index ddd905e711..8bbd5a0a07 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -122,16 +122,15 @@ abstract class SpockMethodBodyBuilder { return trimRepeatedQuotes(json) } - protected String getFileContentAsString() { - return request.multipart.serverValue //TODO replace to working extraction + protected Map getMultipartParameters() { + return (Map)request.multipart.serverValue } - protected String getFilenameAsString() { - return request.multipart.serverValue //TODO replace to working extraction - } - - protected String getFileAsString() { - return request.multipart.serverValue //TODO replace to working extraction + protected String getMultipartParameterLine(Map.Entry parameter) { + if (parameter.value instanceof NamedProperty) { + return ".multiPart(${getMultipartFileParameterContent(parameter.key, (NamedProperty) parameter.value)})" + } + return ".param('$parameter.key', '$parameter.value')" } protected String convertUnicodeEscapes(String json) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 1b370b7126..e73990d9f4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -8,6 +8,7 @@ import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Headers import io.codearte.accurest.dsl.internal.MatchingStrategy +import io.codearte.accurest.dsl.internal.NamedProperty import io.codearte.accurest.dsl.internal.OptionalProperty import org.codehaus.groovy.runtime.GStringImpl @@ -320,4 +321,8 @@ class ContentUtils { return ContentType.UNKNOWN } + static String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) { + return "'$propertyName', '$propertyValue.name.serverValue', '$propertyValue.value.serverValue'.bytes" + } + } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 195886ce0e..f5217c6266 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -838,14 +838,18 @@ World.''') World.'''""") } + @Issue('180') def "should generate proper test code when having multipart parameters"(){ given: GroovyDsl contractDsl = GroovyDsl.make { request { method "PUT" url "/multipart" + headers { + header('content-type', 'multipart/form-data;boundary=AaB03x') + } multipart( - formParameter: value(client(regex('".+"')), server('"formParameterValue"')), + formParameter: value(client(regex('.+')), server('"formParameterValue"')), someBooleanParameter: value(client(regex('(true|false)')), server('true')), file: named(value(client(regex('.+')), server('filename.csv')), value(client(regex('.+')), server('file content'))) ) @@ -860,9 +864,13 @@ World.'''""") builder.given(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains('.multiPart') + spockTest.contains("""'content-type', 'multipart/form-data;boundary=AaB03x'""") + spockTest.contains(""".param('formParameter', '"formParameterValue"'""") + spockTest.contains(""".param('someBooleanParameter', 'true')""") + spockTest.contains(""".multiPart('file', 'filename.csv', 'file content'.bytes)""") } + @Issue('180') def "should generate proper test code when having multipart parameters with named as map"() { given: GroovyDsl contractDsl = GroovyDsl.make { From 61e435e543ee747400138decfa35ad3de6ed03c1 Mon Sep 17 00:00:00 2001 From: Milosz Rembisz Date: Wed, 2 Dec 2015 12:56:51 +0100 Subject: [PATCH 266/719] review fixes --- .../accurest/builder/MockMvcSpockMethodBodyBuilder.groovy | 2 +- .../codearte/accurest/builder/SpockMethodBodyBuilder.groovy | 2 +- .../groovy/io/codearte/accurest/dsl/internal/Common.groovy | 2 +- .../io/codearte/accurest/dsl/internal/Multipart.groovy | 2 +- .../io/codearte/accurest/dsl/internal/NamedProperty.groovy | 6 ++++++ .../groovy/io/codearte/accurest/dsl/internal/Request.groovy | 4 ---- 6 files changed, 10 insertions(+), 8 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index 8e8b7a9f4b..64cf5e4afc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -30,7 +30,7 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { bb.addLine(".body('''$bodyAsString''')") } if (request.multipart) { - multipartParameters.each { entry -> bb.addLine(getMultipartParameterLine(entry)) } + multipartParameters?.each { Map.Entry entry -> bb.addLine(getMultipartParameterLine(entry)) } } bb.unindent() } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 8bbd5a0a07..ecff2bc043 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -123,7 +123,7 @@ abstract class SpockMethodBodyBuilder { } protected Map getMultipartParameters() { - return (Map)request.multipart.serverValue + return (Map)request?.multipart?.serverValue } protected String getMultipartParameterLine(Map.Entry parameter) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy index cdf6d3db1f..a6d86e080b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy @@ -53,7 +53,7 @@ class Common { } NamedProperty named(Map namedMap){ - return new NamedProperty(namedMap.get('name'), namedMap.get('content')) + return new NamedProperty(namedMap) } DslProperty value(ClientDslProperty client, ServerDslProperty server) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy index b11bd85db2..1ebc06e1e7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy @@ -14,7 +14,7 @@ class Multipart extends DslProperty { } private static Map extractValue(Map multipart, Closure valueProvider) { - multipart.collectEntries { Map.Entry entry -> + return multipart.collectEntries { Map.Entry entry -> [(entry.key): valueProvider(entry.value)] } as Map } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy index b02a6a2c3f..70c6d30879 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy @@ -9,6 +9,8 @@ import groovy.transform.ToString @CompileStatic class NamedProperty { + private static final String NAME = 'name' + private static final String CONTENT = 'content' DslProperty name DslProperty value @@ -16,4 +18,8 @@ class NamedProperty { this.name = name this.value = value } + + NamedProperty(Map namedMap) { + this(namedMap?.get(NAME), namedMap?.get(CONTENT)) + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy index 0ddff73bdc..54d57e8c53 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy @@ -118,10 +118,6 @@ class Request extends Common { this.multipart = new Multipart(multipartAsValue) } - Multipart getMultipart() { - return multipart - } - MatchingStrategy equalTo(Object value) { return new MatchingStrategy(value, MatchingStrategy.Type.EQUAL_TO) } From 6ffa90acddcb1e5df408dd1caa5c9242436973aa Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 2 Dec 2015 14:17:52 +0100 Subject: [PATCH 267/719] Release version: 0.9.12 [ci skip] From 00d347f812d78105f34c0e2570a5659f578cc3d8 Mon Sep 17 00:00:00 2001 From: mchmielarz Date: Wed, 16 Dec 2015 23:34:17 +0100 Subject: [PATCH 268/719] Conversion of a map with integer as keys added. --- .../util/JsonToJsonPathsConverter.groovy | 2 +- .../MockMvcSpockMethodBuilderSpec.groovy | 29 +++++++++++++++++++ .../util/JsonToJsonPathsConverterSpec.groovy | 15 ++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 319e7ab660..0bf9cc2ff5 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -93,7 +93,7 @@ class JsonToJsonPathsConverter { private static Map convertWithKey(Class parentType, String parentKey, Map map, Closure closureToExecute) { return map.collectEntries { - String entrykey, value -> + Object entrykey, value -> [entrykey, traverseRecursively(parentType, "${parentKey}.${entrykey}", value, closureToExecute)] } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index f5217c6266..efdb49fbc0 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -121,6 +121,35 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } + @Issue("185") + def "should generate assertions for a response body containing map with integers as keys"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property: [ + 14: 0.0, + 7 : 0.0 + ] + ) + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("\$.property[?(@.7 == 0.0)]") + blockBuilder.toString().contains("\$.property[?(@.14 == 0.0)]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + def "should generate assertions for array in response body"() { given: GroovyDsl contractDsl = GroovyDsl.make { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index 5348c77fd5..90b0c0d2da 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -119,6 +119,21 @@ class JsonToJsonPathsConverterSpec extends Specification { assertThatJsonPathsInMapAreValid(json, pathAndValues) } + def "should convert numbers map"() { + given: + String json = ''' { + "extensions": {"7":28.00,"14":41.00,"30":60.00} + } + ''' + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues['''$.extensions[?(@.7 == 28)]'''] == 28.0 + pathAndValues['''$.extensions[?(@.14 == 41)]'''] == 41.0 + pathAndValues['''$.extensions[?(@.30 == 60)]'''] == 60.0 + and: + assertThatJsonPathsInMapAreValid(json, pathAndValues) + } def 'should convert a json with a list of errors'() { given: From a738736b8d302a3c5f8df7ebeb7f0913db3bb66f Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 17 Dec 2015 10:17:06 +0100 Subject: [PATCH 269/719] Release version: 0.9.13 [ci skip] From 97c9d66b088f0494afacecf0e0a9c41887158263 Mon Sep 17 00:00:00 2001 From: mchmielarz Date: Wed, 23 Dec 2015 00:23:21 +0100 Subject: [PATCH 270/719] This fixes #187 --- .../util/JsonToJsonPathsConverter.groovy | 14 ++++++++- .../JaxRsClientSpockMethodBuilderSpec.groovy | 29 +++++++++++++++++++ .../MockMvcSpockMethodBuilderSpec.groovy | 29 +++++++++++++++++++ .../util/JsonToJsonPathsConverterSpec.groovy | 18 +++++++++++- 4 files changed, 88 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 0bf9cc2ff5..a0e62b09fc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -142,7 +142,19 @@ class JsonToJsonPathsConverter { } protected static String potentiallyWrappedWithQuotesValue(Object value) { - return value instanceof Number ? value : "'$value'" + return isNumber(value) || isBoolean(value) || isNull(value) ? value : "'$value'" + } + + private static boolean isNull(value) { + value == null + } + + private static boolean isBoolean(value) { + value instanceof Boolean + } + + private static boolean isNumber(value) { + value instanceof Number } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index d8d13e124f..a8daa0af22 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -34,6 +34,35 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } + @Issue("#187") + def "should generate assertions for null and boolean values"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ + "property1": "true", + "property2": null, + "property3": false +}""" + } + } + JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("\$[?(@.property1 == 'true')]") + blockBuilder.toString().contains("\$[?(@.property2 == null)]") + blockBuilder.toString().contains("\$[?(@.property3 == false)]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + @Issue("#79") def "should generate assertions for simple response body constructed from map with a list"() { given: diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index efdb49fbc0..ba403adcde 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -40,6 +40,35 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) } + @Issue("#187") + def "should generate assertions for null and boolean values"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ + "property1": "true", + "property2": null, + "property3": false +}""" + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("\$[?(@.property1 == 'true')]") + blockBuilder.toString().contains("\$[?(@.property2 == null)]") + blockBuilder.toString().contains("\$[?(@.property3 == false)]") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + } + @Issue("#79") def "should generate assertions for simple response body constructed from map with a list"() { given: diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index 90b0c0d2da..fd1a4f5c50 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -119,6 +119,21 @@ class JsonToJsonPathsConverterSpec extends Specification { assertThatJsonPathsInMapAreValid(json, pathAndValues) } + def 'should convert a json with null and boolean values'() { + given: + String json = ''' + { + "property1" : null, + "property2" : true + } +''' + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues['''$[?(@.property1 == null)]'''] == null + pathAndValues['''$[?(@.property2 == true)]'''] == true + } + def "should convert numbers map"() { given: String json = ''' { @@ -207,7 +222,8 @@ class JsonToJsonPathsConverterSpec extends Specification { private void assertThatJsonPathsInMapAreValid(String json, JsonPaths pathAndValues) { DocumentContext parsedJson = JsonPath.using(Configuration.builder().options(Option.ALWAYS_RETURN_LIST).build()).parse(json); pathAndValues.each { - assert parsedJson.read(it.jsonPath, JSONArray).getAt(it.optionalSuffix ?: 0) == it.optionalSuffix ? [it.value] : it.value + def at = parsedJson.read(it.jsonPath, JSONArray).getAt(it.optionalSuffix ?: 0) + assert at == it.optionalSuffix ? [it.value] : it.value } } From bfbd7d01db49af30192a50b0a4f3d58dd29822f7 Mon Sep 17 00:00:00 2001 From: mchmielarz Date: Wed, 23 Dec 2015 22:33:46 +0100 Subject: [PATCH 271/719] Returns added to methods. --- .../codearte/accurest/util/JsonToJsonPathsConverter.groovy | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index a0e62b09fc..46dd08003b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -146,15 +146,15 @@ class JsonToJsonPathsConverter { } private static boolean isNull(value) { - value == null + return value == null } private static boolean isBoolean(value) { - value instanceof Boolean + return value instanceof Boolean } private static boolean isNumber(value) { - value instanceof Number + return value instanceof Number } } From 347d46a7f2dab75263c77e110a2cc3916a12bdb6 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 30 Dec 2015 10:00:59 +0100 Subject: [PATCH 272/719] Release version: 0.9.14 [ci skip] From da5313e3765e9b48c0086c296f2b2b4df7fe1380 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sun, 7 Feb 2016 01:43:05 +0100 Subject: [PATCH 273/719] Implement new way of scanning for contract files. Add support for generating ignored tests. Fix #28 #53 --- .travis.yml | 2 +- .../accurest/SingleTestGenerator.groovy | 11 +-- .../io/codearte/accurest/TestGenerator.groovy | 64 +++++++++--------- .../accurest/builder/MethodBuilder.groovy | 13 +++- .../config/AccurestConfigProperties.groovy | 41 ++++++++++++ .../codearte/accurest/config/TestMode.groovy | 15 ++++- .../io/codearte/accurest/file/Contract.groovy | 17 +++++ .../accurest/file/ContractFileScanner.groovy | 67 +++++++++++++++++++ .../accurest/GeneratorScannerSpec.groovy | 38 ++--------- .../io/codearte/accurest/MainTest.groovy | 2 +- .../file/ContractFileScannerSpec.groovy | 30 +++++++++ 11 files changed, 226 insertions(+), 74 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy diff --git a/.travis.yml b/.travis.yml index bdf2cb280b..220272e2ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,4 +12,4 @@ cache: - $HOME/.m2 install: ./gradlew assemble -script: ./gradlew check funcTest --stacktrace --info --continue +script: ./gradlew clean check funcTest --stacktrace --info --continue diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index fb2d135419..d950bd345c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -5,6 +5,7 @@ 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.file.Contract import static io.codearte.accurest.builder.ClassBuilder.createClass import static io.codearte.accurest.builder.MethodBuilder.createTestMethod @@ -19,7 +20,7 @@ class SingleTestGenerator { } @PackageScope - String buildClass(List listOfFiles, String className, String classPackage) { + String buildClass(Collection listOfFiles, String className, String classPackage) { ClassBuilder clazz = createClass(capitalize(className), classPackage, configProperties) @@ -29,6 +30,10 @@ class SingleTestGenerator { } } + if (listOfFiles.ignored.find {it}) { + clazz.addImport("org.junit.Ignore") + } + if (configProperties.staticImports) { configProperties.staticImports.each { clazz.addStaticImport(it) @@ -50,9 +55,7 @@ class SingleTestGenerator { } if (configProperties.ruleClassForTests) { - - clazz.addImport('org.junit.Rule') - .addRule(configProperties.ruleClassForTests) + clazz.addImport('org.junit.Rule').addRule(configProperties.ruleClassForTests) } addJsonPathRelatedImports(clazz) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index bcd7ac3350..6c97397b5a 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -1,14 +1,20 @@ package io.codearte.accurest +import com.google.common.collect.Multimap import groovy.transform.PackageScope import io.codearte.accurest.config.AccurestConfigProperties -import org.apache.commons.io.FilenameUtils -import org.codehaus.plexus.util.DirectoryScanner +import io.codearte.accurest.file.Contract +import io.codearte.accurest.file.ContractFileScanner +import org.apache.commons.lang3.StringUtils import java.nio.charset.StandardCharsets +import java.nio.file.Path import java.util.concurrent.atomic.AtomicInteger -import static io.codearte.accurest.util.NamesUtil.* +import static io.codearte.accurest.util.NamesUtil.afterLast +import static io.codearte.accurest.util.NamesUtil.beforeLast +import static io.codearte.accurest.util.NamesUtil.convertIllegalPackageChars +import static io.codearte.accurest.util.NamesUtil.directoryToPackage /** * @author Jakub Kubrynski @@ -16,10 +22,12 @@ import static io.codearte.accurest.util.NamesUtil.* class TestGenerator { private final AccurestConfigProperties configProperties + private final String DEFAULT_CLASS_PREFIX = "Accurest" + private AtomicInteger counter = new AtomicInteger() private SingleTestGenerator generator private FileSaver saver - private DirectoryScanner directoryScanner + private ContractFileScanner contractFileScanner TestGenerator(AccurestConfigProperties accurestConfigProperties) { this(accurestConfigProperties, new SingleTestGenerator(accurestConfigProperties), @@ -33,9 +41,9 @@ class TestGenerator { } this.generator = generator this.saver = saver - this.directoryScanner = new DirectoryScanner() - directoryScanner.setExcludes(configProperties.getIgnoredFiles() as String[]) - directoryScanner.setBasedir(configProperties.contractsDslDir) + contractFileScanner = new ContractFileScanner(configProperties.contractsDslDir, + configProperties.excludedFiles as Set, + configProperties.ignoredFiles as Set) } int generate() { @@ -45,31 +53,28 @@ class TestGenerator { @PackageScope void generateTestClasses(final String basePackageName) { - directoryScanner.scan() - directoryScanner.getIncludedDirectories() - .each { String includedDirectoryRelativePath -> - processIncludedDirectory(includedDirectoryRelativePath, basePackageName) - + Multimap contracts = contractFileScanner.findContracts() + contracts.asMap().entrySet().each { + Map.Entry> entry -> processIncludedDirectory(relativizeContractPath(entry), entry.getValue(), basePackageName) } } + private String relativizeContractPath(Map.Entry> entry) { + Path relativePath = configProperties.contractsDslDir.toPath().relativize(entry.getKey()) + if (StringUtils.isBlank(relativePath.toString())) { + return DEFAULT_CLASS_PREFIX + } + return relativePath.toString() + } + private void processIncludedDirectory( - final String includedDirectoryRelativePath, final String basePackageNameForClass) { - if (!includedDirectoryRelativePath.isEmpty()) { - List filesToClass = directoryScanner.includedFiles. - grep { String includedFile -> - return normalizePath(includedFile).matches(normalizePath(includedDirectoryRelativePath + File.separator) + "[A-Za-z0-9_]*\\.groovy") - } - .collect { - return new File(configProperties.contractsDslDir, it) - } - if (filesToClass.size()) { - def className = afterLast(includedDirectoryRelativePath, File.separator) + resolveNameSuffix() - def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath) - def classBytes = generator.buildClass(filesToClass, className, packageName).getBytes(StandardCharsets.UTF_8) - saver.saveClassFile(className, basePackageNameForClass, convertIllegalPackageChars(includedDirectoryRelativePath), classBytes) - counter.incrementAndGet() - } + final String includedDirectoryRelativePath, Collection contracts, final String basePackageNameForClass) { + if (contracts.size()) { + def className = afterLast(includedDirectoryRelativePath.toString(), File.separator) + resolveNameSuffix() + def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath) + def classBytes = generator.buildClass(contracts, className, packageName).getBytes(StandardCharsets.UTF_8) + saver.saveClassFile(className, basePackageNameForClass, convertIllegalPackageChars(includedDirectoryRelativePath.toString()), classBytes) + counter.incrementAndGet() } } @@ -82,7 +87,4 @@ class TestGenerator { return !directory.empty ? "$packageNameForClass.${directoryToPackage(convertIllegalPackageChars(directory))}" : packageNameForClass } - private static String normalizePath(String path) { - return FilenameUtils.separatorsToUnix(path) - } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index 55a0f66f36..2007d05b1b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -5,6 +5,7 @@ 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 io.codearte.accurest.util.NamesUtil import org.codehaus.groovy.control.CompilerConfiguration @@ -17,25 +18,31 @@ class MethodBuilder { private final String methodName private final GroovyDsl stubContent private final AccurestConfigProperties configProperties + private final boolean ignored - private MethodBuilder(String methodName, GroovyDsl stubContent, AccurestConfigProperties configProperties) { + private MethodBuilder(String methodName, GroovyDsl stubContent, AccurestConfigProperties configProperties, boolean ignored) { + this.ignored = ignored this.stubContent = stubContent this.methodName = methodName this.configProperties = configProperties } - static MethodBuilder createTestMethod(File stubsFile, AccurestConfigProperties 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) 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) + return new MethodBuilder(methodName, stubContent, configProperties, contract.ignored) } void appendTo(BlockBuilder blockBuilder) { if (configProperties.targetFramework == TestFramework.JUNIT) { blockBuilder.addLine('@Test') } + if (ignored) { + blockBuilder.addLine('@Ignore') + } blockBuilder.addLine(configProperties.targetFramework.methodModifier + "$methodName() {") getMethodBodyBuilder().appendTo(blockBuilder) blockBuilder.addLine('}') diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy index cc94fb39e9..fbf299f525 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy @@ -3,14 +3,55 @@ package io.codearte.accurest.config * @author Jakub Kubrynski */ class AccurestConfigProperties { + + /** + * For which unit test library tests should be generated + */ TestFramework targetFramework = TestFramework.SPOCK + + /** + * Which mechanism should be used to invoke REST calls during tests + */ TestMode testMode = TestMode.MOCKMVC + + /** + * Base package for generated tests + */ String basePackageForTests + + /** + * Class which all generated tests should extend + */ String baseClassForTests + + /** + * Suffix for generated test classes, like Spec or Test + */ String nameSuffixForTests + + /** + * Rule class that should be added to generated tests + */ String ruleClassForTests + + /** + * Patterns that should not be taken into account for processing + */ + List excludedFiles = [] + + /** + * Patterns for which Accurest should generate @Ignored tests + */ List ignoredFiles = [] + + /** + * Imports that should be added to generated tests + */ String[] imports = [] + + /** + * Static imports that should be added to generated tests + */ String[] staticImports = [] /** diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy index 1c7732d49e..5d1f339bc8 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy @@ -4,5 +4,18 @@ package io.codearte.accurest.config * @author Jakub Kubrynski */ enum TestMode { - MOCKMVC, EXPLICIT, JAXRSCLIENT + /** + * Uses Spring's MockMvc + */ + MOCKMVC, + + /** + * Uses direct HTTP invocations + */ + EXPLICIT, + + /** + * Uses JAX-RS client + */ + JAXRSCLIENT } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy new file mode 100644 index 0000000000..6d7289b24d --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy @@ -0,0 +1,17 @@ +package io.codearte.accurest.file + +import java.nio.file.Path + +/** + * @author Jakub Kubrynski + */ +class Contract { + final Path path; + final boolean ignored; + + Contract(Path path, boolean ignored) { + this.path = path + this.ignored = ignored + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy new file mode 100644 index 0000000000..421b89a4b8 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy @@ -0,0 +1,67 @@ +package io.codearte.accurest.file + +import com.google.common.collect.ArrayListMultimap +import com.google.common.collect.Multimap +import org.apache.commons.io.FilenameUtils + +import java.nio.file.FileSystem +import java.nio.file.FileSystems +import java.nio.file.Path +import java.nio.file.PathMatcher + +/** + * @author Jakub Kubrynski + */ +class ContractFileScanner { + + private final String MATCH_PREFIX = "glob:" + private final File baseDir + private final Set excludeMatchers + private final Set ignoreMatchers + + ContractFileScanner(File baseDir, Set excluded, Set ignored) { + this.baseDir = baseDir + excludeMatchers = processPatterns(excluded, baseDir) + ignoreMatchers = processPatterns(ignored, baseDir) + } + + private Set processPatterns(Set patterns, baseDir) { + FileSystem fileSystem = FileSystems.getDefault() + return patterns.collect({ + fileSystem.getPathMatcher(MATCH_PREFIX + baseDir.toString() + File.separator + it) + }) as Set + } + + Multimap findContracts() { + Multimap result = ArrayListMultimap.create() + appendRecursively(baseDir, result) + return result + } + + private void appendRecursively(File baseDir, Multimap result) { + for (File file : baseDir.listFiles()) { + if (matchesPattern(file, excludeMatchers)) { + break; + } + if (isContractFile(file)) { + Path path = file.toPath() + result.put(file.parentFile.toPath(), new Contract(path, matchesPattern(file, ignoreMatchers))) + } else { + appendRecursively(file, result) + } + } + } + + boolean matchesPattern(File file, Set excludeMatchers) { + for (PathMatcher matcher : excludeMatchers) { + if (matcher.matches(file.toPath())) { + return true; + } + } + return false; + } + + private boolean isContractFile(File file) { + file.isFile() && FilenameUtils.getExtension(file.toString()).equalsIgnoreCase("groovy") + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy index f11187e3d2..e95eeb1fe9 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy @@ -19,45 +19,17 @@ class GeneratorScannerSpec extends Specification { 6 * classGenerator.buildClass(_, _, _) >> "qwerty" } - def "should filter other directory"() { + def "should create class with full package"() { given: - File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) - AccurestConfigProperties properties = new AccurestConfigProperties() - properties.ignoredFiles << "**/other/**" - properties.contractsDslDir = resource.parentFile - TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) - when: - testGenerator.generateTestClasses("com.ofg") - then: - 1 * classGenerator.buildClass(_, 'differentSpec', _) >> "qwerty" - 3 * classGenerator.buildClass(_, 'exceptionsSpec', _) >> "qwerty" - } - - def "should ignore file"() { - given: - File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) - AccurestConfigProperties properties = new AccurestConfigProperties() - properties.ignoredFiles << "**/other.groovy" - properties.contractsDslDir = resource.parentFile - TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) - classGenerator.buildClass(_, _, _) >> "sample" - when: - testGenerator.generateTestClasses("com.ofg") - then: - 1 * classGenerator.buildClass({ it.size() == 1 }, 'otherSpec', _) >> "sample.groovy" - } - - def "should create class with full package"() { - given: AccurestConfigProperties properties = new AccurestConfigProperties() properties.contractsDslDir = new File(this.getClass().getResource("/directory/with/stubs/package").toURI()) TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) - when: - testGenerator.generateTestClasses("com.ofg") - then: + when: + testGenerator.generateTestClasses("com.ofg") + then: 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg') >> "spec" 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v1') >> "spec1" 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v2') >> "spec2" - } + } } 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 4bdc8e9cc8..dd0ab8cf10 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy @@ -10,7 +10,7 @@ class MainTest { contractsDslDir: new File('/home/devel/projects/codearte/accurest/accurest-core/src/test/resources/dsl'), generatedTestSourcesDir: new File('/tmp/accurest'), targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', - staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], ignoredFiles: ["**/other"]) + staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], excludedFiles: ["**/other"]) println new TestGenerator(properties).generate() } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy new file mode 100644 index 0000000000..d6c0fdd1d2 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy @@ -0,0 +1,30 @@ +package io.codearte.accurest.file + +import com.google.common.collect.Multimap +import spock.lang.Specification + +import java.nio.file.Path + +/** + * @author Jakub Kubrynski + */ +class ContractFileScannerSpec extends Specification { + + def "should find contract files"() { + given: + File baseDir = new File(this.getClass().getResource("/directory/with/stubs").toURI()) + Set excluded = ["package/**"] as Set + Set ignored = ["other/different/**"] as Set + ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored) + when: + Multimap result = scanner.findContracts() + then: + result.keySet().size() == 3 + result.get(baseDir.toPath().resolve("different")).size() == 1 + result.get(baseDir.toPath().resolve("other")).size() == 2 + and: + Collection ignoredSet = result.get(baseDir.toPath().resolve("other").resolve("different")) + ignoredSet.size() == 1 + ignoredSet.ignored == [true] + } +} From bd9015c1524d02656e489264a4d86f32deaa3d87 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sun, 7 Feb 2016 17:18:57 +0100 Subject: [PATCH 274/719] Make Wiremock generator use ContractFileScanner. Fix #189 --- .../wiremock/RecursiveFilesConverter.groovy | 21 +++++--- .../RecursiveFilesConverterSpec.groovy | 53 +++++++++++++++---- .../plugin/AccurestGradlePlugin.groovy | 1 + ...erateWireMockClientStubsFromDslTask.groovy | 6 ++- 4 files changed, 61 insertions(+), 20 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy index 8f71f8955b..b031acc174 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy @@ -1,8 +1,12 @@ package io.codearte.accurest.wiremock +import com.google.common.collect.Multimap import groovy.io.FileType import groovy.transform.CompileStatic import groovy.util.logging.Slf4j +import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.file.Contract +import io.codearte.accurest.file.ContractFileScanner import java.nio.charset.StandardCharsets import java.nio.file.Files @@ -14,17 +18,18 @@ import java.nio.file.Paths class RecursiveFilesConverter { private final SingleFileConverter singleFileConverter - private final File sourceRootDirectory - private final File targetRootDirectory + private final AccurestConfigProperties properties - RecursiveFilesConverter(SingleFileConverter singleFileConverter, File sourceRootDirectory, File targetRootDirectory) { + RecursiveFilesConverter(SingleFileConverter singleFileConverter, AccurestConfigProperties properties) { + this.properties = properties this.singleFileConverter = singleFileConverter - this.sourceRootDirectory = sourceRootDirectory - this.targetRootDirectory = targetRootDirectory } void processFiles() { - sourceRootDirectory.eachFileRecurse(FileType.FILES) { File sourceFile -> + ContractFileScanner scanner = new ContractFileScanner(properties.contractsDslDir, properties.excludedFiles as Set, [] as Set) + Multimap contracts = scanner.findContracts() + contracts.values().each { Contract contract -> + File sourceFile = contract.path.toFile() try { if (!singleFileConverter.canHandleFileName(sourceFile.name)) { return @@ -40,8 +45,8 @@ class RecursiveFilesConverter { } private Path createAndReturnTargetDirectory(File sourceFile) { - Path relativePath = Paths.get(sourceRootDirectory.toURI()).relativize(sourceFile.parentFile.toPath()) - Path absoluteTargetPath = targetRootDirectory.toPath().resolve(relativePath) + Path relativePath = Paths.get(properties.contractsDslDir.toURI()).relativize(sourceFile.parentFile.toPath()) + Path absoluteTargetPath = properties.stubsOutputDir.toPath().resolve(relativePath) Files.createDirectories(absoluteTargetPath) absoluteTargetPath } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy index 583de32c0b..f5f9022b97 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.wiremock +import io.codearte.accurest.config.AccurestConfigProperties import org.apache.commons.io.FileUtils import org.apache.commons.io.filefilter.TrueFileFilter import org.junit.Rule @@ -11,42 +12,73 @@ import java.nio.file.Paths class RecursiveFilesConverterSpec extends Specification { - private static final Set EXPECTED_TARGET_FILES = [Paths.get("dslRoot.json"), Paths.get("dir1/dsl1.json"), Paths.get("dir1/dsl1b.json"), Paths.get("dir2/dsl2.json")] + private static + final Set EXPECTED_TARGET_FILES = [Paths.get("dslRoot.json"), Paths.get("dir1/dsl1.json"), Paths.get("dir1/dsl1b.json"), Paths.get("dir2/dsl2.json")] @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); def "should recursively convert all matching files"() { given: + AccurestConfigProperties properties = new AccurestConfigProperties() File originalSourceRootDirectory = new File(this.getClass().getResource("/converter/source").toURI()) - File sourceRootDirectory = tmpFolder.newFolder("source") - File targetRootDirectory = tmpFolder.newFolder("target") - FileUtils.copyDirectory(originalSourceRootDirectory, sourceRootDirectory) + properties.contractsDslDir = tmpFolder.newFolder("source") + properties.stubsOutputDir = tmpFolder.newFolder("target") + FileUtils.copyDirectory(originalSourceRootDirectory, properties.contractsDslDir) and: def singleFileConverterStub = Stub(SingleFileConverter) singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") } singleFileConverterStub.convertContent(_) >> { "converted" } singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') } - RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, sourceRootDirectory, targetRootDirectory) + + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, properties) when: recursiveFilesConverter.processFiles() then: - Collection createdFiles = FileUtils.listFiles(targetRootDirectory, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) - Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, targetRootDirectory) + Collection createdFiles = FileUtils.listFiles(properties.stubsOutputDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) + Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, properties.stubsOutputDir) EXPECTED_TARGET_FILES == relativizedCreatedFiles and: createdFiles.each { it.text == "converted" } } + def "should recursively convert matching files with exlusions"() { + given: + AccurestConfigProperties properties = new AccurestConfigProperties() + File originalSourceRootDirectory = new File(this.getClass().getResource("/converter/source").toURI()) + properties.contractsDslDir = tmpFolder.newFolder("source") + properties.stubsOutputDir = tmpFolder.newFolder("target") + properties.excludedFiles = ["dir1/**"] + FileUtils.copyDirectory(originalSourceRootDirectory, properties.contractsDslDir) + and: + def singleFileConverterStub = Stub(SingleFileConverter) + singleFileConverterStub.canHandleFileName(_) >> { String fileName -> fileName.endsWith(".groovy") } + singleFileConverterStub.convertContent(_) >> { "converted" } + singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> inputFileName.replaceAll('.groovy', '.json') } + + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, properties) + when: + recursiveFilesConverter.processFiles() + then: + Collection createdFiles = FileUtils.listFiles(properties.stubsOutputDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) + Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, properties.stubsOutputDir) + [Paths.get("dslRoot.json"), Paths.get("dir2/dsl2.json")] as Set == relativizedCreatedFiles as Set + and: + createdFiles.each { it.text == "converted" } + } + def "on failure should break processing and throw meaningful exception"() { given: - def sourceFile = tmpFolder.newFile() + def sourceFile = tmpFolder.newFile("test.groovy") and: def singleFileConverterStub = Stub(SingleFileConverter) singleFileConverterStub.canHandleFileName(_) >> { true } singleFileConverterStub.convertContent(_) >> { throw new NullPointerException("Test conversion error") } singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> "${inputFileName}2" } - RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, tmpFolder.root, tmpFolder.root) + AccurestConfigProperties properties = new AccurestConfigProperties() + properties.contractsDslDir = tmpFolder.root + properties.stubsOutputDir = tmpFolder.root + RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, properties) when: recursiveFilesConverter.processFiles() then: @@ -55,7 +87,8 @@ class RecursiveFilesConverterSpec extends Specification { e.cause?.message == "Test conversion error" } - private static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { + private + static Set getRelativePathsForFilesInDirectory(Collection createdFiles, File targetRootDirectory) { Path rootSourcePath = Paths.get(targetRootDirectory.toURI()) Set relativizedCreatedFiles = createdFiles.collect { File file -> rootSourcePath.relativize(Paths.get(file.toURI())) 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 11a86d33c9..1ad91232f6 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 @@ -70,6 +70,7 @@ class AccurestGradlePlugin implements Plugin { task.conventionMapping.with { contractsDslDir = { extension.contractsDslDir } stubsOutputDir = { extension.stubsOutputDir } + configProperties = { extension } } } diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy index be22c44def..f4a518c1bb 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.plugin +import io.codearte.accurest.config.AccurestConfigProperties import io.codearte.accurest.wiremock.DslToWireMockClientConverter import io.codearte.accurest.wiremock.RecursiveFilesConverter import org.gradle.api.internal.ConventionTask @@ -15,13 +16,14 @@ class GenerateWireMockClientStubsFromDslTask extends ConventionTask { @OutputDirectory File stubsOutputDir + AccurestConfigProperties configProperties + @TaskAction void generate() { logger.info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), getContractsDslDir(), - getStubsOutputDir()) + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), getConfigProperties()) converter.processFiles() } } From d42dc2ade47f7a11c3d6a0fc4a4ea7ba8045cbb5 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sun, 7 Feb 2016 21:35:25 +0100 Subject: [PATCH 275/719] Provide support for scenarios. Fix #182 --- .../DslToWireMockClientConverter.groovy | 8 +++- .../wiremock/RecursiveFilesConverter.groovy | 29 ++++++------ .../wiremock/SingleFileConverter.groovy | 3 +- .../DslToWireMockClientConverterSpec.groovy | 20 +++++--- .../RecursiveFilesConverterSpec.groovy | 2 +- .../WiremockScenarioConverterSpec.groovy | 46 +++++++++++++++++++ .../scenario/main_scenario/01_login.groovy | 9 ++++ .../scenario/main_scenario/02_showCart.groovy | 9 ++++ .../scenario/main_scenario/03_logout.groovy | 9 ++++ .../accurest/SingleTestGenerator.groovy | 20 +++++--- .../io/codearte/accurest/TestGenerator.groovy | 4 +- .../accurest/builder/ClassBuilder.groovy | 9 ++++ .../accurest/config/TestFramework.groovy | 25 ++++++++-- .../accurest/dsl/WireMockStubStrategy.groovy | 18 +++++++- .../io/codearte/accurest/file/Contract.groovy | 15 +++++- .../accurest/file/ContractFileScanner.groovy | 40 ++++++++++------ .../JaxRsClientSpockMethodBuilderSpec.groovy | 35 +++++++------- .../MockMvcSpockMethodBuilderSpec.groovy | 41 +++++++++-------- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 33 ++++++------- .../accurest/dsl/WireMockStubVerifier.groovy | 1 + .../file/ContractFileScannerSpec.groovy | 17 ++++++- .../directory/with/scenario/01_login.groovy | 1 + .../with/scenario/02_showCart.groovy | 1 + .../directory/with/scenario/03_logout.groovy | 1 + 24 files changed, 292 insertions(+), 104 deletions(-) create mode 100755 accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockScenarioConverterSpec.groovy create mode 100644 accurest-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy create mode 100644 accurest-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy create mode 100644 accurest-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy create mode 100644 accurest-core/src/test/resources/directory/with/scenario/01_login.groovy create mode 100644 accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy create mode 100644 accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy 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 619bd8b235..616595e8bb 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 @@ -2,12 +2,16 @@ package io.codearte.accurest.wiremock import groovy.transform.CompileStatic import io.codearte.accurest.dsl.WireMockStubStrategy +import io.codearte.accurest.file.Contract + +import java.nio.charset.StandardCharsets @CompileStatic class DslToWireMockClientConverter extends DslToWireMockConverter { @Override - String convertContent(String dslBody) { - return new WireMockStubStrategy(createGroovyDSLfromStringContent(dslBody)).toWireMockClientStub() + String convertContent(String rootName, Contract contract) { + String dslContent = contract.path.getText(StandardCharsets.UTF_8.toString()) + return new WireMockStubStrategy(rootName, contract, createGroovyDSLfromStringContent(dslContent)).toWireMockClientStub() } } diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy index b031acc174..d073a7af2e 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy @@ -1,7 +1,6 @@ package io.codearte.accurest.wiremock -import com.google.common.collect.Multimap -import groovy.io.FileType +import com.google.common.collect.ListMultimap import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import io.codearte.accurest.config.AccurestConfigProperties @@ -27,19 +26,21 @@ class RecursiveFilesConverter { void processFiles() { ContractFileScanner scanner = new ContractFileScanner(properties.contractsDslDir, properties.excludedFiles as Set, [] as Set) - Multimap contracts = scanner.findContracts() - contracts.values().each { Contract contract -> - File sourceFile = contract.path.toFile() - try { - if (!singleFileConverter.canHandleFileName(sourceFile.name)) { - return + ListMultimap contracts = scanner.findContracts() + contracts.asMap().entrySet().each { entry -> + entry.value.each { Contract contract -> + File sourceFile = contract.path.toFile() + try { + if (!singleFileConverter.canHandleFileName(sourceFile.name)) { + return + } + String convertedContent = singleFileConverter.convertContent(entry.key.last().toString(), contract) + 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) } - String convertedContent = singleFileConverter.convertContent(sourceFile.getText(StandardCharsets.UTF_8.toString())) - 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) } } } diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy index 27d10c25c8..fda8aa2e82 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy +++ b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy @@ -1,13 +1,14 @@ package io.codearte.accurest.wiremock import groovy.transform.CompileStatic +import io.codearte.accurest.file.Contract @CompileStatic interface SingleFileConverter { boolean canHandleFileName(String fileName) - String convertContent(String content) + String convertContent(String rootName, Contract content) String generateOutputFileNameForInput(String inputFileName) } \ No newline at end of file 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 61c6b7c29b..60801e3950 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 @@ -1,15 +1,22 @@ package io.codearte.accurest.wiremock +import io.codearte.accurest.file.Contract +import org.junit.Rule +import org.junit.rules.TemporaryFolder import org.skyscreamer.jsonassert.JSONAssert import spock.lang.Specification class DslToWireMockClientConverterSpec extends Specification { + @Rule + public TemporaryFolder tmpFolder = new TemporaryFolder(); + def "should convert DSL file to WireMock JSON"() { given: def converter = new DslToWireMockClientConverter() and: - String dslBody = """ + File file = tmpFolder.newFile("dsl1.groovy") + file.write(""" io.codearte.accurest.dsl.GroovyDsl.make { request { method('PUT') @@ -19,9 +26,9 @@ class DslToWireMockClientConverterSpec extends Specification { status 200 } } -""" +""") when: - String json = converter.convertContent(dslBody) + String json = converter.convertContent("Test", new Contract(file.toPath(), false, 0, null)) then: JSONAssert.assertEquals(''' {"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}} @@ -33,7 +40,8 @@ class DslToWireMockClientConverterSpec extends Specification { given: def converter = new DslToWireMockClientConverter() and: - String dslBody = """ + File file = tmpFolder.newFile("dsl2.groovy") + file.write(""" io.codearte.accurest.dsl.GroovyDsl.make { request { method 'PUT' @@ -77,9 +85,9 @@ class DslToWireMockClientConverterSpec extends Specification { status 200 } } -""" +""") when: - String json = converter.convertContent(dslBody) + String json = converter.convertContent("Test", new Contract(file.toPath(), false, 0, null)) then: JSONAssert.assertEquals(''' { diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy index f5f9022b97..fc0a0014b6 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy @@ -73,7 +73,7 @@ class RecursiveFilesConverterSpec extends Specification { and: def singleFileConverterStub = Stub(SingleFileConverter) singleFileConverterStub.canHandleFileName(_) >> { true } - singleFileConverterStub.convertContent(_) >> { throw new NullPointerException("Test conversion error") } + singleFileConverterStub.convertContent(_, _) >> { throw new NullPointerException("Test conversion error") } singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> "${inputFileName}2" } AccurestConfigProperties properties = new AccurestConfigProperties() properties.contractsDslDir = tmpFolder.root diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockScenarioConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockScenarioConverterSpec.groovy new file mode 100755 index 0000000000..e7911c1303 --- /dev/null +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockScenarioConverterSpec.groovy @@ -0,0 +1,46 @@ +package io.codearte.accurest.wiremock + +import io.codearte.accurest.file.Contract +import spock.lang.Specification + +import java.nio.file.Path +import java.nio.file.Paths + +class WiremockScenarioConverterSpec extends Specification { + + def "should generate first scenario step"() { + given: + DslToWireMockClientConverter converter = new DslToWireMockClientConverter() + Path dsl = Paths.get(this.getClass().getResource("/converter/scenario/main_scenario/01_login.groovy").toURI()) + when: + String content = converter.convertContent("Test", new Contract(dsl, false, 3, 0)) + then: + content.contains('"requiredScenarioState" : "Started"') + content.contains('"newScenarioState" : "Step1"') + content.contains('"scenarioName" : "Scenario_Test"') + } + + def "should generate mid scenario step"() { + given: + DslToWireMockClientConverter converter = new DslToWireMockClientConverter() + Path dsl = Paths.get(this.getClass().getResource("/converter/scenario/main_scenario/02_showCart.groovy").toURI()) + when: + String content = converter.convertContent("Test", new Contract(dsl, false, 3, 1)) + then: + content.contains('"requiredScenarioState" : "Step1"') + content.contains('"newScenarioState" : "Step2"') + content.contains('"scenarioName" : "Scenario_Test"') + } + + def "should generate last scenario step"() { + given: + DslToWireMockClientConverter converter = new DslToWireMockClientConverter() + Path dsl = Paths.get(this.getClass().getResource("/converter/scenario/main_scenario/03_logout.groovy").toURI()) + when: + String content = converter.convertContent("Test", new Contract(dsl, false, 3, 2)) + then: + content.contains('"requiredScenarioState" : "Step2"') + !content.contains('"newScenarioState"') + content.contains('"scenarioName" : "Scenario_Test"') + } +} diff --git a/accurest-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy b/accurest-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy new file mode 100644 index 0000000000..1a30790fc3 --- /dev/null +++ b/accurest-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy @@ -0,0 +1,9 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method('POST') + url '/login' + } + response { + status 200 + } +} diff --git a/accurest-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy b/accurest-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy new file mode 100644 index 0000000000..712c7ef584 --- /dev/null +++ b/accurest-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy @@ -0,0 +1,9 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method('GET') + url '/cart' + } + response { + status 200 + } +} diff --git a/accurest-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy b/accurest-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy new file mode 100644 index 0000000000..33e948e602 --- /dev/null +++ b/accurest-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy @@ -0,0 +1,9 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method('POST') + url '/logout' + } + response { + status 200 + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index d950bd345c..99d7915e9f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -21,8 +21,7 @@ class SingleTestGenerator { @PackageScope String buildClass(Collection listOfFiles, String className, String classPackage) { - ClassBuilder clazz = createClass(capitalize(className), classPackage, - configProperties) + ClassBuilder clazz = createClass(capitalize(className), classPackage, configProperties) if (configProperties.imports) { configProperties.imports.each { @@ -30,8 +29,8 @@ class SingleTestGenerator { } } - if (listOfFiles.ignored.find {it}) { - clazz.addImport("org.junit.Ignore") + if (listOfFiles.ignored.find { it }) { + clazz.addImport(configProperties.targetFramework.getIgnoreClass()) } if (configProperties.staticImports) { @@ -40,6 +39,11 @@ class SingleTestGenerator { } } + if (isScenarioClass(listOfFiles)) { + clazz.addImport(configProperties.targetFramework.getOrderClass()) + clazz.addClassLevelAnnotation(configProperties.targetFramework.getOrderAnnotation()) + } + if (configProperties.testMode == TestMode.JAXRSCLIENT) { clazz.addStaticImport('javax.ws.rs.client.Entity.*') } else if (configProperties.testMode == TestMode.MOCKMVC) { @@ -66,10 +70,14 @@ class SingleTestGenerator { return clazz.build() } + private boolean isScenarioClass(Collection listOfFiles) { + listOfFiles.find({ it.order != null }) != null + } + private ClassBuilder addJsonPathRelatedImports(ClassBuilder clazz) { clazz.addImport(['com.jayway.jsonpath.DocumentContext', - 'com.jayway.jsonpath.JsonPath', - 'net.minidev.json.JSONArray']) + 'com.jayway.jsonpath.JsonPath', + 'net.minidev.json.JSONArray']) } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy index 6c97397b5a..d0e9f15346 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy @@ -1,6 +1,6 @@ package io.codearte.accurest -import com.google.common.collect.Multimap +import com.google.common.collect.ListMultimap import groovy.transform.PackageScope import io.codearte.accurest.config.AccurestConfigProperties import io.codearte.accurest.file.Contract @@ -53,7 +53,7 @@ class TestGenerator { @PackageScope void generateTestClasses(final String basePackageName) { - Multimap contracts = contractFileScanner.findContracts() + ListMultimap contracts = contractFileScanner.findContracts() contracts.asMap().entrySet().each { Map.Entry> entry -> processIncludedDirectory(relativizeContractPath(entry), entry.getValue(), basePackageName) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy index 3e3a8ce1c0..8975faa18f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy @@ -16,6 +16,7 @@ class ClassBuilder { private final List staticImports = [] private final List rules = [] private final List methods = [] + private final List classLevelAnnotations = [] private final TestFramework lang private ClassBuilder(String className, String packageName, String baseClass, TestFramework lang) { @@ -83,6 +84,10 @@ class ClassBuilder { clazz.addEmptyLine() } + classLevelAnnotations.sort().each { + clazz.addLine(it) + } + def classLine = "${lang.classModifier}class $className" if (baseClass) { classLine += " extends $baseClass" @@ -107,4 +112,8 @@ class ClassBuilder { clazz.addLine('}') clazz.toString() } + + void addClassLevelAnnotation(String annotation) { + classLevelAnnotations << annotation + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy index 79758327f3..9aeacf1b3e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy @@ -4,21 +4,28 @@ package io.codearte.accurest.config * @author Jakub Kubrynski */ enum TestFramework { - JUNIT("public ", "public void ", ";", ".java", "Test"), - SPOCK("", "def ", "", ".groovy", "Spec") + JUNIT("public ", "public void ", ";", ".java", "Test", "org.junit.Ignore", "org.junit.FixMethodOrder", "@FixMethodOrder(MethodSorters.NAME_ASCENDING)"), + SPOCK("", "def ", "", ".groovy", "Spec", "spock.lang.Ignore", "spock.lang.Stepwise", "@Stepwise") private final String classModifier private final String methodModifier private final String lineSuffix private final String classExtension; private final String classNameSuffix; + private final String ignoreClass + private final String orderAnnotationImport + private final String orderAnnotation - TestFramework(String classModifier, String methodModifier, String lineSuffix, String classExtension, String classNameSuffix) { + TestFramework(String classModifier, String methodModifier, String lineSuffix, String classExtension, String classNameSuffix, + String ignoreClass, String orderAnnotationImport, String orderAnnotation) { this.classModifier = classModifier this.lineSuffix = lineSuffix this.methodModifier = methodModifier this.classExtension = classExtension this.classNameSuffix = classNameSuffix + this.ignoreClass = ignoreClass + this.orderAnnotationImport = orderAnnotationImport + this.orderAnnotation = orderAnnotation } String getClassModifier() { @@ -40,4 +47,16 @@ enum TestFramework { String getClassNameSuffix() { return classNameSuffix } + + String getIgnoreClass() { + return ignoreClass + } + + String getOrderClass() { + return orderClass + } + + String getOrderAnnotation() { + return orderAnnotation + } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy index 337f7b8557..9133b85067 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy @@ -5,15 +5,22 @@ import com.github.tomakehurst.wiremock.matching.RequestPattern import com.github.tomakehurst.wiremock.stubbing.StubMapping import groovy.transform.CompileDynamic import groovy.transform.CompileStatic +import io.codearte.accurest.file.Contract @CompileStatic class WireMockStubStrategy { + private static final String STEP_START = "Started" + private static final String STEP_PREFIX = "Step" private final WireMockRequestStubStrategy wireMockRequestStubStrategy private final WireMockResponseStubStrategy wireMockResponseStubStrategy private final Integer priority + private final Contract contract + private final String rootName - WireMockStubStrategy(GroovyDsl groovyDsl) { + WireMockStubStrategy(String rootName, Contract contract, GroovyDsl groovyDsl) { + this.rootName = rootName + this.contract = contract this.wireMockRequestStubStrategy = new WireMockRequestStubStrategy(groovyDsl) this.wireMockResponseStubStrategy = new WireMockResponseStubStrategy(groovyDsl) this.priority = groovyDsl.priority @@ -29,6 +36,15 @@ class WireMockStubStrategy { } stubMapping.request = request stubMapping.response = response + + if (contract.order != null) { + stubMapping.scenarioName = "Scenario_" + rootName + stubMapping.requiredScenarioState = contract.order == 0 ? STEP_START : STEP_PREFIX + contract.order + if (contract.order < contract.groupSize - 1) { + stubMapping.newScenarioState = STEP_PREFIX + (contract.order + 1) + } + } + return StubMapping.buildJsonStringFor(stubMapping) } } \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy index 6d7289b24d..d5cbcfea1c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy @@ -8,10 +8,23 @@ import java.nio.file.Path class Contract { final Path path; final boolean ignored; + final int groupSize + final Integer order; - Contract(Path path, boolean ignored) { + Contract(Path path, boolean ignored, int groupSize, Integer order) { + this.groupSize = groupSize this.path = path this.ignored = ignored + this.order = order } + @Override + public String toString() { + return "Contract{" + + "fileName=" + path.fileName + + ", ignored=" + ignored + + ", groupSize=" + groupSize + + ", order=" + order + + '}'; + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy index 421b89a4b8..1e1e27c310 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest.file import com.google.common.collect.ArrayListMultimap +import com.google.common.collect.ListMultimap import com.google.common.collect.Multimap import org.apache.commons.io.FilenameUtils @@ -8,13 +9,15 @@ import java.nio.file.FileSystem import java.nio.file.FileSystems import java.nio.file.Path import java.nio.file.PathMatcher +import java.util.regex.Pattern /** * @author Jakub Kubrynski */ class ContractFileScanner { - private final String MATCH_PREFIX = "glob:" + private static final String MATCH_PREFIX = "glob:" + private static final Pattern SCENARIO_STEP_FILENAME_PATTERN = Pattern.compile("[0-9]+_.*") private final File baseDir private final Set excludeMatchers private final Set ignoreMatchers @@ -32,26 +35,37 @@ class ContractFileScanner { }) as Set } - Multimap findContracts() { - Multimap result = ArrayListMultimap.create() + ListMultimap findContracts() { + ListMultimap result = ArrayListMultimap.create() appendRecursively(baseDir, result) return result } - private void appendRecursively(File baseDir, Multimap result) { - for (File file : baseDir.listFiles()) { - if (matchesPattern(file, excludeMatchers)) { - break; - } - if (isContractFile(file)) { - Path path = file.toPath() - result.put(file.parentFile.toPath(), new Contract(path, matchesPattern(file, ignoreMatchers))) - } else { - appendRecursively(file, result) + private void appendRecursively(File baseDir, ListMultimap result) { + File[] files = baseDir.listFiles() + if (!files) { + return; + } + files.sort().eachWithIndex { File file, int index -> + if (!matchesPattern(file, excludeMatchers)) { + if (isContractFile(file)) { + Path path = file.toPath() + Integer order = null + if (hasScenarioFilenamePattern(path)) { + order = index + } + result.put(file.parentFile.toPath(), new Contract(path, matchesPattern(file, ignoreMatchers), files.size(), order)) + } else { + appendRecursively(file, result) + } } } } + private boolean hasScenarioFilenamePattern(Path path) { + SCENARIO_STEP_FILENAME_PATTERN.matcher(path.fileName.toString()).matches() + } + boolean matchesPattern(File file, Set excludeMatchers) { for (PathMatcher matcher : excludeMatchers) { if (matcher.matches(file.toPath())) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index a8daa0af22..77abde0e80 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier +import io.codearte.accurest.file.Contract import spock.lang.Issue import spock.lang.Specification @@ -31,7 +32,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("#187") @@ -60,7 +61,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("\$[?(@.property2 == null)]") blockBuilder.toString().contains("\$[?(@.property3 == false)]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("#79") @@ -91,7 +92,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("#82") @@ -116,7 +117,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc then: blockBuilder.toString().contains("entity('{\"items\":[\"HOP\"]}', 'application/json')") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("#88") @@ -141,7 +142,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc then: blockBuilder.toString().contains("entity('property1=VAL1', 'application/octet-stream')") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate assertions for array in response body"() { @@ -170,7 +171,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate assertions for array inside response body element"() { @@ -198,7 +199,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate assertions for nested objects in response body"() { @@ -226,7 +227,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for map objects in response body"() { @@ -260,7 +261,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { @@ -288,7 +289,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should ignore 'Accept' header and use 'request' method"() { @@ -312,7 +313,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc then: blockBuilder.toString().contains("request('text/plain')") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should ignore 'Content-Type' header and use 'entity' method"() { @@ -340,7 +341,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("header('Timer', '123')") !blockBuilder.toString().contains("header('Content-Type'") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate a call with an url path and query parameters"() { @@ -390,7 +391,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc spockTest.contains('$[?(@.property2 == \'b\')]') spockTest.contains('$[?(@.property1 == \'a\')]') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue('#169') @@ -441,7 +442,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc spockTest.contains('$[?(@.property2 == \'b\')]') spockTest.contains('$[?(@.property1 == \'a\')]') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate test for empty body"() { @@ -464,7 +465,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc then: spockTest.contains("entity('', 'application/octet-stream')") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate test for String in response body"() { @@ -488,7 +489,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc spockTest.contains('String responseAsString = response.readEntity(String)') spockTest.contains('responseBody == "test"') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue('#171') @@ -517,7 +518,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc then: spockTest.contains(".method('GET')") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index ba403adcde..b02b507a4f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier +import io.codearte.accurest.file.Contract import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll @@ -37,7 +38,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("#187") @@ -66,7 +67,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$[?(@.property2 == null)]") blockBuilder.toString().contains("\$[?(@.property3 == false)]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("#79") @@ -97,7 +98,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("#82") @@ -122,7 +123,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: blockBuilder.toString().contains(".body('''{\"items\":[\"HOP\"]}''')") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("#88") @@ -147,7 +148,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: blockBuilder.toString().contains(".body('''property1=VAL1''')") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue("185") @@ -176,7 +177,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$.property[?(@.7 == 0.0)]") blockBuilder.toString().contains("\$.property[?(@.14 == 0.0)]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate assertions for array in response body"() { @@ -205,7 +206,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate assertions for array inside response body element"() { @@ -233,7 +234,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate assertions for nested objects in response body"() { @@ -261,7 +262,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for map objects in response body"() { @@ -295,7 +296,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { @@ -323,7 +324,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue(["#126", "#143"]) @@ -349,7 +350,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: blockBuilder.toString().contains("\$[?(@.property =~ /\\d+/)]") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate a call with an url path and query parameters"() { @@ -392,7 +393,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu spockTest.contains('$[?(@.property2 == \'b\')]') spockTest.contains('$[?(@.property1 == \'a\')]') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue('#169') @@ -436,7 +437,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu spockTest.contains('$[?(@.property2 == \'b\')]') spockTest.contains('$[?(@.property1 == \'a\')]') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate test for empty body"() { @@ -459,7 +460,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: spockTest.contains(".body('''''')") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate test for String in response body"() { @@ -483,7 +484,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu spockTest.contains('def responseBody = (response.body.asString())') spockTest.contains('responseBody == "test"') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue('113') @@ -518,7 +519,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue('115') @@ -553,7 +554,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should work with more complex stuff and jsonpaths"() { @@ -590,7 +591,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu spockTest.contains('''$.errors[*][?(@.property == 'bank_account_number')]''') spockTest.contains('''$.errors[*][?(@.message == 'incorrect_format')]''') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should work properly with GString url"() { @@ -619,7 +620,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu then: spockTest.contains('''/partners/11/agents/11/customers/09665703Z''') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy(contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should resolve properties in GString with regular expression"() { 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 866a451f47..43324a794c 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 @@ -2,6 +2,7 @@ package io.codearte.accurest.dsl import groovy.json.JsonBuilder import groovy.json.JsonSlurper +import io.codearte.accurest.file.Contract import io.codearte.accurest.util.AssertionUtil import spock.lang.Issue import spock.lang.Specification @@ -36,7 +37,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual(''' { @@ -81,7 +82,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual(''' { @@ -129,7 +130,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual(''' { @@ -181,7 +182,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -228,7 +229,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual(''' { @@ -276,7 +277,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -560,7 +561,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -615,7 +616,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -963,7 +964,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1136,7 +1137,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1170,7 +1171,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1218,7 +1219,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1269,7 +1270,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1298,7 +1299,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Unroll def 'should generate stub without optional parameters'() { when: - String wireMockStub = new WireMockStubStrategy(contractDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1396,7 +1397,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } String toWireMockClientJsonStub(groovyDsl) { - new WireMockStubStrategy(groovyDsl).toWireMockClientStub() + new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() } @Issue('180') @@ -1420,7 +1421,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy(contractDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub() then: println wireMockStub AssertionUtil.assertThatJsonsAreEqual((''' diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy index 537fb78ea2..6665a642e9 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.dsl + import com.github.tomakehurst.wiremock.stubbing.StubMapping import java.util.regex.Pattern diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy index d6c0fdd1d2..e02e06cc56 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.file +import com.google.common.collect.ListMultimap import com.google.common.collect.Multimap import spock.lang.Specification @@ -17,7 +18,7 @@ class ContractFileScannerSpec extends Specification { Set ignored = ["other/different/**"] as Set ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored) when: - Multimap result = scanner.findContracts() + ListMultimap result = scanner.findContracts() then: result.keySet().size() == 3 result.get(baseDir.toPath().resolve("different")).size() == 1 @@ -27,4 +28,18 @@ class ContractFileScannerSpec extends Specification { ignoredSet.size() == 1 ignoredSet.ignored == [true] } + + def "should find contracts group in scenario"() { + given: + File baseDir = new File(this.getClass().getResource("/directory/with/scenario").toURI()) + ContractFileScanner scanner = new ContractFileScanner(baseDir, [] as Set, [] as Set) + when: + ListMultimap contracts = scanner.findContracts() + then: + contracts.values().size() == 3 + contracts.values().find { it.path.fileName.toString().startsWith('01') }.groupSize == 3 + contracts.values().find { it.path.fileName.toString().startsWith('01') }.order == 0 + contracts.values().find { it.path.fileName.toString().startsWith('02') }.order == 1 + contracts.values().find { it.path.fileName.toString().startsWith('03') }.order == 2 + } } diff --git a/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy b/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy new file mode 100644 index 0000000000..66ef387158 --- /dev/null +++ b/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy @@ -0,0 +1 @@ +package directory.with.scenario \ No newline at end of file diff --git a/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy b/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy new file mode 100644 index 0000000000..66ef387158 --- /dev/null +++ b/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy @@ -0,0 +1 @@ +package directory.with.scenario \ No newline at end of file diff --git a/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy b/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy new file mode 100644 index 0000000000..66ef387158 --- /dev/null +++ b/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy @@ -0,0 +1 @@ +package directory.with.scenario \ No newline at end of file From fee01ce347b67f06c35ff46f52ad4466ec73456c Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Mon, 8 Feb 2016 00:05:50 +0100 Subject: [PATCH 276/719] Add functional test and fix code review --- .../accurest/SingleTestGenerator.groovy | 2 +- .../accurest/builder/MethodBuilder.groovy | 2 +- .../accurest/config/TestFramework.groovy | 4 +- .../directory/with/scenario/01_login.groovy | 1 - .../with/scenario/02_showCart.groovy | 1 - .../directory/with/scenario/03_logout.groovy | 1 - .../plugin/ScenarioProjectSpec.groovy | 21 +++ .../scenarioProject/build.gradle | 92 ++++++++++ .../1_shouldMarkClientAsNotFraud.groovy | 28 +++ .../2_shouldMarkClientAsFraud.groovy | 27 +++ .../frauddetection/Application.java | 17 ++ .../FraudDetectionController.java | 39 +++++ .../frauddetection/model/FraudCheck.java | 29 ++++ .../model/FraudCheckResult.java | 32 ++++ .../model/FraudCheckStatus.java | 5 + .../src/main/resources/application.yml | 1 + .../com/blogspot/toomuchcoding/MvcSpec.groovy | 15 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 50514 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .../functionalTest/scenarioProject/gradlew | 164 ++++++++++++++++++ .../scenarioProject/gradlew.bat | 90 ++++++++++ .../loanApplicationService/mappings/.gitkeep | 0 .../frauddetection/Application.java | 17 ++ .../LoanApplicationService.java | 68 ++++++++ .../frauddetection/model/Client.java | 14 ++ .../model/FraudCheckStatus.java | 5 + .../model/FraudServiceRequest.java | 34 ++++ .../model/FraudServiceResponse.java | 27 +++ .../frauddetection/model/LoanApplication.java | 36 ++++ .../model/LoanApplicationResult.java | 32 ++++ .../model/LoanApplicationStatus.java | 5 + .../src/main/resources/application.yml | 1 + .../LoanApplicationServiceSpec.groovy | 58 +++++++ .../shouldMarkClientAsFraud.json | 23 +++ .../shouldMarkClientAsNotFraud.json | 23 +++ .../scenarioProject/settings.gradle | 2 + 36 files changed, 915 insertions(+), 7 deletions(-) create mode 100755 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties create mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 99d7915e9f..b90e794d71 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -40,7 +40,7 @@ class SingleTestGenerator { } if (isScenarioClass(listOfFiles)) { - clazz.addImport(configProperties.targetFramework.getOrderClass()) + clazz.addImport(configProperties.targetFramework.getOrderAnnotationImport()) clazz.addClassLevelAnnotation(configProperties.targetFramework.getOrderAnnotation()) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index 2007d05b1b..9f0ba231d7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -43,7 +43,7 @@ class MethodBuilder { if (ignored) { blockBuilder.addLine('@Ignore') } - blockBuilder.addLine(configProperties.targetFramework.methodModifier + "$methodName() {") + blockBuilder.addLine(configProperties.targetFramework.methodModifier + "validate_$methodName() {") getMethodBodyBuilder().appendTo(blockBuilder) blockBuilder.addLine('}') } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy index 9aeacf1b3e..c1014f19de 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy @@ -52,8 +52,8 @@ enum TestFramework { return ignoreClass } - String getOrderClass() { - return orderClass + String getOrderAnnotationImport() { + return orderAnnotationImport } String getOrderAnnotation() { diff --git a/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy b/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy index 66ef387158..e69de29bb2 100644 --- a/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy +++ b/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy @@ -1 +0,0 @@ -package directory.with.scenario \ No newline at end of file diff --git a/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy b/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy index 66ef387158..e69de29bb2 100644 --- a/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy +++ b/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy @@ -1 +0,0 @@ -package directory.with.scenario \ No newline at end of file diff --git a/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy b/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy index 66ef387158..e69de29bb2 100644 --- a/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy +++ b/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy @@ -1 +0,0 @@ -package directory.with.scenario \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy new file mode 100755 index 0000000000..ea7d0e27e3 --- /dev/null +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy @@ -0,0 +1,21 @@ +package io.codearte.accurest.plugin + +import nebula.test.IntegrationSpec +import spock.lang.Stepwise + +@Stepwise +class ScenarioProjectSpec extends IntegrationSpec { + + void setup() { + copyResources("functionalTest/scenarioProject", "") + runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it + } + + def "should pass basic flow"() { + given: + assert fileExists('build.gradle') + expect: + runTasksSuccessfully('check') + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle new file mode 100644 index 0000000000..25ca064fc4 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -0,0 +1,92 @@ +buildscript { + repositories { + mavenCentral() + mavenLocal() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:1.2.6.RELEASE") + } +} + +ext { + restAssuredVersion = '2.5.0' + spockVersion = '1.0-groovy-2.4' + wiremockVersion = '2.0.5-beta' + + accurestStubsBaseDirectory = 'src/test/resources/stubs' +} + +subprojects { + apply plugin: 'groovy' + + repositories { + mavenCentral() + mavenLocal() + } + + dependencies { + testCompile "org.codehaus.groovy:groovy-all:2.4.5" + testCompile "org.spockframework:spock-core:$spockVersion" + testCompile("junit:junit:4.12") + testCompile "com.github.tomakehurst:wiremock:$wiremockVersion" + } +} + +configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { + apply plugin: 'spring-boot' + apply plugin: 'accurest' + + ext { + wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") + wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'mappings/') + } + + accurest { + targetFramework = 'Spock' + testMode = 'MockMvc' + baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' + contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") + generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") + stubsOutputDir = wireMockStubsOutputDir + } + + jar { + version = '0.0.1' + } + + dependencies { + compile("org.springframework.boot:spring-boot-starter-web") { + exclude module: "spring-boot-starter-tomcat" + } + compile("org.springframework.boot:spring-boot-starter-jetty") + compile("org.springframework.boot:spring-boot-starter-actuator") + + testRuntime "org.spockframework:spock-spring:$spockVersion" + testCompile "org.springframework:spring-test" + testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" + testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" + } + + task cleanup(type: Delete) { + delete 'src/test/resources/mappings', 'src/test/resources/stubs' + } + + clean.dependsOn('cleanup') + +} + +configure(project(':fraudDetectionService')) { + test.dependsOn('generateWireMockClientStubs') +} + +configure(project(':loanApplicationService')) { + + task copyCollaboratorStubs(type: Copy) { + File fraudBuildDir = project(':fraudDetectionService').buildDir + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) + into "src/test/resources/" + } + + generateAccurest.dependsOn('copyCollaboratorStubs') +} + diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy new file mode 100644 index 0000000000..7bc64d0dac --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy @@ -0,0 +1,28 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy new file mode 100644 index 0000000000..44b1c08604 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy @@ -0,0 +1,27 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java new file mode 100644 index 0000000000..5a1a60244e --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -0,0 +1,17 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java new file mode 100644 index 0000000000..e264462cce --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java @@ -0,0 +1,39 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheck; +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckResult; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.math.BigDecimal; + +import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.FRAUD; +import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.OK; +import static org.springframework.web.bind.annotation.RequestMethod.PUT; + +@RestController +public class FraudDetectionController { + + private static final String FRAUD_SERVICE_JSON_VERSION_1 = "application/vnd.fraud.v1+json"; + private static final String NO_REASON = null; + private static final String AMOUNT_TOO_HIGH = "Amount too high"; + private static final BigDecimal MAX_AMOUNT = new BigDecimal("5000"); + + @RequestMapping( + value = "/fraudcheck", + method = PUT, + consumes = FRAUD_SERVICE_JSON_VERSION_1, + produces = FRAUD_SERVICE_JSON_VERSION_1) + public FraudCheckResult fraudCheck(@RequestBody FraudCheck fraudCheck) { + if (amountGreaterThanThreshold(fraudCheck)) { + return new FraudCheckResult(FRAUD, AMOUNT_TOO_HIGH); + } + return new FraudCheckResult(OK, NO_REASON); + } + + private boolean amountGreaterThanThreshold(FraudCheck fraudCheck) { + return MAX_AMOUNT.compareTo(fraudCheck.getLoanAmount()) < 0; + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java new file mode 100644 index 0000000000..77471aee19 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java @@ -0,0 +1,29 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class FraudCheck { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudCheck() { + } + + public String getClientPesel() { + return clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java new file mode 100644 index 0000000000..28efc573f5 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java @@ -0,0 +1,32 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class FraudCheckResult { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudCheckResult() { + } + + public FraudCheckResult(FraudCheckStatus fraudCheckStatus, String rejectionReason) { + this.fraudCheckStatus = fraudCheckStatus; + this.rejectionReason = rejectionReason; + } + + public FraudCheckStatus getFraudCheckStatus() { + return fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b87c365d51 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml new file mode 100644 index 0000000000..a30a91f034 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml @@ -0,0 +1 @@ +server.port=8085 \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy new file mode 100644 index 0000000000..bcb6ef1579 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy @@ -0,0 +1,15 @@ +package com.blogspot.toomuchcoding + +import com.blogspot.toomuchcoding.frauddetection.FraudDetectionController +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import spock.lang.Specification + +class MvcSpec extends Specification { + def setup() { + RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) + } + + void assertThatRejectionReasonIsNull(def rejectionReason) { + assert !rejectionReason + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..667288ad6c2b3b87c990ece1267e56f0bcbf3622 GIT binary patch literal 50514 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 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +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"` + + # 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 "$@" diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat new file mode 100644 index 0000000000..8a0b282aa6 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat @@ -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 Windowz 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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java new file mode 100644 index 0000000000..5a1a60244e --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -0,0 +1,17 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java new file mode 100644 index 0000000000..a2d8ce1e74 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java @@ -0,0 +1,68 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus; +import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceRequest; +import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceResponse; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult; +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +@Service +public class LoanApplicationService { + + private static final String FRAUD_SERVICE_JSON_VERSION_1 = + "application/vnd.fraud.v1+json"; + + private final RestTemplate restTemplate; + + private int port = 8080; + + public LoanApplicationService() { + this.restTemplate = new RestTemplate(); + } + + public LoanApplicationResult loanApplication(LoanApplication loanApplication) { + FraudServiceRequest request = + new FraudServiceRequest(loanApplication); + + FraudServiceResponse response = + sendRequestToFraudDetectionService(request); + + return buildResponseFromFraudResult(response); + } + + private FraudServiceResponse sendRequestToFraudDetectionService( + FraudServiceRequest request) { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(HttpHeaders.CONTENT_TYPE, FRAUD_SERVICE_JSON_VERSION_1); + + ResponseEntity response = + restTemplate.exchange("http://localhost:" + port + "/fraudcheck", HttpMethod.PUT, + new HttpEntity<>(request, httpHeaders), + FraudServiceResponse.class); + + return response.getBody(); + } + + private LoanApplicationResult buildResponseFromFraudResult(FraudServiceResponse response) { + LoanApplicationStatus applicationStatus = null; + if (FraudCheckStatus.OK == response.getFraudCheckStatus()) { + applicationStatus = LoanApplicationStatus.LOAN_APPLIED; + } else if (FraudCheckStatus.FRAUD == response.getFraudCheckStatus()) { + applicationStatus = LoanApplicationStatus.LOAN_APPLICATION_REJECTED; + } + + return new LoanApplicationResult(applicationStatus, response.getRejectionReason()); + } + + public void setPort(int port) { + this.port = port; + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java new file mode 100644 index 0000000000..5e91273eda --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java @@ -0,0 +1,14 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class Client { + + private String pesel; + + public String getPesel() { + return pesel; + } + + public void setPesel(String pesel) { + this.pesel = pesel; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b87c365d51 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java new file mode 100644 index 0000000000..ac595998bc --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java @@ -0,0 +1,34 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class FraudServiceRequest { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudServiceRequest() { + } + + public FraudServiceRequest(LoanApplication loanApplication) { + this.clientPesel = loanApplication.getClient().getPesel(); + this.loanAmount = loanApplication.getAmount(); + } + + public String getClientPesel() { + return clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java new file mode 100644 index 0000000000..9f3353ecbf --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java @@ -0,0 +1,27 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class FraudServiceResponse { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudServiceResponse() { + } + + public FraudCheckStatus getFraudCheckStatus() { + return fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java new file mode 100644 index 0000000000..816087988b --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java @@ -0,0 +1,36 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class LoanApplication { + + private Client client; + + private BigDecimal amount; + + private String loanApplicationId; + + public Client getClient() { + return client; + } + + public void setClient(Client client) { + this.client = client; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + public String getLoanApplicationId() { + return loanApplicationId; + } + + public void setLoanApplicationId(String loanApplicationId) { + this.loanApplicationId = loanApplicationId; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java new file mode 100644 index 0000000000..523f4f2ea3 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java @@ -0,0 +1,32 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class LoanApplicationResult { + + private LoanApplicationStatus loanApplicationStatus; + + private String rejectionReason; + + public LoanApplicationResult() { + } + + public LoanApplicationResult(LoanApplicationStatus loanApplicationStatus, String rejectionReason) { + this.loanApplicationStatus = loanApplicationStatus; + this.rejectionReason = rejectionReason; + } + + public LoanApplicationStatus getLoanApplicationStatus() { + return loanApplicationStatus; + } + + public void setLoanApplicationStatus(LoanApplicationStatus loanApplicationStatus) { + this.loanApplicationStatus = loanApplicationStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java new file mode 100644 index 0000000000..7f7f86e0ea --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum LoanApplicationStatus { + LOAN_APPLIED, LOAN_APPLICATION_REJECTED +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml new file mode 100644 index 0000000000..e86bbd0e0f --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml @@ -0,0 +1 @@ +server.port=8090 \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy new file mode 100644 index 0000000000..5a7d0ae9a9 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy @@ -0,0 +1,58 @@ +package com.blogspot.toomuchcoding + +import com.blogspot.toomuchcoding.frauddetection.Application +import com.blogspot.toomuchcoding.frauddetection.LoanApplicationService +import com.blogspot.toomuchcoding.frauddetection.model.Client +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult +import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus +import com.github.tomakehurst.wiremock.junit.WireMockClassRule +import org.junit.ClassRule +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.test.context.ContextConfiguration +import spock.lang.Shared +import spock.lang.Specification +import spock.lang.Stepwise + +@ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) +@Stepwise +class LoanApplicationServiceSpec extends Specification { + + public static int port = org.springframework.util.SocketUtils.findAvailableTcpPort() + + @ClassRule + @Shared + WireMockClassRule wireMockRule = new WireMockClassRule(port) + + @Autowired + LoanApplicationService sut + + def setup() { + sut.port = port + } + + def 'should successfully apply for loan'() { + given: + LoanApplication application = + new LoanApplication(client: new Client(pesel: '1234567890'), amount: 123.123) + when: + LoanApplicationResult loanApplication = sut.loanApplication(application) + then: + loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED + loanApplication.rejectionReason == null + } + + def 'should be rejected due to abnormal loan amount'() { + given: + LoanApplication application = + new LoanApplication(client: new Client(pesel: '1234567890'), amount: 99_999) + when: + LoanApplicationResult loanApplication = sut.loanApplication(application) + then: + loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLICATION_REJECTED + loanApplication.rejectionReason == 'Amount too high' + } + + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json new file mode 100644 index 0000000000..157726ca2e --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"99999\"}" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"FRAUD\",\"rejectionReason\":\"Amount too high\"}" + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json new file mode 100644 index 0000000000..afa27159d9 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json @@ -0,0 +1,23 @@ +{ + "request": { + "method": "PUT", + "headers": { + "Content-Type": { + "equalTo": "application/vnd.fraud.v1+json" + } + }, + "url": "/fraudcheck", + "bodyPatterns": [ + { + "matches": "{\"clientPesel\":\"[0-9]{10}\",\"loanAmount\":\"123.123\"}" + } + ] + }, + "response": { + "status": 200, + "headers": { + "Content-Type": "application/vnd.fraud.v1+json" + }, + "body": "{\"fraudCheckStatus\":\"OK\",\"rejectionReason\":null}" + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle new file mode 100644 index 0000000000..6a42a6c7ce --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle @@ -0,0 +1,2 @@ +include ':fraudDetectionService' +include ':loanApplicationService' From c1a418b16a391bf42441a09966f2eb4b732d2461 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 8 Feb 2016 10:37:03 +0100 Subject: [PATCH 277/719] Raised axion plugin version. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 42d265f044..250be22775 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { mavenLocal() } dependencies { - classpath "pl.allegro.tech.build:axion-release-plugin:1.2.2" + classpath "pl.allegro.tech.build:axion-release-plugin:1.3.4" classpath "com.bmuschko:gradle-nexus-plugin:2.3" classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.5.3" } From cb50c194cd46027098183c137341d3ec2471bdd4 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 8 Feb 2016 10:37:22 +0100 Subject: [PATCH 278/719] Release version: 1.0.0-RC1 [ci skip] From 0e7f739a453cab832b591cb1b08414a433a920ec Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 8 Feb 2016 10:37:22 +0100 Subject: [PATCH 279/719] Release version: 1.0.0-RC1 [ci skip] From 5388ead6460c6236bb9fcff41126c7ac57ea2e6d Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 8 Feb 2016 10:37:22 +0100 Subject: [PATCH 280/719] Release version: 1.0.0-RC1 [ci skip] From a9e837ed88b2406bc687bf0c8cedf810bb67adf1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 8 Feb 2016 21:33:32 +0100 Subject: [PATCH 281/719] [#134] Asserting JSON via JSON Assert --- .../accurest/SingleTestGenerator.groovy | 21 +- .../builder/SpockMethodBodyBuilder.groovy | 4 +- .../config/AccurestConfigProperties.groovy | 5 + .../dsl/WireMockRequestStubStrategy.groovy | 2 +- .../accurest/dsl/internal/Headers.groovy | 11 + .../util/DelegatingJsonVerifiable.java | 227 ++++++++++ .../FinishedDelegatingJsonVerifiable.java | 19 + .../accurest/util/JsonPathEntry.groovy | 40 -- .../codearte/accurest/util/JsonPaths.groovy | 19 +- .../util/JsonToJsonPathsConverter.groovy | 143 ++++--- .../accurest/util/MethodBuffering.java | 9 + .../util/MethodBufferingJsonVerifiable.java | 49 +++ .../util/MethodBufferingReadyToCheck.java | 8 + .../accurest/util/ShouldTraverse.java | 12 + .../JaxRsClientSpockMethodBuilderSpec.groovy | 58 +-- .../MockMvcSpockMethodBuilderSpec.groovy | 65 ++- .../util/JsonToJsonPathsConverterSpec.groovy | 396 ++++++++++++++++-- .../plugin/AccurestGradlePlugin.groovy | 3 +- ...erateWireMockClientStubsFromDslTask.groovy | 1 - .../functionalTest/bootSimple/build.gradle | 1 + build.gradle | 1 + gradle.properties | 1 + 22 files changed, 870 insertions(+), 225 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBuffering.java create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingReadyToCheck.java create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/ShouldTraverse.java diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index b90e794d71..afb839a3ef 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest 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 @@ -11,8 +12,12 @@ import static io.codearte.accurest.builder.ClassBuilder.createClass import static io.codearte.accurest.builder.MethodBuilder.createTestMethod import static io.codearte.accurest.util.NamesUtil.capitalize +@Slf4j class SingleTestGenerator { + private static final String JSON_ASSERT_STATIC_IMPORT = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThat' + private static final String JSON_ASSERT_CLASS = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion' + private final AccurestConfigProperties configProperties SingleTestGenerator(AccurestConfigProperties configProperties) { @@ -76,8 +81,20 @@ class SingleTestGenerator { private ClassBuilder addJsonPathRelatedImports(ClassBuilder clazz) { clazz.addImport(['com.jayway.jsonpath.DocumentContext', - 'com.jayway.jsonpath.JsonPath', - 'net.minidev.json.JSONArray']) + 'com.jayway.jsonpath.JsonPath']) + if (jsonAssertPresent()) { + clazz.addStaticImport(JSON_ASSERT_STATIC_IMPORT) + } + } + + private static boolean jsonAssertPresent() { + try { + Class.forName(JSON_ASSERT_CLASS) + return true + } catch (ClassNotFoundException e) { + log.debug("JsonAssert is not present on classpath. Will not add a static import") + return false + } } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index ecff2bc043..c5202cad39 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -90,9 +90,7 @@ abstract class SpockMethodBodyBuilder { appendJsonPath(bb, responseAsString) JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) jsonPaths.each { - it.buildJsonPathComparison('parsedJson').each { - bb.addLine(it) - } + bb.addLine("assertThat(parsedJson)" + it.method()) } processBodyElement(bb, "", responseBody) } else if (contentType == ContentType.XML) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy index fbf299f525..88c6574471 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy @@ -34,6 +34,11 @@ class AccurestConfigProperties { */ String ruleClassForTests + /** + * Which version of JSON Assert (com.blogspot.toomuchcoding:jsonassert) to use + */ + String jsonAssertVersion = "+" + /** * Patterns that should not be taken into account for processing */ diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index 03304bdbc3..f1c618cbd0 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -68,7 +68,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT, equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ] } else { - requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath) } ?: null + requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath()) } ?: null } } else if (contentType == ContentType.XML) { requestPattern.bodyPatterns = [new ValuePattern(equalToXml: getMatchingStrategy(request.body.clientValue).clientValue.toString())] diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy index d9c1bc85b7..27dd9bf192 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy @@ -26,4 +26,15 @@ class Headers { } } + boolean equals(o) { + if (this.is(o)) return true + if (getClass() != o.class) return false + Headers headers = (Headers) o + if (entries != headers.entries) return false + return true + } + + int hashCode() { + return entries.hashCode() + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java new file mode 100644 index 0000000000..28a95c8a8b --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -0,0 +1,227 @@ +package io.codearte.accurest.util; + +import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; + +/** + * @author Marcin Grzejszczak + */ +class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { + + private final JsonVerifiable delegate; + private final StringBuffer methodsBuffer; + + DelegatingJsonVerifiable(JsonVerifiable delegate, + StringBuffer methodsBuffer) { + this.delegate = delegate; + this.methodsBuffer = new StringBuffer(methodsBuffer.toString()); + } + + DelegatingJsonVerifiable(JsonVerifiable delegate) { + this.delegate = delegate; + this.methodsBuffer = new StringBuffer(); + } + + private static String stringWithEscapedQuotes(Object object) { + String stringValue = object.toString(); + return stringValue.replaceAll("\"", "\\\\\""); + } + + private static String wrapValueWithQuotes(Object value) { + return value instanceof String ? + "\"" + stringWithEscapedQuotes(value).replaceAll("\\$", "\\\\\\$") + "\"" : + value.toString(); + } + + @Override + public MethodBufferingJsonVerifiable contains(Object value) { + DelegatingJsonVerifiable verifiable = new FinishedDelegatingJsonVerifiable(delegate.contains(value), methodsBuffer); + verifiable.methodsBuffer.append(".contains(").append(wrapValueWithQuotes(value)) + .append(")"); + if (isAssertingAValueInArray()) { + verifiable.methodsBuffer.append(".value()"); + } + return verifiable; + } + + @Override + public MethodBufferingJsonVerifiable field(Object value) { + Object valueToPut = value instanceof ShouldTraverse ? ((ShouldTraverse) value).value : value; + DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.field(valueToPut), methodsBuffer); + if (delegate.isIteratingOverArray() && !(value instanceof ShouldTraverse)) { + verifiable.methodsBuffer.append(".contains(").append(wrapValueWithQuotes(valueToPut)) + .append(")"); + } else { + verifiable.methodsBuffer.append(".field(").append(wrapValueWithQuotes(valueToPut)) + .append(")"); + } + return verifiable; + } + + @Override + public MethodBufferingJsonVerifiable array(Object value) { + DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.array(value), methodsBuffer); + verifiable.methodsBuffer.append(".array(").append(wrapValueWithQuotes(value)) + .append(")"); + return verifiable; + } + + @Override + public MethodBufferingJsonVerifiable arrayField(Object value) { + DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.field(value).arrayField(), methodsBuffer); + verifiable.methodsBuffer.append(".array(").append(wrapValueWithQuotes(value)) + .append(")"); + return verifiable; + } + + @Override + public MethodBufferingJsonVerifiable arrayField() { + return new DelegatingJsonVerifiable(delegate.arrayField(), methodsBuffer); + } + + @Override + public MethodBufferingJsonVerifiable array() { + DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.array(), methodsBuffer); + verifiable.methodsBuffer.append(".array()"); + return verifiable; + } + + @Override + public MethodBufferingJsonVerifiable iterationPassingArray() { + return new DelegatingJsonVerifiable(delegate, methodsBuffer); + } + + @Override + public MethodBufferingJsonVerifiable isEqualTo(String value) { + DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer); + if (delegate.isAssertingAValueInArray()) { + readyToCheck.methodsBuffer.append(".value()"); + } else { + readyToCheck.methodsBuffer.append(".isEqualTo(") + .append(wrapValueWithQuotes(value)).append(")"); + } + return readyToCheck; + } + + @Override + public MethodBufferingJsonVerifiable isEqualTo(Object value) { + if (value == null) { + return isNull(); + } + return isEqualTo(value.toString()); + } + + @Override + public MethodBufferingJsonVerifiable isEqualTo(Number value) { + DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer); + if (delegate.isAssertingAValueInArray()) { + readyToCheck.methodsBuffer.append(".value()"); + } else { + readyToCheck.methodsBuffer.append(".isEqualTo(").append(String.valueOf(value)) + .append(")"); + } + return readyToCheck; + } + + @Override + public MethodBufferingJsonVerifiable isNull() { + DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isNull(), methodsBuffer); + readyToCheck.methodsBuffer.append(".isNull()"); + return readyToCheck; + } + + @Override + public MethodBufferingJsonVerifiable matches(String value) { + DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.matches(value), methodsBuffer); + if (delegate.isAssertingAValueInArray()) { + readyToCheck.methodsBuffer.append(".value()"); + } else { + readyToCheck.methodsBuffer.append(".matches(").append(wrapValueWithQuotes(value)) + .append(")"); + } + return readyToCheck; + } + + @Override + public MethodBufferingJsonVerifiable isEqualTo(Boolean value) { + DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer); + if (delegate.isAssertingAValueInArray()) { + readyToCheck.methodsBuffer.append(".value()"); + } else { + readyToCheck.methodsBuffer.append(".isEqualTo(").append(String.valueOf(value)) + .append(")"); + } + return readyToCheck; + } + + @Override + public MethodBufferingJsonVerifiable value() { + return new FinishedDelegatingJsonVerifiable(delegate, methodsBuffer); + } + + @Override + public JsonVerifiable withoutThrowingException() { + return delegate.withoutThrowingException(); + } + + @Override + public String jsonPath() { + return delegate.jsonPath(); + } + + @Override + public void matchesJsonPath(String s) { + delegate.matchesJsonPath(s); + } + + @Override + public boolean isIteratingOverNamelessArray() { + return delegate.isIteratingOverNamelessArray(); + } + + @Override + public boolean isIteratingOverArray() { + return delegate.isIteratingOverArray(); + } + + @Override + public boolean isAssertingAValueInArray() { + return delegate.isAssertingAValueInArray(); + } + + @Override + public String method() { + return methodsBuffer.toString(); + } + + @Override + public boolean equals(Object o) { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + DelegatingJsonVerifiable that = (DelegatingJsonVerifiable) o; + + if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) + return false; + return methodsBuffer != null ? + methodsBuffer.equals(that.methodsBuffer) : + that.methodsBuffer == null; + + } + + @Override + public int hashCode() { + int result = delegate != null ? delegate.hashCode() : 0; + result = 31 * result + (methodsBuffer != null ? methodsBuffer.hashCode() : 0); + return result; + } + + @Override + public String toString() { + return "DelegatingJsonVerifiable{" + + "delegate=\n" + delegate + + ", methodsBuffer=" + methodsBuffer + + '}'; + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java new file mode 100644 index 0000000000..7167ac6a97 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java @@ -0,0 +1,19 @@ +package io.codearte.accurest.util; + +import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; + +/** + * @author Marcin Grzejszczak + */ +class FinishedDelegatingJsonVerifiable extends DelegatingJsonVerifiable { + + FinishedDelegatingJsonVerifiable(JsonVerifiable delegate, + StringBuffer methodsBuffer) { + super(delegate, methodsBuffer); + } + + FinishedDelegatingJsonVerifiable(JsonVerifiable delegate) { + super(delegate, new StringBuffer()); + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy deleted file mode 100644 index be1638027e..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPathEntry.groovy +++ /dev/null @@ -1,40 +0,0 @@ -package io.codearte.accurest.util - -import java.util.regex.Pattern - -class JsonPathEntry { - final String jsonPath - final String optionalSuffix - final Object value - - JsonPathEntry(String jsonPath, String optionalSuffix, Object value) { - this.jsonPath = jsonPath - this.optionalSuffix = optionalSuffix - this.value = value - } - - List buildJsonPathComparison(String parsedJsonVariable) { - if (optionalSuffix) { - return ["!${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).empty"] - } else if (traversesOverCollections()) { - return ["${parsedJsonVariable}.read('''${jsonPath}''', JSONArray).get(0) ${operator()} ${potentiallyWrappedWithQuotesValue()}"] - } - return ["${parsedJsonVariable}.read('''${jsonPath}''') ${operator()} ${potentiallyWrappedWithQuotesValue()}"] - } - - private boolean traversesOverCollections() { - return jsonPath.contains('[*]') - } - - String operator() { - return value instanceof Pattern ? "==~" : "==" - } - - String potentiallyWrappedWithQuotesValue() { - return value instanceof Number ? value : "'''$value'''" - } - - static JsonPathEntry simple(String jsonPath, Object value) { - return new JsonPathEntry(jsonPath, "", value) - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy index 6c4aad1214..d3786b757e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy @@ -1,23 +1,6 @@ package io.codearte.accurest.util -class JsonPaths extends HashSet { +class JsonPaths extends HashSet { - Object getAt(String key) { - return find { - it.jsonPath == key - }?.value - } - - Object putAt(String key, Object value) { - JsonPathEntry entry = find { - it.jsonPath == key - } - if (!entry) { - return null - } - Object oldValue = entry.value - add(new JsonPathEntry(entry.jsonPath, entry.optionalSuffix, value)) - return oldValue - } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 46dd08003b..9a66bf0561 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -1,9 +1,12 @@ package io.codearte.accurest.util -import java.util.regex.Pattern + +import com.blogspot.toomuchcoding.jsonassert.JsonAssertion +import groovy.json.JsonOutput import groovy.json.JsonSlurper import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.OptionalProperty +import java.util.regex.Pattern /** * @author Marcin Grzejszczak */ @@ -12,9 +15,6 @@ class JsonToJsonPathsConverter { private static final Boolean SERVER_SIDE = false private static final Boolean CLIENT_SIDE = true - public static final String ROOT_JSON_PATH_ELEMENT = '$' - public static final String ALL_ELEMENTS = "[*]" - public static JsonPaths transformToJsonPathWithTestsSideValues(def json) { return transformToJsonPathWithValues(json, SERVER_SIDE) } @@ -29,17 +29,19 @@ class JsonToJsonPathsConverter { } JsonPaths pathsAndValues = [] as Set Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide) - traverseRecursivelyForKey(convertedJson, ROOT_JSON_PATH_ELEMENT) { String key, Object value -> - if (value instanceof ExecutionProperty) { + MethodBufferingJsonVerifiable methodBufferingJsonPathVerifiable = + new DelegatingJsonVerifiable(JsonAssertion.assertThat(JsonOutput.toJson(convertedJson)).withoutThrowingException()) + traverseRecursivelyForKey(convertedJson, methodBufferingJsonPathVerifiable) + { MethodBufferingJsonVerifiable key, Object value -> + if (value instanceof ExecutionProperty || !(key instanceof FinishedDelegatingJsonVerifiable)) { return } - JsonPathEntry entry = getValueToInsert(key, value) - pathsAndValues.add(entry) + pathsAndValues.add(key) } return pathsAndValues } - protected static def traverseRecursively(Class parentType, String key, def value, Closure closure) { + protected static def traverseRecursively(Class parentType, MethodBufferingJsonVerifiable key, def value, Closure closure) { if (value instanceof String && value) { try { def json = new JsonSlurper().parseText(value) @@ -47,7 +49,7 @@ class JsonToJsonPathsConverter { return convertWithKey(parentType, key, json, closure) } } catch (Exception ignore) { - return closure(key, value) + return runClosure(closure, key, value) } } else if (isAnEntryWithNonCollectionLikeValue(value)) { return convertWithKey(List, key, value as Map, closure) @@ -56,18 +58,51 @@ class JsonToJsonPathsConverter { } else if (value instanceof Map) { return convertWithKey(Map, key, value as Map, closure) } else if (value instanceof List) { + MethodBufferingJsonVerifiable jsonPathVerifiable = createAsserterFromList(key, value) value.each { def element -> - traverseRecursively(List, "$key[*]", element, closure) + traverseRecursively(List, createAsserterFromListElement(jsonPathVerifiable, element), + element, closure) } return value + } else if (key.isIteratingOverArray()) { + traverseRecursively(Object, key.arrayField().contains(value), value, closure) } try { - return closure(key, value) + return runClosure(closure, key, value) } catch (Exception ignore) { return value } } + private static MethodBufferingJsonVerifiable createAsserterFromList(MethodBufferingJsonVerifiable key, List value) { + if (key.isIteratingOverNamelessArray()) { + return key.array() + } else if (key.isIteratingOverArray() && isAnEntryWithLists(value)) { + if (!value.every { listContainsOnlyPrimitives(it as List)} ) { + return key.array() + } else { + return key.iterationPassingArray() + } + } else if (key.isIteratingOverArray()) { + return key.iterationPassingArray() + } + return key + } + + private static MethodBufferingJsonVerifiable createAsserterFromListElement(MethodBufferingJsonVerifiable jsonPathVerifiable, def element) { + if (jsonPathVerifiable.isAssertingAValueInArray()) { + return jsonPathVerifiable.contains(element) + } + return jsonPathVerifiable + } + + private static def runClosure(Closure closure, MethodBufferingJsonVerifiable key, def value) { + if (key.isAssertingAValueInArray()) { + return closure(valueToAsserter(key, value), value) + } + return closure(key, value) + } + private static boolean isAnEntryWithNonCollectionLikeValue(def value) { if (!(value instanceof Map)) { return false @@ -87,74 +122,52 @@ class JsonToJsonPathsConverter { } Map valueAsMap = ((Map) value) return valueAsMap.entrySet().every { Map.Entry entry -> - [String, Number].any { entry.value.getClass().isAssignableFrom(it) } + [String, Number, Boolean].any { it.isAssignableFrom(entry.value.getClass()) } } } - private static Map convertWithKey(Class parentType, String parentKey, Map map, Closure closureToExecute) { + private static boolean listContainsOnlyPrimitives(List list) { + return list.every { def element -> + [String, Number, Boolean].any { + it.isAssignableFrom(element.getClass()) + } + } + } + private static boolean isAnEntryWithLists(def value) { + if (!(value instanceof Iterable)) { + return false + } + return value.every { def entry -> + entry instanceof List + } + } + + private static Map convertWithKey(Class parentType, MethodBufferingJsonVerifiable parentKey, Map map, Closure closureToExecute) { return map.collectEntries { Object entrykey, value -> - [entrykey, traverseRecursively(parentType, "${parentKey}.${entrykey}", value, closureToExecute)] + [entrykey, traverseRecursively(parentType, + value instanceof List ? listContainsOnlyPrimitives(value) ? + parentKey.arrayField(entrykey) : + parentKey.array(entrykey) : + value instanceof Map ? parentKey.field(new ShouldTraverse(entrykey)) : + valueToAsserter(parentKey.field(entrykey), value) + , value, closureToExecute)] } } - private static void traverseRecursivelyForKey(def json, String rootKey, Closure closure) { + private static void traverseRecursivelyForKey(def json, MethodBufferingJsonVerifiable rootKey, Closure closure) { traverseRecursively(Map, rootKey, json, closure) } - private static JsonPathEntry getValueToInsert(String key, Object value) { - return convertToListElementFiltering(key, value) - } - - protected static JsonPathEntry convertToListElementFiltering(String key, Object value) { - if (key.endsWith(ALL_ELEMENTS)) { - int lastAllElements = key.lastIndexOf(ALL_ELEMENTS) - String keyWithoutAllElements = key.substring(0, lastAllElements) - return JsonPathEntry.simple("""$keyWithoutAllElements[?(@ ${compareWith(value)})]""".toString(), value) - } - return getKeyForTraversalOfListWithNonPrimitiveTypes(key, value) - } - - private static JsonPathEntry getKeyForTraversalOfListWithNonPrimitiveTypes(String key, Object value) { - int lastDot = key.lastIndexOf('.') - String keyWithoutLastElement = key.substring(0, lastDot) - String lastElement = key.substring(lastDot + 1).replaceAll(~/\[\*\]/, "") - return new JsonPathEntry( - """$keyWithoutLastElement[?(@.$lastElement ${compareWith(value)})]""".toString(), - lastElement, - value - ) - } - - protected static String compareWith(Object value) { + protected static MethodBufferingJsonVerifiable valueToAsserter(MethodBufferingJsonVerifiable key, Object value) { if (value instanceof Pattern) { - return patternComparison((value as Pattern).pattern()) + return key.matches((value as Pattern).pattern()) } else if (value instanceof OptionalProperty) { - return patternComparison((value as OptionalProperty).optionalPattern()) + return key.matches((value as OptionalProperty).optionalPattern()) } else if (value instanceof GString) { - return """=~ /${RegexpBuilders.buildGStringRegexpForTestSide(value)}/""" + return key.matches(RegexpBuilders.buildGStringRegexpForTestSide(value)) } - return """== ${potentiallyWrappedWithQuotesValue(value)}""" - } - - protected static String patternComparison(String pattern){ - return """=~ /$pattern/""" - } - - protected static String potentiallyWrappedWithQuotesValue(Object value) { - return isNumber(value) || isBoolean(value) || isNull(value) ? value : "'$value'" - } - - private static boolean isNull(value) { - return value == null - } - - private static boolean isBoolean(value) { - return value instanceof Boolean - } - - private static boolean isNumber(value) { - return value instanceof Number + return key.isEqualTo(value) } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBuffering.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBuffering.java new file mode 100644 index 0000000000..606ae4518e --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBuffering.java @@ -0,0 +1,9 @@ +package io.codearte.accurest.util; + +/** + * @author Marcin Grzejszczak + */ +public interface MethodBuffering { + + String method(); +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java new file mode 100644 index 0000000000..d19a24f99a --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java @@ -0,0 +1,49 @@ +package io.codearte.accurest.util; + +import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; + +/** + * @author Marcin Grzejszczak + */ +public interface MethodBufferingJsonVerifiable + extends JsonVerifiable, MethodBuffering, MethodBufferingReadyToCheck { + @Override + MethodBufferingJsonVerifiable contains(Object value); + + @Override + MethodBufferingJsonVerifiable field(Object value); + + @Override + MethodBufferingJsonVerifiable array(Object value); + + MethodBufferingJsonVerifiable arrayField(Object value); + + @Override + MethodBufferingJsonVerifiable arrayField(); + + @Override + MethodBufferingJsonVerifiable array(); + + MethodBufferingJsonVerifiable iterationPassingArray(); + + @Override + MethodBufferingJsonVerifiable isEqualTo(String value); + + @Override + MethodBufferingJsonVerifiable isEqualTo(Object value); + + @Override + MethodBufferingJsonVerifiable isEqualTo(Number value); + + @Override + MethodBufferingJsonVerifiable isNull(); + + @Override + MethodBufferingJsonVerifiable matches(String value); + + @Override + MethodBufferingJsonVerifiable isEqualTo(Boolean value); + + @Override + MethodBufferingJsonVerifiable value(); +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingReadyToCheck.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingReadyToCheck.java new file mode 100644 index 0000000000..b885692ead --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingReadyToCheck.java @@ -0,0 +1,8 @@ +package io.codearte.accurest.util; + +/** + * @author Marcin Grzejszczak + */ +interface MethodBufferingReadyToCheck extends MethodBuffering { + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ShouldTraverse.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/ShouldTraverse.java new file mode 100644 index 0000000000..a4590e504e --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ShouldTraverse.java @@ -0,0 +1,12 @@ +package io.codearte.accurest.util; + +/** + * @author Marcin Grzejszczak + */ +class ShouldTraverse { + final Object value; + + ShouldTraverse(Object value) { + this.value = value; + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index 77abde0e80..9662646416 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -29,8 +29,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") - blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -57,9 +57,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property1 == 'true')]") - blockBuilder.toString().contains("\$[?(@.property2 == null)]") - blockBuilder.toString().contains("\$[?(@.property3 == false)]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false)""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull()""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -88,9 +88,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") - blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") - blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -115,7 +115,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("entity('{\"items\":[\"HOP\"]}', 'application/json')") + blockBuilder.toString().contains("""entity('{\"items\":[\"HOP\"]}', 'application/json')""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -140,7 +140,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("entity('property1=VAL1', 'application/octet-stream')") + blockBuilder.toString().contains("""entity('property1=VAL1', 'application/octet-stream')""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -168,8 +168,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") - blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") + blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -196,8 +196,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") - blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -224,8 +224,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -258,15 +258,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + GroovyDsl contractDsl = GroovyDsl.make { request { method "GET" url "test" @@ -286,8 +286,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -337,9 +337,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("entity('', 'text/plain')") - blockBuilder.toString().contains("header('Timer', '123')") - !blockBuilder.toString().contains("header('Content-Type'") + blockBuilder.toString().contains("""entity('', 'text/plain')""") + blockBuilder.toString().contains("""header('Timer', '123')""") + !blockBuilder.toString().contains("""header('Content-Type'""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -388,8 +388,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc spockTest.contains("queryParam('age', '99'") spockTest.contains("queryParam('name', 'Denis.Stepanov'") spockTest.contains("queryParam('email', 'bob@email.com'") - spockTest.contains('$[?(@.property2 == \'b\')]') - spockTest.contains('$[?(@.property1 == \'a\')]') + spockTest.contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + spockTest.contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -439,8 +439,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc spockTest.contains("queryParam('age', '99'") spockTest.contains("queryParam('name', 'Denis.Stepanov'") spockTest.contains("queryParam('email', 'bob@email.com'") - spockTest.contains('$[?(@.property2 == \'b\')]') - spockTest.contains('$[?(@.property1 == \'a\')]') + spockTest.contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + spockTest.contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -486,7 +486,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains('String responseAsString = response.readEntity(String)') + spockTest.contains("String responseAsString = response.readEntity(String)") spockTest.contains('responseBody == "test"') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index b02b507a4f..56444a53ad 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -9,7 +9,6 @@ import spock.lang.Specification import spock.lang.Unroll import java.util.regex.Pattern - /** * @author Jakub Kubrynski */ @@ -35,8 +34,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") - blockBuilder.toString().contains("\$[?(@.property2 == 'b')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -63,9 +62,9 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property1 == 'true')]") - blockBuilder.toString().contains("\$[?(@.property2 == null)]") - blockBuilder.toString().contains("\$[?(@.property3 == false)]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull()""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false)""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -94,9 +93,9 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") - blockBuilder.toString().contains("\$.property2[*][?(@.a == 'sth')]") - blockBuilder.toString().contains("\$.property2[*][?(@.b == 'sthElse')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -121,7 +120,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains(".body('''{\"items\":[\"HOP\"]}''')") + blockBuilder.toString().contains(""".body('''{\"items\":[\"HOP\"]}''')""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -146,7 +145,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains(".body('''property1=VAL1''')") + blockBuilder.toString().contains(""".body('''property1=VAL1''')""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -174,8 +173,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$.property[?(@.7 == 0.0)]") - blockBuilder.toString().contains("\$.property[?(@.14 == 0.0)]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(7).isEqualTo(0.0)""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(14).isEqualTo(0.0)""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -203,8 +202,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[*][?(@.property1 == 'a')]") - blockBuilder.toString().contains("\$[*][?(@.property2 == 'b')]") + blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -231,8 +230,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$.property1[*][?(@.property3 == 'test2')]") - blockBuilder.toString().contains("\$.property1[*][?(@.property2 == 'test1')]") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -259,15 +258,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$.property2[?(@.property3 == 'b')]") - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for map objects in response body"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + GroovyDsl contractDsl = GroovyDsl.make { request { method "GET" url "test" @@ -293,8 +292,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -321,8 +320,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property2 =~ /[0-9]{3}/)]") - blockBuilder.toString().contains("\$[?(@.property1 == 'a')]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -348,7 +347,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("\$[?(@.property =~ /\\d+/)]") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").matches("\\d+")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -390,8 +389,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu def spockTest = blockBuilder.toString() then: spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - spockTest.contains('$[?(@.property2 == \'b\')]') - spockTest.contains('$[?(@.property1 == \'a\')]') + spockTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') + spockTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -434,8 +433,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu def spockTest = blockBuilder.toString() then: spockTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - spockTest.contains('$[?(@.property2 == \'b\')]') - spockTest.contains('$[?(@.property1 == \'a\')]') + spockTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') + spockTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -588,8 +587,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains('''$.errors[*][?(@.property == 'bank_account_number')]''') - spockTest.contains('''$.errors[*][?(@.message == 'incorrect_format')]''') + spockTest.contains("""assertThat(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number")""") + spockTest.contains("""assertThat(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -655,7 +654,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''') + spockTest.contains("""assertThat(parsedJson).field("message").matches("User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]")""") } @Issue('42') @@ -669,7 +668,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu def spockTest = blockBuilder.toString() then: spockTest.contains('''"email":"abc@abc.com"''') - spockTest.contains('''parsedJson.read(\'\'\'$[?(@.code =~ /(123123)?/)]''') + spockTest.contains("""assertThat(parsedJson).field("code").matches("(123123)?")""") !spockTest.contains('''REGEXP''') !spockTest.contains('''OPTIONAL''') !spockTest.contains('''OptionalProperty''') diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index fd1a4f5c50..2b712db6b6 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -1,10 +1,11 @@ package io.codearte.accurest.util -import groovy.json.JsonOutput -import groovy.json.JsonSlurper + import com.jayway.jsonpath.Configuration import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.jayway.jsonpath.Option +import groovy.json.JsonOutput +import groovy.json.JsonSlurper import net.minidev.json.JSONArray import spock.lang.Specification import spock.lang.Unroll @@ -18,11 +19,26 @@ class JsonToJsonPathsConverterSpec extends Specification { when: JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: - pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value' - pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4 - pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1' - pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name2')]'''] == 'name2' - pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name == 'name3')]'''] == 'name3' + pathAndValues.find { + it.method() == """.array().field("some").field("nested").field("json").isEqualTo("with value")""" && + it.jsonPath() == '''$[*].some.nested[?(@.json == 'with value')]''' + } + pathAndValues.find { + it.method() == """.array().field("some").field("nested").field("anothervalue").isEqualTo(4)""" && + it.jsonPath() == '''$[*].some.nested[?(@.anothervalue == 4)]''' + } + pathAndValues.find { + it.method() == """.array().field("some").field("nested").array("withlist").contains("name").isEqualTo("name1")""" && + it.jsonPath() == '''$[*].some.nested.withlist[*][?(@.name == 'name1')]''' + } + pathAndValues.find { + it.method() == """.array().field("some").field("nested").array("withlist").contains("name").isEqualTo("name2")""" && + it.jsonPath() == '''$[*].some.nested.withlist[*][?(@.name == 'name2')]''' + } + pathAndValues.find { + it.method() == """.array().field("some").field("nested").array("withlist").field("anothernested").field("name").isEqualTo("name3")""" && + it.jsonPath() == '''$[*].some.nested.withlist[*].anothernested[?(@.name == 'name3')]''' + } and: assertThatJsonPathsInMapAreValid(json, pathAndValues) where: @@ -96,10 +112,22 @@ class JsonToJsonPathsConverterSpec extends Specification { when: JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: - pathAndValues['''$.some.nested[?(@.json == 'with value')]'''] == 'with value' - pathAndValues['''$.some.nested[?(@.anothervalue == 4)]'''] == 4 - pathAndValues['''$.some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1' - pathAndValues['''$.some.nested.withlist[*][?(@.name == 'name2')]'''] == 'name2' + pathAndValues.find { + it.method() == """.field("some").field("nested").field("json").isEqualTo("with value")""" && + it.jsonPath() == '''$.some.nested[?(@.json == 'with value')]''' + } + pathAndValues.find { + it.method() == """.field("some").field("nested").field("anothervalue").isEqualTo(4)""" && + it.jsonPath() == '''$.some.nested[?(@.anothervalue == 4)]''' + } + pathAndValues.find { + it.method() == """.field("some").field("nested").array("withlist").contains("name").isEqualTo("name1")""" && + it.jsonPath() == '''$.some.nested.withlist[*][?(@.name == 'name1')]''' + } + pathAndValues.find { + it.method() == """.field("some").field("nested").array("withlist").contains("name").isEqualTo("name2")""" && + it.jsonPath() == '''$.some.nested.withlist[*][?(@.name == 'name2')]''' + } and: assertThatJsonPathsInMapAreValid(json, pathAndValues) } @@ -114,7 +142,10 @@ class JsonToJsonPathsConverterSpec extends Specification { when: JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: - pathAndValues['''$.items[?(@ == 'HOP')]'''] == 'HOP' + pathAndValues.find { + it.method() == """.array("items").contains("HOP").value()""" && + it.jsonPath() == '''$.items[?(@ == 'HOP')]''' + } and: assertThatJsonPathsInMapAreValid(json, pathAndValues) } @@ -130,8 +161,14 @@ class JsonToJsonPathsConverterSpec extends Specification { when: JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: - pathAndValues['''$[?(@.property1 == null)]'''] == null - pathAndValues['''$[?(@.property2 == true)]'''] == true + pathAndValues.find { + it.method() == """.field("property1").isNull()""" && + it.jsonPath() == '''$[?(@.property1 == null)]''' + } + pathAndValues.find { + it.method() == """.field("property2").isEqualTo(true)""" && + it.jsonPath() == '''$[?(@.property2 == true)]''' + } } def "should convert numbers map"() { @@ -143,9 +180,18 @@ class JsonToJsonPathsConverterSpec extends Specification { when: JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: - pathAndValues['''$.extensions[?(@.7 == 28)]'''] == 28.0 - pathAndValues['''$.extensions[?(@.14 == 41)]'''] == 41.0 - pathAndValues['''$.extensions[?(@.30 == 60)]'''] == 60.0 + pathAndValues.find { + it.method() == """.field("extensions").field("7").isEqualTo(28)""" && + it.jsonPath() == '''$.extensions[?(@.7 == 28)]''' + } + pathAndValues.find { + it.method() == """.field("extensions").field("14").isEqualTo(41)""" && + it.jsonPath() == '''$.extensions[?(@.14 == 41)]''' + } + pathAndValues.find { + it.method() == """.field("extensions").field("30").isEqualTo(60)""" && + it.jsonPath() == '''$.extensions[?(@.30 == 60)]''' + } and: assertThatJsonPathsInMapAreValid(json, pathAndValues) } @@ -163,15 +209,22 @@ class JsonToJsonPathsConverterSpec extends Specification { when: JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: - pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email' - pathAndValues['''$.errors[*][?(@.message == 'inconsistent value')]'''] == 'inconsistent value' - pathAndValues['''$.errors[*][?(@.message == 'inconsistent value2')]'''] == 'inconsistent value2' - pathAndValues['''$.errors[*][?(@.property == 'email')]'''] == 'email' + pathAndValues.find { + it.method() == """.array("errors").contains("property").isEqualTo("email")""" && + it.jsonPath() == '''$.errors[*][?(@.property == 'email')]''' + } + pathAndValues.find { + it.method() == """.array("errors").contains("message").isEqualTo("inconsistent value")""" && + it.jsonPath() == '''$.errors[*][?(@.message == 'inconsistent value')]''' + } + pathAndValues.find { + it.method() == """.array("errors").contains("message").isEqualTo("inconsistent value2")""" && + it.jsonPath() == '''$.errors[*][?(@.message == 'inconsistent value2')]''' + } and: assertThatJsonPathsInMapAreValid(json, pathAndValues) } - def 'should convert a map json with a regex pattern'() { given: List json = [ @@ -184,7 +237,7 @@ class JsonToJsonPathsConverterSpec extends Specification { [name: "name2"], [name: "name1"], [anothernested: - [name: Pattern.compile('[a-zA-Z]+')] + [name: Pattern.compile("[a-zA-Z]+")] ], [age: "123456789"] ] @@ -207,23 +260,304 @@ class JsonToJsonPathsConverterSpec extends Specification { when: JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) then: - pathAndValues['''$[*].some.nested[?(@.json == 'with value')]'''] == 'with value' - pathAndValues['''$[*].some.nested[?(@.anothervalue == 4)]'''] == 4 - pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name1')]'''] == 'name1' - pathAndValues['''$[*].some.nested.withlist[*][?(@.name == 'name2')]'''] - (pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''] as Pattern).pattern() == '[a-zA-Z]+' + pathAndValues.find { + it.method() == """.array().field("some").field("nested").field("json").isEqualTo("with value")""" && + it.jsonPath() == '''$[*].some.nested[?(@.json == 'with value')]''' + } + pathAndValues.find { + it.method() == """.array().field("some").field("nested").field("anothervalue").isEqualTo(4)""" && + it.jsonPath() == '''$[*].some.nested[?(@.anothervalue == 4)]''' + } + pathAndValues.find { + it.method() == """.array().field("some").field("nested").array("withlist").contains("name").isEqualTo("name1")""" && + it.jsonPath() == '''$[*].some.nested.withlist[*][?(@.name == 'name1')]''' + } + pathAndValues.find { + it.method() == """.array().field("some").field("nested").array("withlist").contains("name").isEqualTo("name2")""" && + it.jsonPath() == '''$[*].some.nested.withlist[*][?(@.name == 'name2')]''' + } + pathAndValues.find { + it.method() == """.array().field("some").field("nested").array("withlist").field("anothernested").field("name").matches("[a-zA-Z]+")""" && + it.jsonPath() == '''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]''' + } when: - pathAndValues['''$[*].some.nested.withlist[*].anothernested[?(@.name =~ /[a-zA-Z]+/)]'''] = "Kowalski" json.some.nested.withlist[0][2].anothernested.name = "Kowalski" then: assertThatJsonPathsInMapAreValid(JsonOutput.prettyPrint(JsonOutput.toJson(json)), pathAndValues) } + + + def "should generate assertions for simple response body"() { + given: + String json = """{ + "property1": "a", + "property2": "b" + }""" + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues.find { + it.method()== """.field("property1").isEqualTo("a")""" && + it.jsonPath() == """\$[?(@.property1 == 'a')]""" + } + pathAndValues.find { + it.method()== """.field("property2").isEqualTo("b")""" && + it.jsonPath() == """\$[?(@.property2 == 'b')]""" + } + and: + pathAndValues.size() == 2 + } + + def "should generate assertions for null and boolean values"() { + given: + String json = """{ + "property1": "true", + "property2": null, + "property3": false + }""" + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues.find { + it.method()== """.field("property1").isEqualTo("true")""" && + it.jsonPath() == """\$[?(@.property1 == 'true')]""" + } + pathAndValues.find { + it.method()== """.field("property2").isNull()""" && + it.jsonPath() == """\$[?(@.property2 == null)]""" + } + pathAndValues.find { + it.method()== """.field("property3").isEqualTo(false)""" && + it.jsonPath() == """\$[?(@.property3 == false)]""" + } + and: + pathAndValues.size() == 3 + } + + def "should generate assertions for simple response body constructed from map with a list"() { + given: + Map json = [ + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ] + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + then: + pathAndValues.find { + it.method()== """.field("property1").isEqualTo("a")""" && + it.jsonPath() == """\$[?(@.property1 == 'a')]""" + } + pathAndValues.find { + it.method()== """.array("property2").contains("a").isEqualTo("sth")""" && + it.jsonPath() == """\$.property2[*][?(@.a == 'sth')]""" + } + pathAndValues.find { + it.method()== """.array("property2").contains("b").isEqualTo("sthElse")""" && + it.jsonPath() == """\$.property2[*][?(@.b == 'sthElse')]""" + } + and: + pathAndValues.size() == 3 + } + + def "should generate assertions for a response body containing map with integers as keys"() { + given: + Map json = [ + property: [ + 14: 0.0, + 7 : 0.0 + ] + ] + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + then: + pathAndValues.find { + it.method()== """.field("property").field(7).isEqualTo(0.0)""" && + it.jsonPath() == """\$.property[?(@.7 == 0.0)]""" + } + pathAndValues.find { + it.method()== """.field("property").field(14).isEqualTo(0.0)""" && + it.jsonPath() == """\$.property[?(@.14 == 0.0)]""" + } + and: + pathAndValues.size() == 2 + } + + def "should generate assertions for array in response body"() { + given: + String json = """[ + { + "property1": "a" + }, + { + "property2": "b" + }]""" + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues.find { + it.method()== """.array().contains("property1").isEqualTo("a")""" && + it.jsonPath() == """\$[*][?(@.property1 == 'a')]""" + } + pathAndValues.find { + it.method()== """.array().contains("property2").isEqualTo("b")""" && + it.jsonPath() == """\$[*][?(@.property2 == 'b')]""" + } + and: + pathAndValues.size() == 2 + } + + def "should generate assertions for array inside response body element"() { + given: + String json = """{ + "property1": [ + { "property2": "test1"}, + { "property3": "test2"} + ] +}""" + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues.find { + it.method()== """.array("property1").contains("property2").isEqualTo("test1")""" && + it.jsonPath() == """\$.property1[*][?(@.property2 == 'test1')]""" + } + pathAndValues.find { + it.method()== """.array("property1").contains("property3").isEqualTo("test2")""" && + it.jsonPath() == """\$.property1[*][?(@.property3 == 'test2')]""" + } + and: + pathAndValues.size() == 2 + } + + def "should generate assertions for nested objects in response body"() { + given: + String json = """{ + "property1": "a", + "property2": {"property3": "b"} + }""" + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues.find { + it.method()== """.field("property2").field("property3").isEqualTo("b")""" && + it.jsonPath() == """\$.property2[?(@.property3 == 'b')]""" + } + pathAndValues.find { + it.method()== """.field("property1").isEqualTo("a")""" && + it.jsonPath() == """\$[?(@.property1 == 'a')]""" + } + and: + pathAndValues.size() == 2 + } + + def "should generate regex assertions for map objects in response body"() { + given: + Map json = [ + property1: "a", + property2: Pattern.compile('[0-9]{3}') + ] + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + then: + pathAndValues.find { + it.method()== """.field("property2").matches("[0-9]{3}")""" && + it.jsonPath() == """\$[?(@.property2 =~ /[0-9]{3}/)]""" + } + pathAndValues.find { + it.method()== """.field("property1").isEqualTo("a")""" && + it.jsonPath() == """\$[?(@.property1 == 'a')]""" + } + and: + pathAndValues.size() == 2 + } + + def "should generate escaped regex assertions for string objects in response body"() { + given: + Map json = [ + property2: Pattern.compile('\\d+') + ] + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + then: + pathAndValues.find { + it.method()== """.field("property2").matches("\\d+")""" && + it.jsonPath() == """\$[?(@.property2 =~ /\\d+/)]""" + } + and: + pathAndValues.size() == 1 + } + + + def "should work with more complex stuff and jsonpaths"() { + given: + Map json = [ + errors: [ + [property: "bank_account_number", + message: "incorrect_format"] + ] + ] + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + then: + pathAndValues.find { + it.method()== """.array("errors").contains("property").isEqualTo("bank_account_number")""" && + it.jsonPath() == """\$.errors[*][?(@.property == 'bank_account_number')]""" + } + pathAndValues.find { + it.method()== """.array("errors").contains("message").isEqualTo("incorrect_format")""" && + it.jsonPath() == """\$.errors[*][?(@.message == 'incorrect_format')]""" + } + and: + pathAndValues.size() == 2 + } + + def "should manage to parse a double array"() { + given: + String json = ''' + [{ + "place": + { + "bounding_box": + { + "coordinates": + [[ + [-77.119759,38.995548], + [-76.909393,38.791645] + ]] + } + } + }] + ''' + when: + JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + then: + pathAndValues.find { + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(38.995548).value()""" && + it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]""" + } + pathAndValues.find { + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(-77.119759).value()""" && + it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]""" + } + pathAndValues.find { + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(-76.909393).value()""" && + it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]""" + } + pathAndValues.find { + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(38.791645).value()""" && + it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]""" + } + and: + pathAndValues.size() == 4 + } private void assertThatJsonPathsInMapAreValid(String json, JsonPaths pathAndValues) { DocumentContext parsedJson = JsonPath.using(Configuration.builder().options(Option.ALWAYS_RETURN_LIST).build()).parse(json); pathAndValues.each { - def at = parsedJson.read(it.jsonPath, JSONArray).getAt(it.optionalSuffix ?: 0) - assert at == it.optionalSuffix ? [it.value] : it.value + assert !parsedJson.read(it.jsonPath(), JSONArray).empty } } 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 1ad91232f6..fc8d4bfded 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 @@ -4,8 +4,6 @@ import io.codearte.accurest.config.AccurestConfigProperties import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task -import org.gradle.api.artifacts.DependencyResolveDetails - /** * @author Jakub Kubrynski */ @@ -31,6 +29,7 @@ class AccurestGradlePlugin implements Plugin { createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.5-beta") + project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:jsonassert:${extension.getJsonAssertVersion()}") project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy index f4a518c1bb..3a7825fbda 100644 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy +++ b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy @@ -22,7 +22,6 @@ class GenerateWireMockClientStubsFromDslTask extends ConventionTask { void generate() { logger.info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), getConfigProperties()) converter.processFiles() } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index c6c08c4b0b..6329484d1f 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -29,6 +29,7 @@ configurations { repositories { mavenCentral() + mavenLocal() } dependencies { diff --git a/build.gradle b/build.gradle index 250be22775..16011ddca1 100644 --- a/build.gradle +++ b/build.gradle @@ -72,6 +72,7 @@ project(':accurest-core') { compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' compile 'asm:asm:3.3.1' compile "com.github.tomakehurst:wiremock:$wiremockVersion" + compile "com.blogspot.toomuchcoding:jsonassert:$jsonassertVersion" testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') diff --git a/gradle.properties b/gradle.properties index 27a71580f7..bc99f91ba8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,3 +2,4 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.5-beta +jsonassertVersion = 0.1.0 From 533e6b9eadd86a34328f85965d0c16b9eee19ccc Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 15 Feb 2016 18:35:56 +0100 Subject: [PATCH 282/719] Applied changes following review --- .../accurest/SingleTestGenerator.groovy | 2 +- .../util/DelegatingJsonVerifiable.java | 36 +++++++++---------- .../util/MethodBufferingJsonVerifiable.java | 2 +- .../util/MethodBufferingReadyToCheck.java | 8 ----- 4 files changed, 20 insertions(+), 28 deletions(-) delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingReadyToCheck.java diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index afb839a3ef..bca38a0b1b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -92,7 +92,7 @@ class SingleTestGenerator { Class.forName(JSON_ASSERT_CLASS) return true } catch (ClassNotFoundException e) { - log.debug("JsonAssert is not present on classpath. Will not add a static import") + log.debug("JsonAssert is not present on classpath. Will not add a static import.") return false } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index 28a95c8a8b..3148dc6a97 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -32,11 +32,19 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { value.toString(); } + private void appendMethodWithValue(String methodName, Object value) { + methodsBuffer.append(".").append(methodName).append("(").append(value) + .append(")"); + } + + private void appendMethodWithQuotedValue(String methodName, Object value) { + appendMethodWithValue(methodName, wrapValueWithQuotes(value)); + } + @Override public MethodBufferingJsonVerifiable contains(Object value) { DelegatingJsonVerifiable verifiable = new FinishedDelegatingJsonVerifiable(delegate.contains(value), methodsBuffer); - verifiable.methodsBuffer.append(".contains(").append(wrapValueWithQuotes(value)) - .append(")"); + verifiable.appendMethodWithQuotedValue("contains", value); if (isAssertingAValueInArray()) { verifiable.methodsBuffer.append(".value()"); } @@ -48,11 +56,9 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { Object valueToPut = value instanceof ShouldTraverse ? ((ShouldTraverse) value).value : value; DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.field(valueToPut), methodsBuffer); if (delegate.isIteratingOverArray() && !(value instanceof ShouldTraverse)) { - verifiable.methodsBuffer.append(".contains(").append(wrapValueWithQuotes(valueToPut)) - .append(")"); + verifiable.appendMethodWithQuotedValue("contains", valueToPut); } else { - verifiable.methodsBuffer.append(".field(").append(wrapValueWithQuotes(valueToPut)) - .append(")"); + verifiable.appendMethodWithQuotedValue("field", valueToPut); } return verifiable; } @@ -60,16 +66,14 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { @Override public MethodBufferingJsonVerifiable array(Object value) { DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.array(value), methodsBuffer); - verifiable.methodsBuffer.append(".array(").append(wrapValueWithQuotes(value)) - .append(")"); + verifiable.appendMethodWithQuotedValue("array", value); return verifiable; } @Override public MethodBufferingJsonVerifiable arrayField(Object value) { DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.field(value).arrayField(), methodsBuffer); - verifiable.methodsBuffer.append(".array(").append(wrapValueWithQuotes(value)) - .append(")"); + verifiable.appendMethodWithQuotedValue("array", value); return verifiable; } @@ -96,8 +100,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate.isAssertingAValueInArray()) { readyToCheck.methodsBuffer.append(".value()"); } else { - readyToCheck.methodsBuffer.append(".isEqualTo(") - .append(wrapValueWithQuotes(value)).append(")"); + readyToCheck.appendMethodWithQuotedValue("isEqualTo", value); } return readyToCheck; } @@ -116,8 +119,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate.isAssertingAValueInArray()) { readyToCheck.methodsBuffer.append(".value()"); } else { - readyToCheck.methodsBuffer.append(".isEqualTo(").append(String.valueOf(value)) - .append(")"); + readyToCheck.appendMethodWithValue("isEqualTo", String.valueOf(value)); } return readyToCheck; } @@ -135,8 +137,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate.isAssertingAValueInArray()) { readyToCheck.methodsBuffer.append(".value()"); } else { - readyToCheck.methodsBuffer.append(".matches(").append(wrapValueWithQuotes(value)) - .append(")"); + readyToCheck.appendMethodWithQuotedValue("matches", value); } return readyToCheck; } @@ -147,8 +148,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate.isAssertingAValueInArray()) { readyToCheck.methodsBuffer.append(".value()"); } else { - readyToCheck.methodsBuffer.append(".isEqualTo(").append(String.valueOf(value)) - .append(")"); + readyToCheck.appendMethodWithValue("isEqualTo", String.valueOf(value)); } return readyToCheck; } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java index d19a24f99a..c46e0f61b7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java @@ -6,7 +6,7 @@ import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; * @author Marcin Grzejszczak */ public interface MethodBufferingJsonVerifiable - extends JsonVerifiable, MethodBuffering, MethodBufferingReadyToCheck { + extends JsonVerifiable, MethodBuffering { @Override MethodBufferingJsonVerifiable contains(Object value); diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingReadyToCheck.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingReadyToCheck.java deleted file mode 100644 index b885692ead..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingReadyToCheck.java +++ /dev/null @@ -1,8 +0,0 @@ -package io.codearte.accurest.util; - -/** - * @author Marcin Grzejszczak - */ -interface MethodBufferingReadyToCheck extends MethodBuffering { - -} From 97f03964bc36c9dd7e2f48cb2e3d5de978bd5bc6 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 17 Feb 2016 13:48:31 +0100 Subject: [PATCH 283/719] Fixed class imports for JUnit. Added test for class imports and annotations. --- .../accurest/SingleTestGenerator.groovy | 2 - .../accurest/config/TestFramework.groovy | 14 ++-- .../accurest/SingleTestGeneratorSpec.groovy | 67 +++++++++++++++++++ 3 files changed, 74 insertions(+), 9 deletions(-) create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index bca38a0b1b..309173138f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -59,8 +59,6 @@ class SingleTestGenerator { if (configProperties.targetFramework == TestFramework.JUNIT) { clazz.addImport('org.junit.Test') - } else { - clazz.addImport('groovy.json.JsonSlurper') } if (configProperties.ruleClassForTests) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy index c1014f19de..42d420ee7b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy @@ -4,8 +4,8 @@ package io.codearte.accurest.config * @author Jakub Kubrynski */ enum TestFramework { - JUNIT("public ", "public void ", ";", ".java", "Test", "org.junit.Ignore", "org.junit.FixMethodOrder", "@FixMethodOrder(MethodSorters.NAME_ASCENDING)"), - SPOCK("", "def ", "", ".groovy", "Spec", "spock.lang.Ignore", "spock.lang.Stepwise", "@Stepwise") + JUNIT("public ", "public void ", ";", ".java", "Test", "org.junit.Ignore", ["org.junit.FixMethodOrder", "org.junit.runners.MethodSorters"], "@FixMethodOrder(MethodSorters.NAME_ASCENDING)"), + SPOCK("", "def ", "", ".groovy", "Spec", "spock.lang.Ignore", ["spock.lang.Stepwise"], "@Stepwise") private final String classModifier private final String methodModifier @@ -13,18 +13,18 @@ enum TestFramework { private final String classExtension; private final String classNameSuffix; private final String ignoreClass - private final String orderAnnotationImport + private final List orderAnnotationImports private final String orderAnnotation TestFramework(String classModifier, String methodModifier, String lineSuffix, String classExtension, String classNameSuffix, - String ignoreClass, String orderAnnotationImport, String orderAnnotation) { + String ignoreClass, List orderAnnotationImports, String orderAnnotation) { this.classModifier = classModifier this.lineSuffix = lineSuffix this.methodModifier = methodModifier this.classExtension = classExtension this.classNameSuffix = classNameSuffix this.ignoreClass = ignoreClass - this.orderAnnotationImport = orderAnnotationImport + this.orderAnnotationImports = orderAnnotationImports this.orderAnnotation = orderAnnotation } @@ -52,8 +52,8 @@ enum TestFramework { return ignoreClass } - String getOrderAnnotationImport() { - return orderAnnotationImport + List getOrderAnnotationImport() { + return orderAnnotationImports } String getOrderAnnotation() { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy new file mode 100644 index 0000000000..fbfa267ec4 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -0,0 +1,67 @@ +package io.codearte.accurest + +import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.file.Contract +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification +import spock.lang.Unroll + +import static io.codearte.accurest.config.TestFramework.JUNIT +import static io.codearte.accurest.config.TestFramework.SPOCK + +class SingleTestGeneratorSpec extends Specification { + + @Rule + TemporaryFolder tmpFolder = new TemporaryFolder() + File file + + static List jUnitClassStrings = ['package test;', 'import com.jayway.jsonpath.DocumentContext;', 'import com.jayway.jsonpath.JsonPath;', + 'import org.junit.FixMethodOrder;', 'import org.junit.Ignore;', 'import org.junit.Test;', 'import org.junit.runners.MethodSorters;', + 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThat;', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*;', + '@FixMethodOrder(MethodSorters.NAME_ASCENDING)', '@Test', '@Ignore'] + + static List spockClassStrings = ['package test', 'import com.jayway.jsonpath.DocumentContext', 'import com.jayway.jsonpath.JsonPath', + 'import spock.lang.Ignore', 'import spock.lang.Specification', 'import spock.lang.Stepwise', + 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThat', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*', + '@Stepwise', '@Ignore'] + + def setup() { + file = tmpFolder.newFile() + file.write(""" + io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url 'url' + } + response { + status 200 + } + } +""") + } + + @Unroll + def "should build test class for #testFramework"() { + given: + AccurestConfigProperties properties = new AccurestConfigProperties(); + properties.targetFramework = testFramework + Contract contract = new Contract(file.toPath(), true, 1, 2) + contract.ignored >> true + contract.order >> 2 + SingleTestGenerator testGenerator = new SingleTestGenerator(properties) + + when: + String clazz = testGenerator.buildClass([contract], "test", "test") + + then: + classStrings.forEach({ clazz.contains(it) }) + + where: + testFramework | classStrings + JUNIT | jUnitClassStrings + SPOCK | spockClassStrings + } + + +} From 661c0dcbd72ba3acc34133e2409e4f3f452ed148 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 17 Feb 2016 22:26:54 +0100 Subject: [PATCH 284/719] Started splitting test methods generation implementation into separate cases for Spock and JUnit. --- .../builder/JUnitMethodBodyBuilder.groovy | 67 +++++- .../accurest/builder/MethodBodyBuilder.groovy | 225 ++++++++++++++++++ .../MockMvcJUnitMethodBodyBuilder.groovy | 37 +++ .../builder/SpockMethodBodyBuilder.groovy | 210 +++------------- 4 files changed, 349 insertions(+), 190 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index 0f31ff8eb8..1b4e08b449 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -1,18 +1,65 @@ 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 + /** * @author Jakub Kubrynski + * @author Olga Maciaszek-Sharma */ -class JUnitMethodBodyBuilder { -/* - given() - .contentType("application/json") - .header("Accept", "application/json") - .body("{'name': 'MyApp', 'description' : 'awesome app'}".replaceAll("'", "\"")). +@TypeChecked +@PackageScope +abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { - expect() - .statusCode(200).body("id", is(not(nullValue()))). + JUnitMethodBodyBuilder(GroovyDsl stubDefinition) { + super(stubDefinition) + } - when() - .post(root.toString() + "rest/applications").asString();*/ + @Override + protected void when(BlockBuilder bb) { + + } + + @Override + protected String getResponseAsString() { + return null + } + + @Override + protected String addCommentSignIfRequired(String baseString) { + return "// $baseString" + } + + @Override + protected String addColonIfRequired(String baseString) { + return "$baseString;" + } + + @Override + protected String getResponseBodyPropertyComparisonString(String property, String value) { + return "assertThat(responseBody${property}).isEqualTo(\"${value}\");" + } + + @Override + protected String getMultipartParameterLine(Map.Entry parameter) { + return null //TODO + } + + @Override + protected void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { + blockBuilder.addLine("${exec.insertValue("parsedJson.read(\"\\\$$property\")")};") + } + + @Override + protected String getPropertyInListString(String property, Integer listIndex) { + return "${property}.get($listIndex)" ?: '' + } + + @Override + protected String convertUnicodeEscapesIfRequired(String json) { + return json // TODO: verify if that's fine or escapeJava required + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy new file mode 100644 index 0000000000..443c6cd579 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -0,0 +1,225 @@ +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.DslProperty +import io.codearte.accurest.dsl.internal.ExecutionProperty +import io.codearte.accurest.dsl.internal.MatchingStrategy +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.util.ContentType +import io.codearte.accurest.util.JsonPaths +import io.codearte.accurest.util.JsonToJsonPathsConverter +import io.codearte.accurest.util.MapConverter + +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 + */ +@TypeChecked +@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) + + protected void given(BlockBuilder bb) {} + + protected abstract void when(BlockBuilder bb) + + protected abstract String getResponseAsString() + + protected abstract String addCommentSignIfRequired(String baseString) + + protected abstract String addColonIfRequired(String baseString) + + protected abstract String getResponseBodyPropertyComparisonString(String property, String value) + + protected abstract String getMultipartParameterLine(Map.Entry parameter) + + protected abstract void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) + + protected abstract void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) + + protected abstract String getPropertyInListString(String property, Integer index) + + protected abstract String convertUnicodeEscapesIfRequired(String json) + + void appendTo(BlockBuilder blockBuilder) { + blockBuilder.startBlock() + + 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() + given(bb) + bb.endBlock().addEmptyLine() + } + + + protected void then(BlockBuilder bb) { + validateResponseCodeBlock(bb) + if (response.headers) { + validateResponseHeadersBlock(bb) + } + if (response.body) { + bb.endBlock() + bb.addLine('and:').startBlock() + validateResponseBodyBlock(bb) + } + } + + private void validateResponseBodyBlock(BlockBuilder bb) { + def responseBody = response.body.serverValue + ContentType contentType = getResponseContentType() + if (responseBody instanceof GString) { + responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) + } + if (contentType == ContentType.JSON) { + appendJsonPath(bb, responseAsString) + JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) + jsonPaths.each { + bb.addLine("assertThat(parsedJson)" + it.method()) + } + processBodyElement(bb, "", responseBody) + } else if (contentType == ContentType.XML) { + bb.addLine("def responseBody = new XmlSlurper().parseText($responseAsString)") + // TODO xml validation + } else { + bb.addLine("def responseBody = ($responseAsString)") + processText(bb, "", responseBody as String) + } + } + + 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(addColonIfRequired("DocumentContext parsedJson = JsonPath.parse($json)")) + } + + protected void processText(BlockBuilder blockBuilder, String property, String value) { + if (value.startsWith('$')) { + value = value.substring(1).replaceAll('\\$value', "responseBody$property") + blockBuilder.addLine(value) + } else { + blockBuilder.addLine(getResponseBodyPropertyComparisonString(property, value)) + } + } + + 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 getMultipartParameters() { + return (Map) request?.multipart?.serverValue + } + + protected String trimRepeatedQuotes(String toTrim) { + return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim // TODO: implement for JUnit + } + + protected Object extractServerValueFromBody(bodyValue) { + if (bodyValue instanceof GString) { + bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) + } else { + bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) + } + 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) + } + + protected String resolveParamValue(Object value) { + return value.toString() + } + + protected String resolveParamValue(MatchingStrategy matchingStrategy) { + 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() + } + + protected void processBodyElement(BlockBuilder blockBuilder, String property, Map map) { + map.each { + processBodyElement(blockBuilder, property, it) + } + } + + protected void processBodyElement(BlockBuilder blockBuilder, String property, List list) { + list.eachWithIndex { listElement, listIndex -> + String prop = getPropertyInListString(property, listIndex as Integer) + processBodyElement(blockBuilder, prop, listElement) + } + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy new file mode 100644 index 0000000000..707a2eae42 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy @@ -0,0 +1,37 @@ +package io.codearte.accurest.builder + +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.internal.Header + +import java.util.regex.Pattern + +/** + * @author Olga Maciaszek-Sharma + * @since 2016-02-17 + */ +class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder{ + + MockMvcJUnitMethodBodyBuilder(GroovyDsl stubDefinition) { + super(stubDefinition) + } + + @Override + protected void validateResponseCodeBlock(BlockBuilder bb) { + bb.addLine("assertThat(response.statusCode()).isEqualTo($response.status.serverValue);") + } + + @Override + protected void validateResponseHeadersBlock(BlockBuilder bb) { + response.headers?.collect { Header header -> + bb.addLine("assertThat(response.header(\"$header.name\")).${createHeaderComparison(header.serverValue)}") + } + } + + private String createHeaderComparison(Object headerValue) { + return "isEqualTo(\"$headerValue\");" + } + + private String createHeaderComparison(Pattern headerValue) { + return "matches(\"$headerValue\");" + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index c5202cad39..dce3ad6910 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -5,219 +5,69 @@ import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.dsl.internal.* +import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.dsl.internal.ExecutionProperty +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.util.ContentType import io.codearte.accurest.util.MapConverter -import io.codearte.accurest.util.JsonToJsonPathsConverter -import io.codearte.accurest.util.JsonPaths -import static io.codearte.accurest.util.ContentUtils.* +import static io.codearte.accurest.util.ContentUtils.extractValue +import static io.codearte.accurest.util.ContentUtils.getMultipartFileParameterContent +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent +import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader + /** * @author Jakub Kubrynski */ @PackageScope @TypeChecked -abstract class SpockMethodBodyBuilder { - - protected final Request request - protected final Response response +abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { SpockMethodBodyBuilder(GroovyDsl stubDefinition) { - this.request = stubDefinition.request - this.response = stubDefinition.response + super(stubDefinition) } - void appendTo(BlockBuilder blockBuilder) { - blockBuilder.startBlock() - - givenBlock(blockBuilder) - whenBlock(blockBuilder) - thenBlock(blockBuilder) - - blockBuilder.endBlock() - } - - protected void thenBlock(BlockBuilder bb) { - bb.addLine('then:') - bb.startBlock() - then(bb) - bb.endBlock() - } - - protected void whenBlock(BlockBuilder bb) { - bb.addLine('when:') - bb.startBlock() - when(bb) - bb.endBlock().addEmptyLine() - } - - protected void givenBlock(BlockBuilder bb) { - bb.addLine('given:') - bb.startBlock() - given(bb) - bb.endBlock().addEmptyLine() - } - - protected void given(BlockBuilder bb) {} - - protected abstract void when(BlockBuilder bb) - - protected abstract void validateResponseCodeBlock(BlockBuilder bb) - - protected abstract void validateResponseHeadersBlock(BlockBuilder bb) - - protected abstract String getResponseAsString() - - protected void then(BlockBuilder bb) { - validateResponseCodeBlock(bb) - if (response.headers) { - validateResponseHeadersBlock(bb) - } - if (response.body) { - bb.endBlock() - bb.addLine('and:').startBlock() - validateResponseBodyBlock(bb) - } - } - - protected void validateResponseBodyBlock(BlockBuilder bb) { - def responseBody = response.body.serverValue - ContentType contentType = getResponseContentType() - if (responseBody instanceof GString) { - responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) - } - if (contentType == ContentType.JSON) { - appendJsonPath(bb, responseAsString) - JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) - jsonPaths.each { - bb.addLine("assertThat(parsedJson)" + it.method()) - } - processBodyElement(bb, "", responseBody) - } else if (contentType == ContentType.XML) { - bb.addLine("def responseBody = new XmlSlurper().parseText($responseAsString)") - // TODO xml validation - } else { - bb.addLine("def responseBody = ($responseAsString)") - processText(bb, "", responseBody as String) - } - } - - protected void processText(BlockBuilder blockBuilder, String property, String value) { - if (value.startsWith('$')) { - value = value.substring(1).replaceAll('\\$value', "responseBody$property") - blockBuilder.addLine(value) - } else { - blockBuilder.addLine("responseBody$property == \"${value}\"") - } - } - - protected String - - protected String getBodyAsString() { - Object bodyValue = extractServerValueFromBody(request.body.serverValue) - String json = new JsonOutput().toJson(bodyValue) - json = convertUnicodeEscapes(json) - return trimRepeatedQuotes(json) - } - - protected Map getMultipartParameters() { - return (Map)request?.multipart?.serverValue + @Override + protected String getResponseBodyPropertyComparisonString(String property, String value) { + return "responseBody$property == \"${value}\"" } + @Override protected String getMultipartParameterLine(Map.Entry parameter) { - if (parameter.value instanceof NamedProperty) { + if (parameter.value instanceof NamedProperty) { return ".multiPart(${getMultipartFileParameterContent(parameter.key, (NamedProperty) parameter.value)})" } return ".param('$parameter.key', '$parameter.value')" } - protected String convertUnicodeEscapes(String json) { - return StringEscapeUtils.unescapeJavaScript(json) - } - - protected String trimRepeatedQuotes(String toTrim) { - return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim - } - - protected Object extractServerValueFromBody(bodyValue) { - if (bodyValue instanceof GString) { - bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) - } else { - bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) - } - 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) - } - - protected String resolveParamValue(Object value) { - return value.toString() - } - - protected String resolveParamValue(MatchingStrategy matchingStrategy) { - return matchingStrategy.serverValue.toString() - } - - protected void processBodyElement(BlockBuilder blockBuilder, String property, Object value) { - - } - - protected void appendJsonPath(BlockBuilder blockBuilder, String json) { - blockBuilder.addLine("DocumentContext parsedJson = JsonPath.parse($json)") - } - + @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) } - protected void processBodyElement(BlockBuilder blockBuilder, String property, Map map) { - map.each { - processBodyElement(blockBuilder, property, it) - } + @Override + protected String addCommentSignIfRequired(String baseString) { + return baseString } - protected void processBodyElement(BlockBuilder blockBuilder, String property, List list) { - list.eachWithIndex { listElement, listIndex -> - String prop = "$property[$listIndex]" ?: '' - processBodyElement(blockBuilder, prop, listElement) - } + @Override + protected String addColonIfRequired(String baseString) { + return baseString } - protected ContentType getRequestContentType() { - ContentType contentType = recognizeContentTypeFromHeader(request.headers) - if (contentType == ContentType.UNKNOWN) { - contentType = recognizeContentTypeFromContent(request.body.serverValue) - } - return contentType + @Override + protected String getPropertyInListString(String property, Integer listIndex) { + "$property[$listIndex]" ?: '' } - protected ContentType getResponseContentType() { - ContentType contentType = recognizeContentTypeFromHeader(response.headers) - if (contentType == ContentType.UNKNOWN) { - contentType = recognizeContentTypeFromContent(response.body.serverValue) - } - return contentType - } - - protected String getTestSideValue(Object object) { - return MapConverter.getTestSideValues(object).toString() + protected String convertUnicodeEscapesIfRequired(String json) { + return StringEscapeUtils.unescapeJavaScript(json) } } From cdb7a088c5fed96de961cb34311b74b817747824 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 18 Feb 2016 17:06:01 +0100 Subject: [PATCH 285/719] Added more methods with separate implementation for JUnit and Spock. --- .../builder/JUnitMethodBodyBuilder.groovy | 15 +++++++++++++++ .../accurest/builder/MethodBodyBuilder.groovy | 8 ++++++-- .../builder/SpockMethodBodyBuilder.groovy | 11 +++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index 1b4e08b449..1c54d464c9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -62,4 +62,19 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { protected String convertUnicodeEscapesIfRequired(String json) { return json // TODO: verify if that's fine or escapeJava required } + + @Override + protected void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) { + processBodyElement(blockBuilder, property + """.get(\\\"$entry.key\\\")""", entry.value) + } + + @Override + protected String getParsedXmlResponseBodyString(String responseString) { + return "Object responseBody = new XmlSlurper().parseText($responseString);" + } + + @Override + protected String getSimpleResponseBodyString(String responseString) { + return "Object responseBody = ($responseString);" + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index 443c6cd579..5580687632 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -61,6 +61,10 @@ abstract class MethodBodyBuilder { protected abstract String convertUnicodeEscapesIfRequired(String json) + protected abstract String getParsedXmlResponseBodyString(String responseString) + + protected abstract String getSimpleResponseBodyString(String responseString) + void appendTo(BlockBuilder blockBuilder) { blockBuilder.startBlock() @@ -118,10 +122,10 @@ abstract class MethodBodyBuilder { } processBodyElement(bb, "", responseBody) } else if (contentType == ContentType.XML) { - bb.addLine("def responseBody = new XmlSlurper().parseText($responseAsString)") + bb.addLine(getParsedXmlResponseBodyString(responseAsString)) // TODO xml validation } else { - bb.addLine("def responseBody = ($responseAsString)") + bb.addLine(getSimpleResponseBodyString(responseAsString)) processText(bb, "", responseBody as String) } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index dce3ad6910..3f40878d9a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -67,7 +67,18 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { "$property[$listIndex]" ?: '' } + @Override protected String convertUnicodeEscapesIfRequired(String json) { return StringEscapeUtils.unescapeJavaScript(json) } + + @Override + protected String getParsedXmlResponseBodyString(String responseString) { + return "def responseBody = new XmlSlurper().parseText($responseAsString)" + } + + @Override + protected String getSimpleResponseBodyString(String responseString) { + return "def responseBody = ($responseAsString)" + } } From 210b9f0bffef7aa9d190d6ed3a1185a719d79b57 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Fri, 19 Feb 2016 15:55:08 +0100 Subject: [PATCH 286/719] Made all the cases work apart from method execution and mulitparts. Added tests for JUnit. --- .../accurest/builder/BlockBuilder.groovy | 11 + .../builder/JUnitMethodBodyBuilder.groovy | 37 +- .../JaxRsClientSpockMethodBodyBuilder.groovy | 4 + .../accurest/builder/MethodBodyBuilder.groovy | 90 +- .../MockMvcJUnitMethodBodyBuilder.groovy | 8 +- .../MockMvcSpockMethodBodyBuilder.groovy | 59 +- .../builder/SpockMethodBodyBuilder.groovy | 40 +- .../util/DelegatingJsonVerifiable.java | 8 +- .../MockMvcJunitMethodBuilderSpec.groovy | 973 ++++++++++++++++++ 9 files changed, 1134 insertions(+), 96 deletions(-) create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy index 62d97fdda7..3ab11e9359 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy @@ -62,6 +62,17 @@ class BlockBuilder { return this } + BlockBuilder addAtTheEnd(String toAdd) { + if (builder.charAt(builder.length() - 1) as String == '\n') { + builder.replace(builder.length() - 1, builder.length(), toAdd) + builder << '\n' + } else { + builder << toAdd + } + return this + } + + @Override String toString() { return builder.toString() diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index 1c54d464c9..f6153341d1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -5,6 +5,8 @@ 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.Request /** * @author Jakub Kubrynski @@ -18,14 +20,9 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { super(stubDefinition) } - @Override - protected void when(BlockBuilder bb) { - - } - @Override protected String getResponseAsString() { - return null + return "response.getBody().asString()" } @Override @@ -34,8 +31,9 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { } @Override - protected String addColonIfRequired(String baseString) { - return "$baseString;" + protected BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) { + blockBuilder.addAtTheEnd(';') + return blockBuilder } @Override @@ -60,7 +58,8 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { @Override protected String convertUnicodeEscapesIfRequired(String json) { - return json // TODO: verify if that's fine or escapeJava required + String unescapedJson = StringEscapeUtils.unescapeJavaScript(json) + return StringEscapeUtils.escapeJava(unescapedJson) } @Override @@ -77,4 +76,24 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { protected String getSimpleResponseBodyString(String responseString) { return "Object responseBody = ($responseString);" } + + @Override + protected String getResponseString(Request request) { + return 'ResponseOptions response = given().spec(request)' + } + + @Override + protected String getRequestString() { + return 'MockMvcRequestSpecification request = given()' + } + + @Override + protected String getHeaderString(Header header) { + return ".header(\"${getTestSideValue(header.name)}\", \"${getTestSideValue(header.serverValue)}\")" + } + + @Override + protected String getBodyString(String bodyAsString) { + return ".body(\"$bodyAsString\")" + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy index abf43d77fc..0a5339f0e0 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy @@ -1,4 +1,5 @@ package io.codearte.accurest.builder + import groovy.transform.PackageScope import groovy.transform.TypeChecked import io.codearte.accurest.dsl.GroovyDsl @@ -14,6 +15,9 @@ class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { super(stubDefinition) } + @Override + protected void given(BlockBuilder bb) {} + @Override protected void givenBlock(BlockBuilder bb) { } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index 5580687632..3f92a12f5e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -3,13 +3,16 @@ 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.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.JsonPaths import io.codearte.accurest.util.JsonToJsonPathsConverter @@ -39,15 +42,11 @@ abstract class MethodBodyBuilder { protected abstract void validateResponseHeadersBlock(BlockBuilder bb) - protected void given(BlockBuilder bb) {} - - protected abstract void when(BlockBuilder bb) - protected abstract String getResponseAsString() protected abstract String addCommentSignIfRequired(String baseString) - protected abstract String addColonIfRequired(String baseString) + protected abstract BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) protected abstract String getResponseBodyPropertyComparisonString(String property, String value) @@ -65,6 +64,14 @@ abstract class MethodBodyBuilder { protected abstract String getSimpleResponseBodyString(String responseString) + protected abstract String getResponseString(Request request) + + protected abstract String getRequestString() + + protected abstract String getHeaderString(Header header) + + protected abstract String getBodyString(String bodyAsString) + void appendTo(BlockBuilder blockBuilder) { blockBuilder.startBlock() @@ -74,6 +81,7 @@ abstract class MethodBodyBuilder { blockBuilder.endBlock() } + protected void thenBlock(BlockBuilder bb) { bb.addLine(addCommentSignIfRequired('then:')) bb.startBlock() @@ -95,6 +103,32 @@ abstract class MethodBodyBuilder { bb.endBlock().addEmptyLine() } + protected void given(BlockBuilder bb) { + bb.addLine(getRequestString()) + 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 entry -> bb.addLine(getMultipartParameterLine(entry)) } + } + 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");/) + bb.unindent() + } protected void then(BlockBuilder bb) { validateResponseCodeBlock(bb) @@ -103,7 +137,7 @@ abstract class MethodBodyBuilder { } if (response.body) { bb.endBlock() - bb.addLine('and:').startBlock() + bb.addLine(addCommentSignIfRequired('and:')).startBlock() validateResponseBodyBlock(bb) } } @@ -115,18 +149,21 @@ abstract class MethodBodyBuilder { responseBody = extractValue(responseBody, contentType, { DslProperty dslProperty -> dslProperty.serverValue }) } if (contentType == ContentType.JSON) { - appendJsonPath(bb, responseAsString) + appendJsonPath(bb, getResponseAsString()) JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) jsonPaths.each { bb.addLine("assertThat(parsedJson)" + it.method()) + addColonIfRequired(bb) } processBodyElement(bb, "", responseBody) } else if (contentType == ContentType.XML) { - bb.addLine(getParsedXmlResponseBodyString(responseAsString)) + bb.addLine(getParsedXmlResponseBodyString(getResponseAsString())) + addColonIfRequired(bb) // TODO xml validation - } else { - bb.addLine(getSimpleResponseBodyString(responseAsString)) + } else { + bb.addLine(getSimpleResponseBodyString(getResponseAsString())) processText(bb, "", responseBody as String) + addColonIfRequired(bb) } } @@ -139,15 +176,18 @@ abstract class MethodBodyBuilder { } protected void appendJsonPath(BlockBuilder blockBuilder, String json) { - blockBuilder.addLine(addColonIfRequired("DocumentContext parsedJson = JsonPath.parse($json)")) + blockBuilder.addLine(("DocumentContext parsedJson = JsonPath.parse($json)")) + addColonIfRequired(blockBuilder) } protected void processText(BlockBuilder blockBuilder, String property, String value) { if (value.startsWith('$')) { value = value.substring(1).replaceAll('\\$value', "responseBody$property") blockBuilder.addLine(value) + addColonIfRequired(blockBuilder) } else { blockBuilder.addLine(getResponseBodyPropertyComparisonString(property, value)) + addColonIfRequired(blockBuilder) } } @@ -226,4 +266,32 @@ abstract class MethodBodyBuilder { processBodyElement(blockBuilder, prop, listElement) } } + + 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) { List result, QueryParameter param -> + result << "${param.name}=${resolveParamValue(param).toString()}" + } + .join('&') + return "${MapConverter.getTestSideValues(url.serverValue)}?$params" + } + return MapConverter.getTestSideValues(url.serverValue) + } + + + private boolean hasQueryParams(Url url) { + return url.queryParameters + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy index 707a2eae42..6bfc8c357f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy @@ -9,7 +9,7 @@ import java.util.regex.Pattern * @author Olga Maciaszek-Sharma * @since 2016-02-17 */ -class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder{ +class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { MockMvcJUnitMethodBodyBuilder(GroovyDsl stubDefinition) { super(stubDefinition) @@ -28,10 +28,12 @@ class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder{ } private String createHeaderComparison(Object headerValue) { - return "isEqualTo(\"$headerValue\");" + String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") + return "isEqualTo(\"$escapedHeader\");" } private String createHeaderComparison(Pattern headerValue) { - return "matches(\"$headerValue\");" + String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") + return "matches(\"$escapedHeader\");" } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index 64cf5e4afc..fe18c08a19 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -2,13 +2,8 @@ package io.codearte.accurest.builder 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.QueryParameter -import io.codearte.accurest.dsl.internal.Request -import io.codearte.accurest.dsl.internal.Url -import io.codearte.accurest.util.MapConverter import java.util.regex.Pattern @@ -20,36 +15,12 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { super(stubDefinition) } - protected void given(BlockBuilder bb) { - bb.addLine('def request = given()') - bb.indent() - request.headers?.collect { Header header -> - bb.addLine(".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')") - } - if (request.body) { - bb.addLine(".body('''$bodyAsString''')") - } - if (request.multipart) { - multipartParameters?.each { Map.Entry entry -> bb.addLine(getMultipartParameterLine(entry)) } - } - bb.unindent() - } - - protected void when(BlockBuilder bb) { - bb.addLine('def response = given().spec(request)') - bb.indent() - - String url = buildUrl(request) - String method = request.method.serverValue.toString().toLowerCase() - - bb.addLine(/.${method}("$url")/) - bb.unindent() - } - + @Override protected void validateResponseCodeBlock(BlockBuilder bb) { bb.addLine("response.statusCode == $response.status.serverValue") } + @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { response.headers?.collect { Header header -> bb.addLine("response.header('$header.name') ${convertHeaderComparison(header.serverValue)}") @@ -68,30 +39,4 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { protected String getResponseAsString() { return 'response.body.asString()' } - - 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) { List result, QueryParameter param -> - result << "${param.name}=${resolveParamValue(param).toString()}" - } - .join('&') - return "${MapConverter.getTestSideValues(url.serverValue)}?$params" - } - return MapConverter.getTestSideValues(url.serverValue) - } - - private boolean hasQueryParams(Url url) { - return url.queryParameters - } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 3f40878d9a..b61807f689 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -1,22 +1,15 @@ package io.codearte.accurest.builder -import groovy.json.JsonOutput import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked 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.MatchingStrategy +import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.NamedProperty -import io.codearte.accurest.dsl.internal.QueryParameter -import io.codearte.accurest.util.ContentType -import io.codearte.accurest.util.MapConverter +import io.codearte.accurest.dsl.internal.Request -import static io.codearte.accurest.util.ContentUtils.extractValue import static io.codearte.accurest.util.ContentUtils.getMultipartFileParameterContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader /** * @author Jakub Kubrynski @@ -58,8 +51,8 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { } @Override - protected String addColonIfRequired(String baseString) { - return baseString + protected BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) { + return blockBuilder } @Override @@ -74,11 +67,32 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { @Override protected String getParsedXmlResponseBodyString(String responseString) { - return "def responseBody = new XmlSlurper().parseText($responseAsString)" + return "def responseBody = new XmlSlurper().parseText($responseString)" } @Override protected String getSimpleResponseBodyString(String responseString) { - return "def responseBody = ($responseAsString)" + return "def responseBody = ($responseString)" } + + @Override + protected String getResponseString(Request request) { + return 'def response = given().spec(request)' + } + + @Override + protected String getRequestString() { + return 'def request = given()' + } + + @Override + protected String getHeaderString(Header header) { + return ".header('${getTestSideValue(header.name)}', '${getTestSideValue(header.serverValue)}')" + } + + @Override + protected String getBodyString(String bodyAsString) { + return ".body('''$bodyAsString''')" + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index 3148dc6a97..410375b385 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -2,6 +2,8 @@ package io.codearte.accurest.util; import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; +import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; + /** * @author Marcin Grzejszczak */ @@ -11,7 +13,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { private final StringBuffer methodsBuffer; DelegatingJsonVerifiable(JsonVerifiable delegate, - StringBuffer methodsBuffer) { + StringBuffer methodsBuffer) { this.delegate = delegate; this.methodsBuffer = new StringBuffer(methodsBuffer.toString()); } @@ -100,7 +102,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate.isAssertingAValueInArray()) { readyToCheck.methodsBuffer.append(".value()"); } else { - readyToCheck.appendMethodWithQuotedValue("isEqualTo", value); + readyToCheck.appendMethodWithQuotedValue("isEqualTo", escapeJava(value)); } return readyToCheck; } @@ -137,7 +139,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate.isAssertingAValueInArray()) { readyToCheck.methodsBuffer.append(".value()"); } else { - readyToCheck.appendMethodWithQuotedValue("matches", value); + readyToCheck.appendMethodWithQuotedValue("matches", escapeJava(value)); } return readyToCheck; } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy new file mode 100644 index 0000000000..7e78ab2475 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy @@ -0,0 +1,973 @@ +package io.codearte.accurest.builder + +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.WireMockStubStrategy +import io.codearte.accurest.dsl.WireMockStubVerifier +import io.codearte.accurest.file.Contract +import jdk.nashorn.internal.ir.annotations.Ignore +import spock.lang.Issue +import spock.lang.Specification +import spock.lang.Unroll + +import java.util.regex.Pattern + +/** + * @author Olga Maciaszek-Sharma + * @since 2015-08-07 + */ +class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStubVerifier { + + 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" +}""" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains('assertThat(parsedJson).field("property1").isEqualTo("a");') + blockBuilder.toString().contains('assertThat(parsedJson).field("property2").isEqualTo("b");') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("#187") + def "should generate assertions for null and boolean values"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ + "property1": "true", + "property2": null, + "property3": false +}""" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true");""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull();""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false);""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("#79") + def "should generate assertions for simple response body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth");""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("#82") + def "should generate proper request when body constructed from map with a list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + items: ['HOP'] + ) + } + response { + status 200 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains('.body("{\\"items\\":[\\"HOP\\"]}")') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("#88") + def "should generate proper request when body constructed from GString"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + "property1=VAL1" + ) + } + response { + status 200 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains('.body("\\"property1=VAL1\\"")') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue("185") + def "should generate assertions for a response body containing map with integers as keys"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property: [ + 14: 0.0, + 7 : 0.0 + ] + ) + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(7).isEqualTo(0.0);""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(14).isEqualTo(0.0);""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + 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" +}]""" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b");""") + blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + 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"} + ] +}""" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1");""") + blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + 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"} +} +''' + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b");""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate regex assertions for map objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: "a", + property2: value( + client('123'), + server(regex('[0-9]{3}')) + ) + ) + headers { + header('Content-Type': 'application/json') + + } + + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}");""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + + def "should generate regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + headers { + header('Content-Type': 'application/json') + + } + + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}");""") + blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue(["#126", "#143"]) + def "should generate escaped regex assertions for string objects in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property":" ${value(client('123'), server(regex('\\d+')))}"}""") + headers { + header('Content-Type': 'application/json') + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + then: + blockBuilder.toString().contains("""assertThat(parsedJson).field("property").matches("\\\\d+");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate a call with an url path and query parameters"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + jUnitTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') + jUnitTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue('#169') + def "should generate a call with an url path and query parameters with url containing a pattern"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + jUnitTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') + jUnitTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate test for empty body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method('POST') + url("/ws/payments") + body("") + } + response { + status 406 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains(".body(\"\\\"\\\"\")") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should generate test for String in response body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "POST" + url "test" + } + response { + status 200 + body "test" + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('Object responseBody = (response.getBody().asString());') + jUnitTest.contains('assertThat(responseBody).isEqualTo("test");') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue('113') + def "should generate regex test for String in response header"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'POST' + url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) + headers { header 'Content-Type': 'application/json' } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex('http://localhost/partners/[0-9]+/users/[0-9]+'))) + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + @Issue('115') + def "should generate regex with helper method"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'POST' + url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) + headers { header 'Content-Type': 'application/json' } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex("^${hostname()}/partners/[0-9]+/users/[0-9]+"))) + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");') + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should work with more complex stuff and jsonpaths"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + priority 10 + request { + method 'POST' + url '/validation/client' + headers { + header 'Content-Type': 'application/json' + } + body( + bank_account_number: '0014282912345698765432161182', + email: 'foo@bar.com', + phone_number: '100299300', + personal_id: 'ABC123456' + ) + } + + response { + status 200 + body(errors: [ + [property: "bank_account_number", message: "incorrect_format"] + ]) + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains("""assertThat(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number");""") + jUnitTest.contains("""assertThat(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format");""") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + + } + + def "should work properly with GString url"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + + request { + method 'PUT' + url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" + headers { + header 'Content-Type': 'application/json' + } + body( + first_name: 'Josef', + ) + } + response { + status 422 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains("/partners/11/agents/11/customers/09665703Z") + and: + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + + def "should resolve properties in GString with regular expression"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(client(regex(email())), server('not.existing@user.com')), + callback_url: $(client(regex(hostname())), server('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: 4, + message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + ) + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''') + } + + + @Issue('42') + @Unroll + def "should not omit the optional field in the test creation"() { + given: + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('\\"email\\":\\"abc@abc.com\\"') + jUnitTest.contains('assertThat(parsedJson).field("code").matches("(123123)?");') + !jUnitTest.contains('''REGEXP''') + !jUnitTest.contains('''OPTIONAL''') + !jUnitTest.contains('''OptionalProperty''') + where: + contractDsl << [ + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: value(stub("123123"), test(optional("123123"))), + message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) + } + }, + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", + "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" + } + """ + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "code" : "${value(stub(123123), test(optional(123123)))}", + "message" : "User not found by email = [${ + value(server(regex(email())), client('not.existing@user.com')) + }]" + } + """ + ) + } + } + ] + } + + @Issue('72') + @Ignore + //TODO: fix exec method for jUnit + def "should make the execute method work"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + + } + + } + response { + status 200 + body("""{ + "fraudCheckStatus": "OK", + "rejectionReason": ${value(client(null), server(execute('assertThatRejectionReasonIsNull($it)')))} +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + + } + + } + + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''') + } + + def "should support inner map and list definitions"() { + given: + + Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) + Pattern ANYSTRING = Pattern.compile(/.*/) + Pattern NUMBERS = Pattern.compile(/[\d\.]*/) + Pattern DATETIME = ANYSTRING + + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" + headers { + header('Content-Type': 'application/json') + } + body( + client: [ + first_name : $(stub(regex(onlyAlphaUnicode())), test('Denis')), + last_name : $(stub(regex(onlyAlphaUnicode())), test('FakeName')), + email : $(stub(regex(email())), test('fakemail@fakegmail.com')), + fax : $(stub(PHONE_NUMBER), test('+xx001213214')), + phone : $(stub(PHONE_NUMBER), test('2223311')), + data_of_birth: $(stub(DATETIME), test('2002-10-22T00:00:00Z')) + ], + client_id_card: [ + id : $(stub(ANYSTRING), test('ABC12345')), + date_of_issue: $(stub(ANYSTRING), test('2002-10-02T00:00:00Z')), + address : [ + street : $(stub(ANYSTRING), test('Light Street')), + city : $(stub(ANYSTRING), test('Fire')), + region : $(stub(ANYSTRING), test('Skys')), + country: $(stub(ANYSTRING), test('HG')), + zip : $(stub(NUMBERS), test('658965')) + ] + ], + incomes_and_expenses: [ + monthly_income : $(stub(NUMBERS), test('0.0')), + monthly_loan_repayments: $(stub(NUMBERS), test('100')), + monthly_living_expenses: $(stub(NUMBERS), test('22')) + ], + additional_info: [ + allow_to_contact: $(stub(optional(regex(anyBoolean()))), test('true')) + ] + ) + } + response { + status 200 + headers { + header('Content-Type': 'application/json') + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains '\\"street\\":\\"Light Street\\"' + !jUnitTest.contains("clientValue") + !jUnitTest.contains("cursor") + } + + def "shouldn't generate unicode escape characters"() { + given: + Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) + + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев" + headers { + header('Content-Type': 'application/json') + } + body( + client: [ + first_name: $(stub(ONLY_ALPHA_UNICODE), test('Пенева')), + last_name : $(stub(ONLY_ALPHA_UNICODE), test('Пенева')) + ] + ) + } + response { + status 200 + headers { + header('Content-Type': 'application/json') + } + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + !jUnitTest.contains("\\u041f") + } + + @Issue('177') + def "should generate proper test code when having multiline body"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multiline" + body('''hello, +World.''') + } + response { + status 200 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains("""'''hello, +World.'''""") + } + + @Issue('180') + @Ignore + //TODO: fix multiparts in JUnit + def "should generate proper test code when having multipart parameters"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + headers { + header('content-type', 'multipart/form-data;boundary=AaB03x') + } + multipart( + formParameter: value(client(regex('.+')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named(value(client(regex('.+')), server('filename.csv')), value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains("""'content-type', 'multipart/form-data;boundary=AaB03x'""") + jUnitTest.contains(""".param('formParameter', '"formParameterValue"'""") + jUnitTest.contains(""".param('someBooleanParameter', 'true')""") + jUnitTest.contains(""".multiPart('file', 'filename.csv', 'file content'.bytes)""") + } + + @Issue('180') + @Ignore + //TODO: fix multiparts in JUnit + def "should generate proper test code when having multipart parameters with named as map"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + multipart( + formParameter: value(client(regex('".+"')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named( + name: value(client(regex('.+')), server('filename.csv')), + content: value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def jUnitTest = blockBuilder.toString() + then: + jUnitTest.contains('.multiPart') + } + + +} From d2a6044b3635300463e2f0bf6c9920de1aac43d5 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Fri, 19 Feb 2016 16:15:17 +0100 Subject: [PATCH 287/719] Raised JsonAssert version. Switched to assertThatJson() method. Fixed some tests. --- .../accurest/SingleTestGenerator.groovy | 3 +- .../accurest/builder/MethodBodyBuilder.groovy | 2 +- .../accurest/SingleTestGeneratorSpec.groovy | 4 +- .../JaxRsClientSpockMethodBuilderSpec.groovy | 48 ++-- .../MockMvcJunitMethodBuilderSpec.groovy | 63 ++--- .../MockMvcSpockMethodBuilderSpec.groovy | 267 +++++++++--------- gradle.properties | 2 +- 7 files changed, 196 insertions(+), 193 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 309173138f..ba23ee1bdb 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -15,7 +15,8 @@ import static io.codearte.accurest.util.NamesUtil.capitalize @Slf4j class SingleTestGenerator { - private static final String JSON_ASSERT_STATIC_IMPORT = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThat' + private static + final String JSON_ASSERT_STATIC_IMPORT = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson' private static final String JSON_ASSERT_CLASS = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion' private final AccurestConfigProperties configProperties diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index 3f92a12f5e..1702962476 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -152,7 +152,7 @@ abstract class MethodBodyBuilder { appendJsonPath(bb, getResponseAsString()) JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) jsonPaths.each { - bb.addLine("assertThat(parsedJson)" + it.method()) + bb.addLine("assertThatJson(parsedJson)" + it.method()) addColonIfRequired(bb) } processBodyElement(bb, "", responseBody) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy index fbfa267ec4..7a9d560c9b 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -18,12 +18,12 @@ class SingleTestGeneratorSpec extends Specification { static List jUnitClassStrings = ['package test;', 'import com.jayway.jsonpath.DocumentContext;', 'import com.jayway.jsonpath.JsonPath;', 'import org.junit.FixMethodOrder;', 'import org.junit.Ignore;', 'import org.junit.Test;', 'import org.junit.runners.MethodSorters;', - 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThat;', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*;', + 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson;', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*;', '@FixMethodOrder(MethodSorters.NAME_ASCENDING)', '@Test', '@Ignore'] static List spockClassStrings = ['package test', 'import com.jayway.jsonpath.DocumentContext', 'import com.jayway.jsonpath.JsonPath', 'import spock.lang.Ignore', 'import spock.lang.Specification', 'import spock.lang.Stepwise', - 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThat', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*', + 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*', '@Stepwise', '@Ignore'] def setup() { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index 9662646416..81cfcb2755 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -29,8 +29,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -57,9 +57,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false)""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull()""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property3").isEqualTo(false)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isNull()""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("true")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -88,9 +88,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth")""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -168,8 +168,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -196,8 +196,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -224,8 +224,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").field("property3").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -258,15 +258,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + GroovyDsl contractDsl = GroovyDsl.make { request { method "GET" url "test" @@ -286,8 +286,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -388,8 +388,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc spockTest.contains("queryParam('age', '99'") spockTest.contains("queryParam('name', 'Denis.Stepanov'") spockTest.contains("queryParam('email', 'bob@email.com'") - spockTest.contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") - spockTest.contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""") + spockTest.contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + spockTest.contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -400,7 +400,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc GroovyDsl contractDsl = GroovyDsl.make { request { method 'GET' - url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))){ + url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { queryParameters { parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) parameter 'offset': $(client(containing("20")), server(equalTo("20"))) @@ -439,8 +439,8 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc spockTest.contains("queryParam('age', '99'") spockTest.contains("queryParam('name', 'Denis.Stepanov'") spockTest.contains("queryParam('email', 'bob@email.com'") - spockTest.contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") - spockTest.contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""") + spockTest.contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + spockTest.contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy index 7e78ab2475..f3bd466005 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy @@ -4,7 +4,7 @@ import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier import io.codearte.accurest.file.Contract -import jdk.nashorn.internal.ir.annotations.Ignore +import spock.lang.Ignore import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll @@ -37,8 +37,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains('assertThat(parsedJson).field("property1").isEqualTo("a");') - blockBuilder.toString().contains('assertThat(parsedJson).field("property2").isEqualTo("b");') + blockBuilder.toString().contains('assertThatJson(parsedJson).field("property1").isEqualTo("a");') + blockBuilder.toString().contains('assertThatJson(parsedJson).field("property2").isEqualTo("b");') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -65,9 +65,9 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true");""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull();""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false);""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("true");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isNull();""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property3").isEqualTo(false);""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -96,9 +96,9 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth");""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse");""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -176,8 +176,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(7).isEqualTo(0.0);""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(14).isEqualTo(0.0);""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(7).isEqualTo(0.0);""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(14).isEqualTo(0.0);""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -205,8 +205,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b");""") - blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property2").isEqualTo("b");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property1").isEqualTo("a");""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -233,8 +233,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1");""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property2").isEqualTo("test1");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property3").isEqualTo("test2");""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -261,8 +261,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b");""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").field("property3").isEqualTo("b");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a");""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -295,8 +295,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}");""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a");""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -324,8 +324,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}");""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a");""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -351,7 +351,7 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property").matches("\\\\d+");""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").matches("\\\\d+");""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -393,8 +393,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu def jUnitTest = blockBuilder.toString() then: jUnitTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - jUnitTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') - jUnitTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') + jUnitTest.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') + jUnitTest.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -437,8 +437,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu def jUnitTest = blockBuilder.toString() then: jUnitTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - jUnitTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') - jUnitTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') + jUnitTest.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') + jUnitTest.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -591,8 +591,8 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu builder.appendTo(blockBuilder) def jUnitTest = blockBuilder.toString() then: - jUnitTest.contains("""assertThat(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number");""") - jUnitTest.contains("""assertThat(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format");""") + jUnitTest.contains("""assertThatJson(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number");""") + jUnitTest.contains("""assertThatJson(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format");""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) @@ -659,7 +659,7 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu builder.appendTo(blockBuilder) def jUnitTest = blockBuilder.toString() then: - jUnitTest.contains('''$[?(@.message =~ /User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]/)]''') + jUnitTest.contains('''assertThatJson(parsedJson).field("message").matches("User not found by email = \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,4}\\\\\\\\]");''') } @@ -674,7 +674,7 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu def jUnitTest = blockBuilder.toString() then: jUnitTest.contains('\\"email\\":\\"abc@abc.com\\"') - jUnitTest.contains('assertThat(parsedJson).field("code").matches("(123123)?");') + jUnitTest.contains('assertThatJson(parsedJson).field("code").matches("(123123)?");') !jUnitTest.contains('''REGEXP''') !jUnitTest.contains('''OPTIONAL''') !jUnitTest.contains('''OptionalProperty''') @@ -940,8 +940,8 @@ World.'''""") } @Issue('180') - @Ignore //TODO: fix multiparts in JUnit + @Ignore def "should generate proper test code when having multipart parameters with named as map"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -969,5 +969,4 @@ World.'''""") jUnitTest.contains('.multiPart') } - } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index 56444a53ad..c88781b155 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -9,6 +9,7 @@ import spock.lang.Specification import spock.lang.Unroll import java.util.regex.Pattern + /** * @author Jakub Kubrynski */ @@ -34,8 +35,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -62,9 +63,9 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("true")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").isNull()""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property3").isEqualTo(false)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("true")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isNull()""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property3").isEqualTo(false)""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -93,9 +94,9 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("a").isEqualTo("sth")""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -173,8 +174,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(7).isEqualTo(0.0)""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property").field(14).isEqualTo(0.0)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(7).isEqualTo(0.0)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(14).isEqualTo(0.0)""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -202,8 +203,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property2").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThat(parsedJson).array().contains("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property2").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -230,8 +231,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") - blockBuilder.toString().contains("""assertThat(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -258,15 +259,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").field("property3").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").field("property3").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for map objects in response body"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + GroovyDsl contractDsl = GroovyDsl.make { request { method "GET" url "test" @@ -292,38 +293,38 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } def "should generate regex assertions for string objects in response body"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") - headers { - header('Content-Type': 'application/json') + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") + headers { + header('Content-Type': 'application/json') + + } } - } - } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property2").matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThat(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @Issue(["#126", "#143"]) @@ -347,7 +348,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThat(parsedJson).field("property").matches("\\d+")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").matches("\\\\d+")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -389,8 +390,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu def spockTest = blockBuilder.toString() then: spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - spockTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') - spockTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') + spockTest.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') + spockTest.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -401,7 +402,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu GroovyDsl contractDsl = GroovyDsl.make { request { method 'GET' - url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))){ + url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { queryParameters { parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) parameter 'offset': $(client(containing("20")), server(equalTo("20"))) @@ -433,8 +434,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu def spockTest = blockBuilder.toString() then: spockTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - spockTest.contains('assertThat(parsedJson).field("property1").isEqualTo("a")') - spockTest.contains('assertThat(parsedJson).field("property2").isEqualTo("b")') + spockTest.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') + spockTest.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -587,8 +588,8 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains("""assertThat(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number")""") - spockTest.contains("""assertThat(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format")""") + spockTest.contains("""assertThatJson(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number")""") + spockTest.contains("""assertThatJson(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) } @@ -654,7 +655,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains("""assertThat(parsedJson).field("message").matches("User not found by email = \\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4}\\\\]")""") + spockTest.contains("""assertThatJson(parsedJson).field("message").matches("User not found by email = \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,4}\\\\\\\\]")""") } @Issue('42') @@ -668,67 +669,69 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu def spockTest = blockBuilder.toString() then: spockTest.contains('''"email":"abc@abc.com"''') - spockTest.contains("""assertThat(parsedJson).field("code").matches("(123123)?")""") + spockTest.contains("""assertThatJson(parsedJson).field("code").matches("(123123)?")""") !spockTest.contains('''REGEXP''') !spockTest.contains('''OPTIONAL''') !spockTest.contains('''OptionalProperty''') where: - contractDsl << [ - GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' + contractDsl << [ + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) } - body( - email: $(stub(optional(regex(email()))), test('abc@abc.com')), - callback_url: $(stub(regex(hostname())), test('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: value(stub("123123"), test(optional("123123"))), + message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) } - body( - code: value(stub("123123"), test(optional("123123"))), - message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" - ) - } - }, - GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - """ { + }, + GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + """ { "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" } """ - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' + ) } - body( - """ { + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + """ { "code" : "${value(stub(123123), test(optional(123123)))}", - "message" : "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + "message" : "User not found by email = [${ + value(server(regex(email())), client('not.existing@user.com')) + }]" } """ - ) + ) + } } - } - ] + ] } @Issue('72') @@ -753,7 +756,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } response { status 200 - body( """{ + body("""{ "fraudCheckStatus": "OK", "rejectionReason": ${value(client(null), server(execute('assertThatRejectionReasonIsNull($it)')))} }""") @@ -791,26 +794,26 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } body( client: [ - first_name: $(stub(regex(onlyAlphaUnicode())), test('Denis')), - last_name: $(stub(regex(onlyAlphaUnicode())), test('FakeName')), - email: $(stub(regex(email())), test('fakemail@fakegmail.com')), - fax: $(stub(PHONE_NUMBER), test('+xx001213214')), - phone: $(stub(PHONE_NUMBER), test('2223311')), + first_name : $(stub(regex(onlyAlphaUnicode())), test('Denis')), + last_name : $(stub(regex(onlyAlphaUnicode())), test('FakeName')), + email : $(stub(regex(email())), test('fakemail@fakegmail.com')), + fax : $(stub(PHONE_NUMBER), test('+xx001213214')), + phone : $(stub(PHONE_NUMBER), test('2223311')), data_of_birth: $(stub(DATETIME), test('2002-10-22T00:00:00Z')) ], client_id_card: [ - id: $(stub(ANYSTRING), test('ABC12345')), + id : $(stub(ANYSTRING), test('ABC12345')), date_of_issue: $(stub(ANYSTRING), test('2002-10-02T00:00:00Z')), - address: [ - street: $(stub(ANYSTRING), test('Light Street')), - city: $(stub(ANYSTRING), test('Fire')), - region: $(stub(ANYSTRING), test('Skys')), + address : [ + street : $(stub(ANYSTRING), test('Light Street')), + city : $(stub(ANYSTRING), test('Fire')), + region : $(stub(ANYSTRING), test('Skys')), country: $(stub(ANYSTRING), test('HG')), - zip: $(stub(NUMBERS), test('658965')) + zip : $(stub(NUMBERS), test('658965')) ] ], incomes_and_expenses: [ - monthly_income: $(stub(NUMBERS), test('0.0')), + monthly_income : $(stub(NUMBERS), test('0.0')), monthly_loan_repayments: $(stub(NUMBERS), test('100')), monthly_living_expenses: $(stub(NUMBERS), test('22')) ], @@ -897,7 +900,7 @@ World.'''""") } @Issue('180') - def "should generate proper test code when having multipart parameters"(){ + def "should generate proper test code when having multipart parameters"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -929,32 +932,32 @@ World.'''""") } @Issue('180') - def "should generate proper test code when having multipart parameters with named as map"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/multipart" - multipart( - formParameter: value(client(regex('".+"')), server('"formParameterValue"')), - someBooleanParameter: value(client(regex('(true|false)')), server('true')), - file: named( - name: value(client(regex('.+')), server('filename.csv')), - content: value(client(regex('.+')), server('file content'))) - ) - } - response { - status 200 - } - } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def spockTest = blockBuilder.toString() - then: - spockTest.contains('.multiPart') - } + def "should generate proper test code when having multipart parameters with named as map"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + multipart( + formParameter: value(client(regex('".+"')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named( + name: value(client(regex('.+')), server('filename.csv')), + content: value(client(regex('.+')), server('file content'))) + ) + } + response { + status 200 + } + } + MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.given(blockBuilder) + def spockTest = blockBuilder.toString() + then: + spockTest.contains('.multiPart') + } } diff --git a/gradle.properties b/gradle.properties index bc99f91ba8..fa9182de93 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,4 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.5-beta -jsonassertVersion = 0.1.0 +jsonassertVersion = 0.1.2 From 57c030189bd030ba4417dfd56bd6a45f0371890c Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Sun, 21 Feb 2016 18:00:24 +0100 Subject: [PATCH 288/719] Fixed handling execution properties in JUnit tests. --- .../accurest/builder/JUnitMethodBodyBuilder.groovy | 9 ++++++++- .../builder/MockMvcJunitMethodBuilderSpec.groovy | 4 +--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index f6153341d1..d3365490d0 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -64,7 +64,14 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { @Override protected void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) { - processBodyElement(blockBuilder, property + """.get(\\\"$entry.key\\\")""", entry.value) + processBodyElement(blockBuilder, property + getMapKeyReferenceString(entry), entry.value) + } + + private String getMapKeyReferenceString(Map.Entry entry) { + if (entry.value instanceof ExecutionProperty){ + return "." + entry.key + } + return """.get(\\\"$entry.key\\\")""" } @Override diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy index f3bd466005..0fa9e420f0 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy @@ -740,8 +740,6 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu } @Issue('72') - @Ignore - //TODO: fix exec method for jUnit def "should make the execute method work"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -781,7 +779,7 @@ class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStu builder.appendTo(blockBuilder) def jUnitTest = blockBuilder.toString() then: - jUnitTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''') + jUnitTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''') } def "should support inner map and list definitions"() { From 71adb9f1ff249cb6ae131dbf6c120a76d1566f56 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Sun, 21 Feb 2016 18:55:13 +0100 Subject: [PATCH 289/719] Fixed multipart support in JUnit tests. --- .../builder/JUnitMethodBodyBuilder.groovy | 25 +++++++++++++------ .../accurest/builder/MethodBodyBuilder.groovy | 19 +++++++++++--- .../builder/SpockMethodBodyBuilder.groovy | 20 ++++++++------- .../accurest/util/ContentUtils.groovy | 8 +++++- .../MockMvcJunitMethodBuilderSpec.groovy | 13 +++------- .../MockMvcSpockMethodBuilderSpec.groovy | 2 +- 6 files changed, 55 insertions(+), 32 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index d3365490d0..c5f33b921a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -6,8 +6,12 @@ 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.NamedProperty import io.codearte.accurest.dsl.internal.Request +import static groovy.json.StringEscapeUtils.escapeJava +import static io.codearte.accurest.util.ContentUtils.getJavaMultipartFileParameterContent + /** * @author Jakub Kubrynski * @author Olga Maciaszek-Sharma @@ -41,11 +45,6 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { return "assertThat(responseBody${property}).isEqualTo(\"${value}\");" } - @Override - protected String getMultipartParameterLine(Map.Entry parameter) { - return null //TODO - } - @Override protected void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { blockBuilder.addLine("${exec.insertValue("parsedJson.read(\"\\\$$property\")")};") @@ -59,7 +58,7 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { @Override protected String convertUnicodeEscapesIfRequired(String json) { String unescapedJson = StringEscapeUtils.unescapeJavaScript(json) - return StringEscapeUtils.escapeJava(unescapedJson) + return escapeJava(unescapedJson) } @Override @@ -68,10 +67,10 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { } private String getMapKeyReferenceString(Map.Entry entry) { - if (entry.value instanceof ExecutionProperty){ + if (entry.value instanceof ExecutionProperty) { return "." + entry.key } - return """.get(\\\"$entry.key\\\")""" + return """.get(\\\"$entry.key\\\")""" } @Override @@ -103,4 +102,14 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { protected String getBodyString(String bodyAsString) { return ".body(\"$bodyAsString\")" } + + @Override + protected String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) { + return getJavaMultipartFileParameterContent(propertyName, propertyValue) + } + + @Override + protected String getParameterString(Map.Entry parameter) { + return """.param("${escapeJava(parameter.key)}", "${escapeJava(parameter.value as String)}")""" + } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index 1702962476..a795923e0e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -9,6 +9,7 @@ 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 @@ -19,6 +20,7 @@ import io.codearte.accurest.util.JsonToJsonPathsConverter import io.codearte.accurest.util.MapConverter import static io.codearte.accurest.util.ContentUtils.extractValue +import static io.codearte.accurest.util.ContentUtils.getGroovyMultipartFileParameterContent import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader @@ -50,8 +52,6 @@ abstract class MethodBodyBuilder { protected abstract String getResponseBodyPropertyComparisonString(String property, String value) - protected abstract String getMultipartParameterLine(Map.Entry parameter) - protected abstract void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) protected abstract void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) @@ -72,6 +72,10 @@ abstract class MethodBodyBuilder { protected abstract String getBodyString(String bodyAsString) + protected abstract String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) + + protected abstract String getParameterString(Map.Entry parameter) + void appendTo(BlockBuilder blockBuilder) { blockBuilder.startBlock() @@ -126,7 +130,8 @@ abstract class MethodBodyBuilder { String url = buildUrl(request) String method = request.method.serverValue.toString().toLowerCase() - bb.addLine(/.${method}("$url");/) + bb.addLine(/.${method}("$url")/) + addColonIfRequired(bb) bb.unindent() } @@ -275,7 +280,6 @@ abstract class MethodBodyBuilder { throw new IllegalStateException("URL is not set!") } - @TypeChecked(TypeCheckingMode.SKIP) protected String buildUrlFromUrlPath(Url url) { if (hasQueryParams(url)) { @@ -290,6 +294,13 @@ abstract class MethodBodyBuilder { return MapConverter.getTestSideValues(url.serverValue) } + protected String getMultipartParameterLine(Map.Entry 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 diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index b61807f689..55dba94b57 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -9,7 +9,7 @@ import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.NamedProperty import io.codearte.accurest.dsl.internal.Request -import static io.codearte.accurest.util.ContentUtils.getMultipartFileParameterContent +import static io.codearte.accurest.util.ContentUtils.getGroovyMultipartFileParameterContent /** * @author Jakub Kubrynski @@ -27,14 +27,6 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { return "responseBody$property == \"${value}\"" } - @Override - protected String getMultipartParameterLine(Map.Entry parameter) { - if (parameter.value instanceof NamedProperty) { - return ".multiPart(${getMultipartFileParameterContent(parameter.key, (NamedProperty) parameter.value)})" - } - return ".param('$parameter.key', '$parameter.value')" - } - @Override protected void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { blockBuilder.addLine("${exec.insertValue("parsedJson.read('\\\$$property')")}") @@ -95,4 +87,14 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { return ".body('''$bodyAsString''')" } + @Override + protected String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) { + return getGroovyMultipartFileParameterContent(propertyName, propertyValue) + } + + @Override + protected String getParameterString(Map.Entry parameter) { + return ".param('$parameter.key', '$parameter.value')" + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index e73990d9f4..87e93b4e9e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -15,6 +15,7 @@ import org.codehaus.groovy.runtime.GStringImpl import java.util.regex.Matcher import java.util.regex.Pattern +import static org.apache.commons.lang3.StringEscapeUtils.escapeJava import static org.apache.commons.lang3.StringEscapeUtils.escapeJson import static org.apache.commons.lang3.StringEscapeUtils.escapeXml11 @@ -321,8 +322,13 @@ class ContentUtils { return ContentType.UNKNOWN } - static String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) { + static String getGroovyMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) { return "'$propertyName', '$propertyValue.name.serverValue', '$propertyValue.value.serverValue'.bytes" } + static String getJavaMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) { + return """"${escapeJava(propertyName)}", "${escapeJava(propertyValue.name.serverValue as String)}", "${escapeJava(propertyValue.value.serverValue as String)}".getBytes()""" + } + + } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy index 0fa9e420f0..91c5ffb18f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy @@ -4,7 +4,6 @@ import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier import io.codearte.accurest.file.Contract -import spock.lang.Ignore import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll @@ -904,8 +903,6 @@ World.'''""") } @Issue('180') - @Ignore - //TODO: fix multiparts in JUnit def "should generate proper test code when having multipart parameters"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -931,15 +928,13 @@ World.'''""") builder.given(blockBuilder) def jUnitTest = blockBuilder.toString() then: - jUnitTest.contains("""'content-type', 'multipart/form-data;boundary=AaB03x'""") - jUnitTest.contains(""".param('formParameter', '"formParameterValue"'""") - jUnitTest.contains(""".param('someBooleanParameter', 'true')""") - jUnitTest.contains(""".multiPart('file', 'filename.csv', 'file content'.bytes)""") + jUnitTest.contains('"content-type", "multipart/form-data;boundary=AaB03x"') + jUnitTest.contains('.param("formParameter", "\\"formParameterValue\\"")') + jUnitTest.contains('.param("someBooleanParameter", "true")') + jUnitTest.contains('.multiPart("file", "filename.csv", "file content".getBytes());') } @Issue('180') - //TODO: fix multiparts in JUnit - @Ignore def "should generate proper test code when having multipart parameters with named as map"() { given: GroovyDsl contractDsl = GroovyDsl.make { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy index c88781b155..3b7df919f0 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy @@ -922,7 +922,7 @@ World.'''""") MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.given(blockBuilder) + builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: spockTest.contains("""'content-type', 'multipart/form-data;boundary=AaB03x'""") From 3cae227d19b6cbd09462f6237faf7e83ac492e38 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Sun, 21 Feb 2016 22:47:50 +0100 Subject: [PATCH 290/719] Merged specs for MockMvcSpockMethodBuilder and MockMvcJUnitMethodBuilder. --- .../MockMvcJunitMethodBuilderSpec.groovy | 965 ------------------ ...groovy => MockMvcMethodBuilderSpec.groovy} | 546 ++++++---- 2 files changed, 352 insertions(+), 1159 deletions(-) delete mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy rename accurest-core/src/test/groovy/io/codearte/accurest/builder/{MockMvcSpockMethodBuilderSpec.groovy => MockMvcMethodBuilderSpec.groovy} (52%) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy deleted file mode 100644 index 91c5ffb18f..0000000000 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcJunitMethodBuilderSpec.groovy +++ /dev/null @@ -1,965 +0,0 @@ -package io.codearte.accurest.builder - -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.dsl.WireMockStubStrategy -import io.codearte.accurest.dsl.WireMockStubVerifier -import io.codearte.accurest.file.Contract -import spock.lang.Issue -import spock.lang.Specification -import spock.lang.Unroll - -import java.util.regex.Pattern - -/** - * @author Olga Maciaszek-Sharma - * @since 2015-08-07 - */ -class MockMvcJunitMethodBuilderSpec extends Specification implements WireMockStubVerifier { - - 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" -}""" - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains('assertThatJson(parsedJson).field("property1").isEqualTo("a");') - blockBuilder.toString().contains('assertThatJson(parsedJson).field("property2").isEqualTo("b");') - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue("#187") - def "should generate assertions for null and boolean values"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body """{ - "property1": "true", - "property2": null, - "property3": false -}""" - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("true");""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isNull();""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property3").isEqualTo(false);""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue("#79") - def "should generate assertions for simple response body constructed from map with a list"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property1: 'a', - property2: [ - [a: 'sth'], - [b: 'sthElse'] - ] - ) - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a");""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth");""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse");""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue("#82") - def "should generate proper request when body constructed from map with a list"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - body( - items: ['HOP'] - ) - } - response { - status 200 - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains('.body("{\\"items\\":[\\"HOP\\"]}")') - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue("#88") - def "should generate proper request when body constructed from GString"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - body( - "property1=VAL1" - ) - } - response { - status 200 - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains('.body("\\"property1=VAL1\\"")') - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue("185") - def "should generate assertions for a response body containing map with integers as keys"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property: [ - 14: 0.0, - 7 : 0.0 - ] - ) - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(7).isEqualTo(0.0);""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(14).isEqualTo(0.0);""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - 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" -}]""" - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property2").isEqualTo("b");""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property1").isEqualTo("a");""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - 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"} - ] -}""" - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property2").isEqualTo("test1");""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property3").isEqualTo("test2");""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - 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"} -} -''' - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").field("property3").isEqualTo("b");""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a");""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - def "should generate regex assertions for map objects in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property1: "a", - property2: value( - client('123'), - server(regex('[0-9]{3}')) - ) - ) - headers { - header('Content-Type': 'application/json') - - } - - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}");""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a");""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - - def "should generate regex assertions for string objects in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") - headers { - header('Content-Type': 'application/json') - - } - - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}");""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a");""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue(["#126", "#143"]) - def "should generate escaped regex assertions for string objects in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body("""{"property":" ${value(client('123'), server(regex('\\d+')))}"}""") - headers { - header('Content-Type': 'application/json') - } - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").matches("\\\\d+");""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - def "should generate a call with an url path and query parameters"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'GET' - urlPath('/users') { - queryParameters { - parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) - parameter 'offset': $(client(containing("20")), server(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) - parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) - parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) - parameter 'email': "bob@email.com" - parameter 'hello': $(client(matching("Denis.*")), server(absent())) - parameter 'hello': absent() - } - } - } - response { - status 200 - body """ - { - "property1": "a", - "property2": "b" - } - """ - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - jUnitTest.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') - jUnitTest.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue('#169') - def "should generate a call with an url path and query parameters with url containing a pattern"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'GET' - url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { - queryParameters { - parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) - parameter 'offset': $(client(containing("20")), server(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) - parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) - parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) - parameter 'email': "bob@email.com" - parameter 'hello': $(client(matching("Denis.*")), server(absent())) - parameter 'hello': absent() - } - } - } - response { - status 200 - body """ - { - "property1": "a", - "property2": "b" - } - """ - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - jUnitTest.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') - jUnitTest.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - def "should generate test for empty body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method('POST') - url("/ws/payments") - body("") - } - response { - status 406 - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains(".body(\"\\\"\\\"\")") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - def "should generate test for String in response body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "POST" - url "test" - } - response { - status 200 - body "test" - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('Object responseBody = (response.getBody().asString());') - jUnitTest.contains('assertThat(responseBody).isEqualTo("test");') - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue('113') - def "should generate regex test for String in response header"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'POST' - url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) - headers { header 'Content-Type': 'application/json' } - body( - first_name: 'John', - last_name: 'Smith', - personal_id: '12345678901', - phone_number: '500500500', - invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', - password: 'john' - ) - } - response { - status 201 - headers { - header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex('http://localhost/partners/[0-9]+/users/[0-9]+'))) - } - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");') - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - @Issue('115') - def "should generate regex with helper method"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'POST' - url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) - headers { header 'Content-Type': 'application/json' } - body( - first_name: 'John', - last_name: 'Smith', - personal_id: '12345678901', - phone_number: '500500500', - invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', - password: 'john' - ) - } - response { - status 201 - headers { - header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex("^${hostname()}/partners/[0-9]+/users/[0-9]+"))) - } - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");') - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - def "should work with more complex stuff and jsonpaths"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - priority 10 - request { - method 'POST' - url '/validation/client' - headers { - header 'Content-Type': 'application/json' - } - body( - bank_account_number: '0014282912345698765432161182', - email: 'foo@bar.com', - phone_number: '100299300', - personal_id: 'ABC123456' - ) - } - - response { - status 200 - body(errors: [ - [property: "bank_account_number", message: "incorrect_format"] - ]) - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains("""assertThatJson(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number");""") - jUnitTest.contains("""assertThatJson(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format");""") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - - } - - def "should work properly with GString url"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - - request { - method 'PUT' - url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" - headers { - header 'Content-Type': 'application/json' - } - body( - first_name: 'Josef', - ) - } - response { - status 422 - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains("/partners/11/agents/11/customers/09665703Z") - and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - - def "should resolve properties in GString with regular expression"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - email: $(client(regex(email())), server('not.existing@user.com')), - callback_url: $(client(regex(hostname())), server('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: 4, - message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" - ) - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('''assertThatJson(parsedJson).field("message").matches("User not found by email = \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,4}\\\\\\\\]");''') - } - - - @Issue('42') - @Unroll - def "should not omit the optional field in the test creation"() { - given: - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('\\"email\\":\\"abc@abc.com\\"') - jUnitTest.contains('assertThatJson(parsedJson).field("code").matches("(123123)?");') - !jUnitTest.contains('''REGEXP''') - !jUnitTest.contains('''OPTIONAL''') - !jUnitTest.contains('''OptionalProperty''') - where: - contractDsl << [ - GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - email: $(stub(optional(regex(email()))), test('abc@abc.com')), - callback_url: $(stub(regex(hostname())), test('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: value(stub("123123"), test(optional("123123"))), - message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" - ) - } - }, - GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - """ { - "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", - "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" - } - """ - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - """ { - "code" : "${value(stub(123123), test(optional(123123)))}", - "message" : "User not found by email = [${ - value(server(regex(email())), client('not.existing@user.com')) - }]" - } - """ - ) - } - } - ] - } - - @Issue('72') - def "should make the execute method work"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - - } - - } - response { - status 200 - body("""{ - "fraudCheckStatus": "OK", - "rejectionReason": ${value(client(null), server(execute('assertThatRejectionReasonIsNull($it)')))} -}""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - - } - - } - - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''') - } - - def "should support inner map and list definitions"() { - given: - - Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) - Pattern ANYSTRING = Pattern.compile(/.*/) - Pattern NUMBERS = Pattern.compile(/[\d\.]*/) - Pattern DATETIME = ANYSTRING - - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" - headers { - header('Content-Type': 'application/json') - } - body( - client: [ - first_name : $(stub(regex(onlyAlphaUnicode())), test('Denis')), - last_name : $(stub(regex(onlyAlphaUnicode())), test('FakeName')), - email : $(stub(regex(email())), test('fakemail@fakegmail.com')), - fax : $(stub(PHONE_NUMBER), test('+xx001213214')), - phone : $(stub(PHONE_NUMBER), test('2223311')), - data_of_birth: $(stub(DATETIME), test('2002-10-22T00:00:00Z')) - ], - client_id_card: [ - id : $(stub(ANYSTRING), test('ABC12345')), - date_of_issue: $(stub(ANYSTRING), test('2002-10-02T00:00:00Z')), - address : [ - street : $(stub(ANYSTRING), test('Light Street')), - city : $(stub(ANYSTRING), test('Fire')), - region : $(stub(ANYSTRING), test('Skys')), - country: $(stub(ANYSTRING), test('HG')), - zip : $(stub(NUMBERS), test('658965')) - ] - ], - incomes_and_expenses: [ - monthly_income : $(stub(NUMBERS), test('0.0')), - monthly_loan_repayments: $(stub(NUMBERS), test('100')), - monthly_living_expenses: $(stub(NUMBERS), test('22')) - ], - additional_info: [ - allow_to_contact: $(stub(optional(regex(anyBoolean()))), test('true')) - ] - ) - } - response { - status 200 - headers { - header('Content-Type': 'application/json') - } - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains '\\"street\\":\\"Light Street\\"' - !jUnitTest.contains("clientValue") - !jUnitTest.contains("cursor") - } - - def "shouldn't generate unicode escape characters"() { - given: - Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) - - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев" - headers { - header('Content-Type': 'application/json') - } - body( - client: [ - first_name: $(stub(ONLY_ALPHA_UNICODE), test('Пенева')), - last_name : $(stub(ONLY_ALPHA_UNICODE), test('Пенева')) - ] - ) - } - response { - status 200 - headers { - header('Content-Type': 'application/json') - } - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.appendTo(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - !jUnitTest.contains("\\u041f") - } - - @Issue('177') - def "should generate proper test code when having multiline body"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/multiline" - body('''hello, -World.''') - } - response { - status 200 - } - } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def spockTest = blockBuilder.toString() - then: - spockTest.contains("""'''hello, -World.'''""") - } - - @Issue('180') - def "should generate proper test code when having multipart parameters"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/multipart" - headers { - header('content-type', 'multipart/form-data;boundary=AaB03x') - } - multipart( - formParameter: value(client(regex('.+')), server('"formParameterValue"')), - someBooleanParameter: value(client(regex('(true|false)')), server('true')), - file: named(value(client(regex('.+')), server('filename.csv')), value(client(regex('.+')), server('file content'))) - ) - } - response { - status 200 - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('"content-type", "multipart/form-data;boundary=AaB03x"') - jUnitTest.contains('.param("formParameter", "\\"formParameterValue\\"")') - jUnitTest.contains('.param("someBooleanParameter", "true")') - jUnitTest.contains('.multiPart("file", "filename.csv", "file content".getBytes());') - } - - @Issue('180') - def "should generate proper test code when having multipart parameters with named as map"() { - given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/multipart" - multipart( - formParameter: value(client(regex('".+"')), server('"formParameterValue"')), - someBooleanParameter: value(client(regex('(true|false)')), server('true')), - file: named( - name: value(client(regex('.+')), server('filename.csv')), - content: value(client(regex('.+')), server('file content'))) - ) - } - response { - status 200 - } - } - MockMvcJUnitMethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") - when: - builder.given(blockBuilder) - def jUnitTest = blockBuilder.toString() - then: - jUnitTest.contains('.multiPart') - } - -} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBuilderSpec.groovy similarity index 52% rename from accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBuilderSpec.groovy index 3b7df919f0..14153a93d6 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBuilderSpec.groovy @@ -5,6 +5,7 @@ import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier import io.codearte.accurest.file.Contract import spock.lang.Issue +import spock.lang.Shared import spock.lang.Specification import spock.lang.Unroll @@ -13,9 +14,70 @@ import java.util.regex.Pattern /** * @author Jakub Kubrynski */ -class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStubVerifier { +class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVerifier { - def "should generate assertions for simple response body"() { + @Shared + GroovyDsl dslWithOptionalsInString = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: value(stub("123123"), test(optional("123123"))), + message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) + } + } + + @Shared + GroovyDsl dslWithOptionals = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", + "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" + } + """ + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + """ { + "code" : "${value(stub(123123), test(optional(123123)))}", + "message" : "User not found by email = [${ + value(server(regex(email())), client('not.existing@user.com')) + }]" + } + """ + ) + } + } + + @Unroll + def "should generate assertions for simple response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -30,7 +92,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu }""" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -38,11 +100,16 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#187") - def "should generate assertions for null and boolean values"() { + @Unroll + def "should generate assertions for null and boolean values with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -58,7 +125,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu }""" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -67,11 +134,16 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isNull()""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property3").isEqualTo(false)""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#79") - def "should generate assertions for simple response body constructed from map with a list"() { + @Unroll + def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -89,7 +161,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu ) } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -98,11 +170,16 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#82") - def "should generate proper request when body constructed from map with a list"() { + @Unroll + def "should generate proper request when body constructed from map with a list #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -116,18 +193,23 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu status 200 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains(""".body('''{\"items\":[\"HOP\"]}''')""") + blockBuilder.toString().contains(bodyString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """.body('''{\"items\":[\"HOP\"]}''')""" + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("{\\"items\\":[\\"HOP\\"]}")' } @Issue("#88") - def "should generate proper request when body constructed from GString"() { + @Unroll + def "should generate proper request when body constructed from GString with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -141,18 +223,23 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu status 200 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains(""".body('''property1=VAL1''')""") + blockBuilder.toString().contains(bodyString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """.body('''property1=VAL1''')""" + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("\\"property1=VAL1\\"")' } @Issue("185") - def "should generate assertions for a response body containing map with integers as keys"() { + @Unroll + def "should generate assertions for a response body containing map with integers as keys with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -169,7 +256,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu ) } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -177,10 +264,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(7).isEqualTo(0.0)""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(14).isEqualTo(0.0)""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should generate assertions for array in response body"() { + @Unroll + def "should generate assertions for array in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -198,7 +290,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu }]""" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -206,10 +298,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property2").isEqualTo("b")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should generate assertions for array inside response body element"() { + @Unroll + def "should generate assertions for array inside response body element with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -226,7 +323,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu }""" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -234,10 +331,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should generate assertions for nested objects in response body"() { + @Unroll + def "should generate assertions for nested objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -254,7 +356,7 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu ''' } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -262,10 +364,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").field("property3").isEqualTo("b")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should generate regex assertions for map objects in response body"() { + @Unroll + def "should generate regex assertions for map objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -283,12 +390,10 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu ) headers { header('Content-Type': 'application/json') - } - } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -296,10 +401,15 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should generate regex assertions for string objects in response body"() { + @Unroll + def "should generate regex assertions for string objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -311,12 +421,10 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") headers { header('Content-Type': 'application/json') - } - } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -324,11 +432,16 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue(["#126", "#143"]) - def "should generate escaped regex assertions for string objects in response body"() { + @Unroll + def "should generate escaped regex assertions for string objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -343,17 +456,22 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").matches("\\\\d+")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should generate a call with an url path and query parameters"() { + @Unroll + def "should generate a call with an url path and query parameters with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -383,21 +501,26 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu """ } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - spockTest.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') - spockTest.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') + test.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + test.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') + test.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('#169') - def "should generate a call with an url path and query parameters with url containing a pattern"() { + @Unroll + def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -427,20 +550,25 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu """ } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - spockTest.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') - spockTest.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') + test.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + test.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') + test.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should generate test for empty body"() { + @Unroll + def "should generate test for empty body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -452,18 +580,23 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu status 406 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains(".body('''''')") + test.contains(bodyString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | ".body('''''')" + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")" } - def "should generate test for String in response body"() { + @Unroll + def "should generate test for String in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -475,20 +608,25 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu body "test" } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('def responseBody = (response.body.asString())') - spockTest.contains('responseBody == "test"') + test.contains(bodyDefinitionString) + test.contains(bodyEvaluationString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (response.getBody().asString());' | 'assertThat(responseBody).isEqualTo("test");' } @Issue('113') - def "should generate regex test for String in response header"() { + @Unroll + def "should generate regex test for String in response header with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -511,19 +649,24 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''') + test.contains(headerEvaluationString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | headerEvaluationString + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' } @Issue('115') - def "should generate regex with helper method"() { + @Unroll + def "should generate regex with helper method with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -546,18 +689,23 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''') + test.contains(headerEvaluationString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | headerEvaluationString + "MockMvcSpockMethodBuilder" | { 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" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");' } - def "should work with more complex stuff and jsonpaths"() { + @Unroll + def "should work with more complex stuff and jsonpaths with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { priority 10 @@ -582,19 +730,24 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu ]) } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains("""assertThatJson(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number")""") - spockTest.contains("""assertThatJson(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format")""") + test.contains("""assertThatJson(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number")""") + test.contains("""assertThatJson(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should work properly with GString url"() { + @Unroll + def "should work properly with GString url with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -612,18 +765,23 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu status 422 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('''/partners/11/agents/11/customers/09665703Z''') + test.contains('''/partners/11/agents/11/customers/09665703Z''') and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - def "should resolve properties in GString with regular expression"() { + @Unroll + def "should resolve properties in GString with regular expression with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { priority 1 @@ -649,93 +807,60 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu ) } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains("""assertThatJson(parsedJson).field("message").matches("User not found by email = \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,4}\\\\\\\\]")""") + 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" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('42') @Unroll - def "should not omit the optional field in the test creation"() { + def "should not omit the optional field in the test creation with MockMvcSpockMethodBodyBuilder"() { given: - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('''"email":"abc@abc.com"''') - spockTest.contains("""assertThatJson(parsedJson).field("code").matches("(123123)?")""") - !spockTest.contains('''REGEXP''') - !spockTest.contains('''OPTIONAL''') - !spockTest.contains('''OptionalProperty''') + test.contains('''"email":"abc@abc.com"''') + test.contains("""assertThatJson(parsedJson).field("code").matches("(123123)?")""") + !test.contains('''REGEXP''') + !test.contains('''OPTIONAL''') + !test.contains('''OptionalProperty''') where: - contractDsl << [ - GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - email: $(stub(optional(regex(email()))), test('abc@abc.com')), - callback_url: $(stub(regex(hostname())), test('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: value(stub("123123"), test(optional("123123"))), - message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" - ) - } - }, - GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - """ { - "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", - "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" - } - """ - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - """ { - "code" : "${value(stub(123123), test(optional(123123)))}", - "message" : "User not found by email = [${ - value(server(regex(email())), client('not.existing@user.com')) - }]" - } - """ - ) - } - } - ] + contractDsl << [dslWithOptionals, dslWithOptionalsInString] + } + + @Issue('42') + @Unroll + def "should not omit the optional field in the test creation with MockMvcJUnitMethodBodyBuilder"() { + given: + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('\\"email\\":\\"abc@abc.com\\"') + test.contains('assertThatJson(parsedJson).field("code").matches("(123123)?");') + !test.contains('''REGEXP''') + !test.contains('''OPTIONAL''') + !test.contains('''OptionalProperty''') + where: + contractDsl << [dslWithOptionals, dslWithOptionalsInString] } @Issue('72') - def "should make the execute method work"() { + @Unroll + def "should make the execute method work with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -750,7 +875,6 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu ) headers { header("""Content-Type""", """application/vnd.fraud.v1+json""") - } } @@ -762,22 +886,24 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu }""") headers { header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''') + test.contains(assertionString) + where: + methodBuilderName | methodBuilder | assertionString + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''' + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''' } - def "should support inner map and list definitions"() { + @Unroll + def "should support inner map and list definitions with #methodBuilderName"() { given: Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) @@ -829,19 +955,24 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains '"street":"Light Street"' - !spockTest.contains("clientValue") - !spockTest.contains("cursor") + test.contains bodyString + !test.contains("clientValue") + !test.contains("cursor") + where: + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '"street":"Light Street"' + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"street\\":\\"Light Street\\"' + } - - def "shouldn't generate unicode escape characters"() { + @Unroll + def "shouldn't generate unicode escape characters with #methodBuilderName"() { given: Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) @@ -866,17 +997,22 @@ class MockMvcSpockMethodBuilderSpec extends Specification implements WireMockStu } } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - !spockTest.contains("\\u041f") + !test.contains("\\u041f") + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('177') - def "should generate proper test code when having multiline body"() { + @Unroll + def "should generate proper test code when having multiline body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -889,18 +1025,23 @@ World.''') status 200 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.given(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains("""'''hello, -World.'''""") + test.contains(bodyString) + where: + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """'''hello, +World.'''""" + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"hello,\\nWorld.\\"' } @Issue('180') - def "should generate proper test code when having multipart parameters"() { + @Unroll + def "should generate proper test code when having multipart parameters with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -919,20 +1060,30 @@ World.'''""") status 200 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains("""'content-type', 'multipart/form-data;boundary=AaB03x'""") - spockTest.contains(""".param('formParameter', '"formParameterValue"'""") - spockTest.contains(""".param('someBooleanParameter', 'true')""") - spockTest.contains(""".multiPart('file', 'filename.csv', 'file content'.bytes)""") + for (String requestString : requestStrings) { + test.contains(requestString) + } + where: + methodBuilderName | methodBuilder | requestStrings + "MockMvcSpockMethodBuilder" | { 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" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['"content-type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", "filename.csv", "file content".getBytes());'] } @Issue('180') - def "should generate proper test code when having multipart parameters with named as map"() { + @Unroll + def "should generate proper test code when having multipart parameters with named as map with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -950,14 +1101,21 @@ World.'''""") status 200 } } - MockMvcSpockMethodBodyBuilder builder = new MockMvcSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.given(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains('.multiPart') + test.contains('.multiPart') + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } + protected void stubMappingIsValidWireMockStub(GroovyDsl contractDsl) { + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } } From 337027136ebd4b184844f8092e42d4d307c66be2 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 22 Feb 2016 16:20:17 +0100 Subject: [PATCH 291/719] Added JUnit support for JaxRs tests. --- .../accurest/SingleTestGenerator.groovy | 3 + .../JaxRsClientJUnitMethodBodyBuilder.groovy | 108 ++++++++ .../JaxRsClientSpockMethodBuilderSpec.groovy | 252 ++++++++++++------ ...vy => MockMvcMethodBodyBuilderSpec.groovy} | 114 ++++---- .../accurest/dsl/WireMockStubVerifier.groovy | 5 + 5 files changed, 341 insertions(+), 141 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy rename accurest-core/src/test/groovy/io/codearte/accurest/builder/{MockMvcMethodBuilderSpec.groovy => MockMvcMethodBodyBuilderSpec.groovy} (83%) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index ba23ee1bdb..42ca73417c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -52,6 +52,9 @@ class SingleTestGenerator { if (configProperties.testMode == TestMode.JAXRSCLIENT) { clazz.addStaticImport('javax.ws.rs.client.Entity.*') + if (configProperties.targetFramework == TestFramework.JUNIT) { + clazz.addImport('import javax.ws.rs.core.Response') + } } else if (configProperties.testMode == TestMode.MOCKMVC) { clazz.addStaticImport('com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*') } else { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy new file mode 100644 index 0000000000..79180caf54 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy @@ -0,0 +1,108 @@ +package io.codearte.accurest.builder + +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.internal.Header +import io.codearte.accurest.dsl.internal.QueryParameter +import io.codearte.accurest.dsl.internal.QueryParameters + +/** + * @author Olga Maciaszek-Sharma + @since 21.02.16 + */ +class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { + + JaxRsClientJUnitMethodBodyBuilder(GroovyDsl stubDefinition) { + super(stubDefinition) + } + + @Override + protected void given(BlockBuilder bb) {} + + @Override + protected void givenBlock(BlockBuilder bb) { + } + + @Override + protected void when(BlockBuilder bb) { + bb.addLine("Response response = webTarget") + bb.indent() + + appendUrlPathAndQueryParameters(bb) + appendRequestWithRequiredResponseContentType(bb) + appendHeaders(bb) + appendMethodAndBody(bb) + bb.addAtTheEnd(';') + + bb.unindent() + + bb.addEmptyLine() + bb.addLine("String responseAsString = response.readEntity(String.class);") + } + + protected void appendUrlPathAndQueryParameters(BlockBuilder bb) { + if (request.url) { + bb.addLine(".path(\"$request.url.serverValue\")") + appendQueryParams(request.url.queryParameters, bb) + } else if (request.urlPath) { + bb.addLine(".path(\"$request.urlPath.serverValue\")") + appendQueryParams(request.urlPath.queryParameters, bb) + } + } + + private void appendQueryParams(QueryParameters queryParameters, BlockBuilder bb) { + if (!queryParameters?.parameters) { + return + } + queryParameters.parameters.findAll(this.&allowedQueryParameter).each { QueryParameter param -> + bb.addLine(".queryParam(\"$param.name\", \"${resolveParamValue(param).toString()}\")") + } + } + + protected void appendMethodAndBody(BlockBuilder bb) { + String method = request.method.serverValue.toString().toLowerCase() + if (request.body) { + String contentType = getHeader('Content-Type') ?: getRequestContentType().mimeType + bb.addLine(".method(\"${method.toUpperCase()}\", entity(\"$bodyAsString\", \"$contentType\"))") + } else { + bb.addLine(".method(\"${method.toUpperCase()}\")") + } + } + + protected appendHeaders(BlockBuilder bb) { + request.headers?.collect { Header header -> + if (header.name == 'Content-Type' || header.name == 'Accept') return + bb.addLine(".header(\"${header.name}\", \"${header.serverValue}\")") + } + } + + protected void appendRequestWithRequiredResponseContentType(BlockBuilder bb) { + String acceptHeader = getHeader("Accept") + if (acceptHeader) { + bb.addLine(".request(\"$acceptHeader\")") + } else { + bb.addLine(".request()") + } + } + + @Override + protected void validateResponseCodeBlock(BlockBuilder bb) { + bb.addLine("assertThat(response.getStatus()).isEqualTo($response.status.serverValue);") + } + + @Override + protected void validateResponseHeadersBlock(BlockBuilder bb) { + response.headers?.collect { Header header -> + bb.addLine("assertThat(response.getHeaderString(\"$header.name\")).isEqualTo(\"$header.serverValue\");") + } + } + + protected String getHeader(String name) { + return request.headers?.entries.find { it.name == name }?.serverValue + } + + @Override + protected String getResponseAsString() { + return 'responseAsString' + } + +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy index 81cfcb2755..e2fdca8146 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy @@ -6,10 +6,12 @@ import io.codearte.accurest.dsl.WireMockStubVerifier import io.codearte.accurest.file.Contract import spock.lang.Issue import spock.lang.Specification +import spock.lang.Unroll class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMockStubVerifier { - def "should generate assertions for simple response body"() { + @Unroll + def "should generate assertions for simple response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -24,7 +26,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc }""" } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -32,11 +34,16 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#187") - def "should generate assertions for null and boolean values"() { + @Unroll + def "should generate assertions for null and boolean values with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -52,7 +59,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc }""" } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -62,10 +69,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("true")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + where: + methodBuilderName | methodBuilder + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#79") - def "should generate assertions for simple response body constructed from map with a list"() { + @Unroll + def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -83,7 +95,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc ) } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -93,10 +105,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + where: + methodBuilderName | methodBuilder + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#82") - def "should generate proper request when body constructed from map with a list"() { + @Unroll + def "should generate proper request when body constructed from map with a list with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -110,18 +127,23 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc status 200 } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""entity('{\"items\":[\"HOP\"]}', 'application/json')""") + blockBuilder.toString().contains(bodyString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + 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")' } @Issue("#88") - def "should generate proper request when body constructed from GString"() { + @Unroll + def "should generate proper request when body constructed from GString with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -135,17 +157,22 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc status 200 } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""entity('property1=VAL1', 'application/octet-stream')""") + blockBuilder.toString().contains(bodyString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + 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")' } - def "should generate assertions for array in response body"() { + @Unroll + def "should generate assertions for array in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -163,7 +190,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc }]""" } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -171,10 +198,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property1").isEqualTo("a")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property2").isEqualTo("b")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - def "should generate assertions for array inside response body element"() { + @Unroll + def "should generate assertions for array inside response body element with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -191,7 +223,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc }""" } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -199,10 +231,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - def "should generate assertions for nested objects in response body"() { + @Unroll + def "should generate assertions for nested objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -219,7 +256,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc ''' } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -227,10 +264,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").field("property3").isEqualTo("b")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - def "should generate regex assertions for map objects in response body"() { + @Unroll + def "should generate regex assertions for map objects in response body with #methodBodyName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -253,7 +295,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -261,10 +303,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - def "should generate regex assertions for string objects in response body"() { + @Unroll + def "should generate regex assertions for string objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -281,7 +328,7 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -289,10 +336,15 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - def "should ignore 'Accept' header and use 'request' method"() { + @Unroll + def "should ignore 'Accept' header and use 'request' method with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -306,17 +358,22 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc status 200 } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("request('text/plain')") + blockBuilder.toString().contains(requestString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | requestString + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | "request('text/plain')" + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")' } - def "should ignore 'Content-Type' header and use 'entity' method"() { + @Unroll + def "should ignore 'Content-Type' header and use 'entity' method with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -332,19 +389,25 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc status 200 } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""entity('', 'text/plain')""") - blockBuilder.toString().contains("""header('Timer', '123')""") - !blockBuilder.toString().contains("""header('Content-Type'""") + for (String requestString : requestStrings) { + blockBuilder.toString().contains(requestString) + } + !blockBuilder.toString().contains("""Content Type""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + 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")'] } - def "should generate a call with an url path and query parameters"() { + @Unroll + def "should generate a call with an url path and query parameters with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -374,28 +437,33 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc """ } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains("queryParam('limit', '10'") - spockTest.contains("queryParam('offset', '20'") - spockTest.contains("queryParam('filter', 'email'") - spockTest.contains("queryParam('sort', 'name'") - spockTest.contains("queryParam('search', '55'") - spockTest.contains("queryParam('age', '99'") - spockTest.contains("queryParam('name', 'Denis.Stepanov'") - spockTest.contains("queryParam('email', 'bob@email.com'") - spockTest.contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") - spockTest.contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") + test.contains(modifyStringIfRequired.call("queryParam('limit', '10'")) + test.contains(modifyStringIfRequired.call("queryParam('offset', '20'")) + test.contains(modifyStringIfRequired.call("queryParam('filter', 'email'")) + test.contains(modifyStringIfRequired.call("queryParam('sort', 'name'")) + test.contains(modifyStringIfRequired.call("queryParam('search', '55'")) + test.contains(modifyStringIfRequired.call("queryParam('age', '99'")) + test.contains(modifyStringIfRequired.call("queryParam('name', 'Denis.Stepanov'")) + test.contains(modifyStringIfRequired.call("queryParam('email', 'bob@email.com'")) + test.contains(modifyStringIfRequired.call("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""")) + test.contains(modifyStringIfRequired.call("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""")) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + 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("'", "\"") } } @Issue('#169') - def "should generate a call with an url path and query parameters with url containing a pattern"() { + @Unroll + def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -425,27 +493,32 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc """ } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains("queryParam('limit', '10'") - spockTest.contains("queryParam('offset', '20'") - spockTest.contains("queryParam('filter', 'email'") - spockTest.contains("queryParam('sort', 'name'") - spockTest.contains("queryParam('search', '55'") - spockTest.contains("queryParam('age', '99'") - spockTest.contains("queryParam('name', 'Denis.Stepanov'") - spockTest.contains("queryParam('email', 'bob@email.com'") - spockTest.contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") - spockTest.contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") + test.contains(modifyStringIfRequired.call("queryParam('limit', '10'")) + test.contains(modifyStringIfRequired.call("queryParam('offset', '20'")) + test.contains(modifyStringIfRequired.call("queryParam('filter', 'email'")) + test.contains(modifyStringIfRequired.call("queryParam('sort', 'name'")) + test.contains(modifyStringIfRequired.call("queryParam('search', '55'")) + test.contains(modifyStringIfRequired.call("queryParam('age', '99'")) + test.contains(modifyStringIfRequired.call("queryParam('name', 'Denis.Stepanov'")) + test.contains(modifyStringIfRequired.call("queryParam('email', 'bob@email.com'")) + test.contains(modifyStringIfRequired.call("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""")) + test.contains(modifyStringIfRequired.call("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""")) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + 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("'", "\"") } } - def "should generate test for empty body"() { + @Unroll + def "should generate test for empty body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -457,18 +530,24 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc status 406 } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains("entity('', 'application/octet-stream')") + spockTest.contains(bodyString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + 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"' } - def "should generate test for String in response body"() { + @Unroll + def "should generate test for String in response body with #methodBodyName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -480,20 +559,25 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc body "test" } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains("String responseAsString = response.readEntity(String)") - spockTest.contains('responseBody == "test"') + test.contains(bodyDefinitionString) + test.contains(bodyEvaluationString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + 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");' } @Issue('#171') - def "should generate test with uppercase method name"() { + @Unroll + def "should generate test with uppercase method name with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -510,15 +594,19 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc """ } } - JaxRsClientSpockMethodBodyBuilder builder = new JaxRsClientSpockMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = methodBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def spockTest = blockBuilder.toString() then: - spockTest.contains(".method('GET')") + spockTest.contains(methodString) and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | methodString + "JaxRsClientSpockMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodBodyBuilder(dsl) } | ".method('GET')" + "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")' } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy similarity index 83% rename from accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBuilderSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index 14153a93d6..d2390e5cca 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -14,7 +14,7 @@ import java.util.regex.Pattern /** * @author Jakub Kubrynski */ -class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVerifier { +class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStubVerifier { @Shared GroovyDsl dslWithOptionalsInString = GroovyDsl.make { @@ -103,8 +103,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#187") @@ -137,8 +137,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#79") @@ -173,8 +173,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#82") @@ -203,8 +203,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """.body('''{\"items\":[\"HOP\"]}''')""" - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("{\\"items\\":[\\"HOP\\"]}")' + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """.body('''{\"items\":[\"HOP\"]}''')""" + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("{\\"items\\":[\\"HOP\\"]}")' } @Issue("#88") @@ -233,8 +233,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """.body('''property1=VAL1''')""" - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("\\"property1=VAL1\\"")' + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """.body('''property1=VAL1''')""" + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("\\"property1=VAL1\\"")' } @Issue("185") @@ -267,8 +267,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -301,8 +301,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -334,8 +334,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -367,8 +367,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -404,8 +404,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -435,8 +435,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue(["#126", "#143"]) @@ -466,8 +466,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -514,8 +514,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('#169') @@ -563,8 +563,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -591,8 +591,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | ".body('''''')" - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")" + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | ".body('''''')" + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")" } @Unroll @@ -620,8 +620,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (response.getBody().asString());' | 'assertThat(responseBody).isEqualTo("test");' + "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");' } @Issue('113') @@ -660,8 +660,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | headerEvaluationString - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' + "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]+");' } @Issue('115') @@ -700,8 +700,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | headerEvaluationString - "MockMvcSpockMethodBuilder" | { 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" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");' + "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]+");' } @Unroll @@ -742,8 +742,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -776,8 +776,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Unroll @@ -816,8 +816,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri 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" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('42') @@ -898,8 +898,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri test.contains(assertionString) where: methodBuilderName | methodBuilder | assertionString - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''' - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''' + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''' + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''' } @Unroll @@ -966,8 +966,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri !test.contains("cursor") where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '"street":"Light Street"' - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"street\\":\\"Light Street\\"' + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '"street":"Light Street"' + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"street\\":\\"Light Street\\"' } @@ -1006,8 +1006,8 @@ class MockMvcMethodBuilderSpec extends Specification implements WireMockStubVeri !test.contains("\\u041f") where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('177') @@ -1034,9 +1034,9 @@ World.''') test.contains(bodyString) where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """'''hello, + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | """'''hello, World.'''""" - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"hello,\\nWorld.\\"' + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"hello,\\nWorld.\\"' } @Issue('180') @@ -1071,11 +1071,11 @@ World.'''""" } where: methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | ["""'content-type', 'multipart/form-data;boundary=AaB03x'""", + "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" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['"content-type", "multipart/form-data;boundary=AaB03x"', + "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());'] @@ -1110,12 +1110,8 @@ World.'''""" test.contains('.multiPart') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - - protected void stubMappingIsValidWireMockStub(GroovyDsl contractDsl) { - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy index 6665a642e9..bb4ec0e18d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest.dsl import com.github.tomakehurst.wiremock.stubbing.StubMapping +import io.codearte.accurest.file.Contract import java.util.regex.Pattern @@ -14,4 +15,8 @@ trait WireMockStubVerifier { assert !mappingDefinition.contains('io.codearte.accurest.dsl.internal') } + void stubMappingIsValidWireMockStub(GroovyDsl contractDsl) { + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + } From 853a3953092d996d60cb0e35aeb410c28ab4ef0b Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 22 Feb 2016 16:23:01 +0100 Subject: [PATCH 292/719] Fixed JaxrsClient method builder spec naming. --- .../accurest/SingleTestGeneratorSpec.groovy | 24 ++++++++++++++++++- ...vy => JaxRsClientMethodBuilderSpec.groovy} | 10 ++++---- 2 files changed, 28 insertions(+), 6 deletions(-) rename accurest-core/src/test/groovy/io/codearte/accurest/builder/{JaxRsClientSpockMethodBuilderSpec.groovy => JaxRsClientMethodBuilderSpec.groovy} (98%) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy index 7a9d560c9b..7d2254e27c 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -42,7 +42,29 @@ class SingleTestGeneratorSpec extends Specification { } @Unroll - def "should build test class for #testFramework"() { + def "should build MockMvc test class for #testFramework"() { + given: + AccurestConfigProperties properties = new AccurestConfigProperties(); + properties.targetFramework = testFramework + Contract contract = new Contract(file.toPath(), true, 1, 2) + contract.ignored >> true + contract.order >> 2 + SingleTestGenerator testGenerator = new SingleTestGenerator(properties) + + when: + String clazz = testGenerator.buildClass([contract], "test", "test") + + then: + classStrings.forEach({ clazz.contains(it) }) + + where: + testFramework | classStrings + JUNIT | jUnitClassStrings + SPOCK | spockClassStrings + } + + @Unroll + def "should build JaxRs test class for #testFramework"() { given: AccurestConfigProperties properties = new AccurestConfigProperties(); properties.targetFramework = testFramework diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy similarity index 98% rename from accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy rename to accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy index e2fdca8146..f659c0bab5 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy @@ -8,7 +8,7 @@ import spock.lang.Issue import spock.lang.Specification import spock.lang.Unroll -class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMockStubVerifier { +class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStubVerifier { @Unroll def "should generate assertions for simple response body with #methodBuilderName"() { @@ -535,9 +535,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains(bodyString) + test.contains(bodyString) and: stubMappingIsValidWireMockStub(contractDsl) where: @@ -598,9 +598,9 @@ class JaxRsClientSpockMethodBuilderSpec extends Specification implements WireMoc BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def spockTest = blockBuilder.toString() + def test = blockBuilder.toString() then: - spockTest.contains(methodString) + test.contains(methodString) and: stubMappingIsValidWireMockStub(contractDsl) where: From 28bc9225a8ca9515259ccdfc7b3e21af67615c1e Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 22 Feb 2016 16:36:02 +0100 Subject: [PATCH 293/719] Fixed Jaxrs imports for JUnit in SingleTestGenerator. --- .../groovy/io/codearte/accurest/SingleTestGenerator.groovy | 2 +- .../io/codearte/accurest/SingleTestGeneratorSpec.groovy | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 42ca73417c..12fefbe155 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -53,7 +53,7 @@ class SingleTestGenerator { if (configProperties.testMode == TestMode.JAXRSCLIENT) { clazz.addStaticImport('javax.ws.rs.client.Entity.*') if (configProperties.targetFramework == TestFramework.JUNIT) { - clazz.addImport('import javax.ws.rs.core.Response') + clazz.addImport('javax.ws.rs.core.Response') } } else if (configProperties.testMode == TestMode.MOCKMVC) { clazz.addStaticImport('com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*') diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy index 7d2254e27c..7496f83446 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.config.TestMode import io.codearte.accurest.file.Contract import org.junit.Rule import org.junit.rules.TemporaryFolder @@ -67,6 +68,7 @@ class SingleTestGeneratorSpec extends Specification { def "should build JaxRs test class for #testFramework"() { given: AccurestConfigProperties properties = new AccurestConfigProperties(); + properties.testMode = TestMode.JAXRSCLIENT properties.targetFramework = testFramework Contract contract = new Contract(file.toPath(), true, 1, 2) contract.ignored >> true @@ -81,8 +83,8 @@ class SingleTestGeneratorSpec extends Specification { where: testFramework | classStrings - JUNIT | jUnitClassStrings - SPOCK | spockClassStrings + JUNIT | ['import static javax.ws.rs.client.Entity.*;', 'import javax.ws.rs.core.Response;'] + SPOCK | ['import static javax.ws.rs.client.Entity.*;'] } From b507a5169a774b17050c84e5c37d9a07732b57c1 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 22 Feb 2016 16:43:48 +0100 Subject: [PATCH 294/719] Fixed adding too many colons in simple string body assertion. --- .../io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy | 2 +- .../io/codearte/accurest/builder/MethodBodyBuilder.groovy | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index c5f33b921a..51cabcbade 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -42,7 +42,7 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { @Override protected String getResponseBodyPropertyComparisonString(String property, String value) { - return "assertThat(responseBody${property}).isEqualTo(\"${value}\");" + return "assertThat(responseBody${property}).isEqualTo(\"${value}\")" } @Override diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index a795923e0e..e8b9efb6e0 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -192,7 +192,6 @@ abstract class MethodBodyBuilder { addColonIfRequired(blockBuilder) } else { blockBuilder.addLine(getResponseBodyPropertyComparisonString(property, value)) - addColonIfRequired(blockBuilder) } } From a80078419d01668878140a0b362e88cb4bc2bbc1 Mon Sep 17 00:00:00 2001 From: mchmielarz Date: Mon, 22 Feb 2016 23:49:59 +0100 Subject: [PATCH 295/719] Enabling creation of delayed stub responses. --- .../DslToWireMockClientConverterSpec.groovy | 25 +++++++++++++++++++ .../dsl/WireMockResponseStubStrategy.groovy | 7 ++++++ .../accurest/dsl/internal/Response.groovy | 5 ++++ 3 files changed, 37 insertions(+) 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 61c6b7c29b..478b61f5de 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 @@ -1,6 +1,7 @@ package io.codearte.accurest.wiremock import org.skyscreamer.jsonassert.JSONAssert +import spock.lang.Issue import spock.lang.Specification class DslToWireMockClientConverterSpec extends Specification { @@ -28,6 +29,30 @@ class DslToWireMockClientConverterSpec extends Specification { ''', json, false) } + @Issue("196") + def "should creation of delayed stub responses be possible"() { + given: + def converter = new DslToWireMockClientConverter() + and: + String dslBody = """ + io.codearte.accurest.dsl.GroovyDsl.make { + request { + method "GET" + url "/test" + } + response { + status 200 + fixedDelayMilliseconds 1000 + } + } +""" + when: + String json = converter.convertContent(dslBody) + then: + JSONAssert.assertEquals(''' +{"request":{"method":"GET","url":"/test"},"response":{"status":200, "fixedDelayMilliseconds":1000}} +''', json, false) + } def "should convert DSL file with a nested list to WireMock JSON"() { given: diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy index 3f63e6433c..8dda4777bd 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy @@ -31,6 +31,7 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { .withStatus(response.status.clientValue as Integer) appendHeaders(builder) appendBody(builder) + appendResponseDelayTime(builder) return builder.build() } @@ -53,5 +54,11 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { } } + private void appendResponseDelayTime(ResponseDefinitionBuilder builder) { + if (response.delay) { + builder.withFixedDelay(response.delay.clientValue as Integer) + } + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy index b2546cd5c8..612a092ef1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy @@ -11,6 +11,7 @@ import groovy.transform.TypeChecked class Response extends Common { DslProperty status + DslProperty delay Headers headers Body body @@ -49,6 +50,10 @@ class Response extends Common { this.body = new Body(bodyAsValue) } + void fixedDelayMilliseconds(int timeInMilliseconds) { + this.delay = toDslProperty(timeInMilliseconds) + } + void assertThatSidesMatch(OptionalProperty stubSide, Object testSide) { throw new IllegalStateException("Optional can be used only in the test side of the response!") } From bb5b1d34e7024138593951e3a9191175ae55c004 Mon Sep 17 00:00:00 2001 From: mchmielarz Date: Tue, 23 Feb 2016 10:35:43 +0100 Subject: [PATCH 296/719] Request body removed for better readability. --- .../accurest/wiremock/DslToWireMockClientConverterSpec.groovy | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) 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 478b61f5de..a534257c9b 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 @@ -37,8 +37,6 @@ class DslToWireMockClientConverterSpec extends Specification { String dslBody = """ io.codearte.accurest.dsl.GroovyDsl.make { request { - method "GET" - url "/test" } response { status 200 @@ -50,7 +48,7 @@ class DslToWireMockClientConverterSpec extends Specification { String json = converter.convertContent(dslBody) then: JSONAssert.assertEquals(''' -{"request":{"method":"GET","url":"/test"},"response":{"status":200, "fixedDelayMilliseconds":1000}} +{"request":{},"response":{"status":200,"fixedDelayMilliseconds":1000}} ''', json, false) } From 61f92d7099838afc95e6a038093e2f4c7bd4c426 Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Tue, 23 Feb 2016 11:22:45 +0100 Subject: [PATCH 297/719] Fix test --- .../wiremock/DslToWireMockClientConverterSpec.groovy | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) 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 efa35f27b8..24d0eb2845 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 @@ -41,7 +41,8 @@ class DslToWireMockClientConverterSpec extends Specification { given: def converter = new DslToWireMockClientConverter() and: - String dslBody = """ + File file = tmpFolder.newFile("dsl-delay.groovy") + file.write(""" io.codearte.accurest.dsl.GroovyDsl.make { request { } @@ -50,9 +51,9 @@ class DslToWireMockClientConverterSpec extends Specification { fixedDelayMilliseconds 1000 } } -""" +""") when: - String json = converter.convertContent(dslBody) + String json = converter.convertContent("test", new Contract(file.toPath(), false, 0, null)) then: JSONAssert.assertEquals(''' {"request":{},"response":{"status":200,"fixedDelayMilliseconds":1000}} From 723aa2d37b7f654b24433b06764e982aa4926bca Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 14:09:19 +0100 Subject: [PATCH 298/719] Fixed selecting the right method builder for test framework. Added functional tests for JUnit. --- .../accurest/SingleTestGenerator.groovy | 5 ++ .../accurest/builder/MethodBuilder.groovy | 8 ++- .../plugin/AccurestGradlePlugin.groovy | 1 + .../plugin/SampleJerseyProjectSpec.groovy | 30 +++++++- .../accurest/plugin/SampleProjectSpec.groovy | 30 +++++++- .../com/blogspot/toomuchcoding/MvcTest.java | 70 +++++++++++++++++++ .../com/blogspot/toomuchcoding/MvcTest.java | 18 +++++ build.gradle | 1 + 8 files changed, 160 insertions(+), 3 deletions(-) create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 12fefbe155..6175152361 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -62,7 +62,12 @@ class SingleTestGenerator { } 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) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index 9f0ba231d7..b3d9c5c286 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -48,8 +48,14 @@ class MethodBuilder { blockBuilder.addLine('}') } - private SpockMethodBodyBuilder getMethodBodyBuilder() { + private MethodBodyBuilder getMethodBodyBuilder() { + if (configProperties.testMode == TestMode.MOCKMVC && configProperties.targetFramework == TestFramework.JUNIT){ + return new MockMvcJUnitMethodBodyBuilder(stubContent) + } if (configProperties.testMode == TestMode.JAXRSCLIENT) { + if (configProperties.targetFramework == TestFramework.JUNIT){ + return new JaxRsClientJUnitMethodBodyBuilder(stubContent) + } return new JaxRsClientSpockMethodBodyBuilder(stubContent) } return new MockMvcSpockMethodBodyBuilder(stubContent) 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 fc8d4bfded..7edaf642d6 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 @@ -30,6 +30,7 @@ class AccurestGradlePlugin implements Plugin { deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.5-beta") project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:jsonassert:${extension.getJsonAssertVersion()}") + project.dependencies.add("testCompile", "org.assertj:assertj-core:3.3.0") project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy index 789d897199..9784abcb05 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -3,19 +3,47 @@ package io.codearte.accurest.plugin import nebula.test.IntegrationSpec import spock.lang.Stepwise +import java.nio.file.Files +import java.nio.file.Path + +import static java.nio.charset.StandardCharsets.UTF_8 +import static java.nio.charset.StandardCharsets.UTF_8 + @Stepwise class SampleJerseyProjectSpec extends IntegrationSpec { + public static final String SPOCK = "targetFramework = 'Spock'" + public static final String JUNIT = "targetFramework = 'JUnit'" + public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" + public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + void setup() { copyResources("functionalTest/sampleJerseyProject", "") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } - def "should pass basic flow"() { + def "should pass basic flow for Spock"() { given: assert fileExists('build.gradle') expect: runTasksSuccessfully('check') } + def "should pass basic flow for JUnit"() { + given: + switchToJunitTestFramework() + assert fileExists('build.gradle') + expect: + runTasksSuccessfully('check') + } + + + private void switchToJunitTestFramework() { + Path path = buildFile.toPath() + String content = new StringBuilder(new String(Files.readAllBytes(path), UTF_8)).replaceAll(SPOCK, JUNIT) + .replaceAll(MVC_SPEC, MVC_TEST) + Files.write(path, content.getBytes(UTF_8)) + } + + } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index e32b8810f4..4ff481157f 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -2,20 +2,48 @@ package io.codearte.accurest.plugin import nebula.test.IntegrationSpec import spock.lang.Stepwise +import spock.lang.Unroll + +import java.nio.file.Files +import java.nio.file.Path + +import static java.nio.charset.StandardCharsets.UTF_8 +import static java.nio.charset.StandardCharsets.UTF_8 @Stepwise class SampleProjectSpec extends IntegrationSpec { + public static final String SPOCK = "targetFramework = 'Spock'" + public static final String JUNIT = "targetFramework = 'JUnit'" + public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" + public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + void setup() { copyResources("functionalTest/sampleProject", "") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } - def "should pass basic flow"() { + def "should pass basic flow for Spock"() { given: assert fileExists('build.gradle') expect: runTasksSuccessfully('check') } + def "should pass basic flow for JUnit"() { + given: + switchToJunitTestFramework() + assert fileExists('build.gradle') + expect: + runTasksSuccessfully('check') + } + + + private void switchToJunitTestFramework() { + Path path = buildFile.toPath() + String content = new StringBuilder(new String(Files.readAllBytes(path), UTF_8)).replaceAll(SPOCK, JUNIT) + .replaceAll(MVC_SPEC, MVC_TEST) + Files.write(path, content.getBytes(UTF_8)) + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java new file mode 100644 index 0000000000..d13134ecc8 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java @@ -0,0 +1,70 @@ +package com.blogspot.toomuchcoding; +import com.blogspot.toomuchcoding.frauddetection.Application; +import com.blogspot.toomuchcoding.frauddetection.FraudRestApplication; +import org.eclipse.jetty.server.Server; +import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.jetty.JettyHttpContainerFactory; +import org.glassfish.jersey.server.ResourceConfig; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.UriBuilder; + +import java.net.URI; + +import static org.springframework.util.SocketUtils.findAvailableTcpPort; + +public abstract class MvcTest { + + public static WebTarget webTarget; + + private static Server server; + + private static Client client; + + @BeforeClass + public static void setupTest() { + + URI baseUri = UriBuilder.fromUri("http://localhost").port(findAvailableTcpPort(8000)).build(); + + + ResourceConfig resourceConfig = ResourceConfig.forApplication(new FraudRestApplication()); + resourceConfig.property("contextConfig", new AnnotationConfigApplicationContext(Application.class)); + server = JettyHttpContainerFactory.createServer(baseUri, resourceConfig, true); + + ClientConfig clientConfig = new ClientConfig(); + clientConfig.connectorProvider(new ApacheConnectorProvider()); + client = ClientBuilder.newClient(clientConfig); + + webTarget = client.target(baseUri); + + try { + server.start(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @AfterClass + public static void cleanupTest() { + if(client != null) { + client.close(); + } + if (server != null) { + try { + server.stop(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public void assertThatRejectionReasonIsNull(Object rejectionReason) { + assert rejectionReason == null; + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java new file mode 100644 index 0000000000..e9d083bde4 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java @@ -0,0 +1,18 @@ +package com.blogspot.toomuchcoding; + +import com.blogspot.toomuchcoding.frauddetection.FraudDetectionController; +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; +import spock.lang.Specification; +import org.junit.Before; + +public class MvcTest { + + @Before + public void setup() { + RestAssuredMockMvc.standaloneSetup(new com.blogspot.toomuchcoding.frauddetection.FraudDetectionController()); + } + + public void assertThatRejectionReasonIsNull(Object rejectionReason) { + assert rejectionReason== null; + } +} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 16011ddca1..1895c32f22 100644 --- a/build.gradle +++ b/build.gradle @@ -73,6 +73,7 @@ project(':accurest-core') { compile 'asm:asm:3.3.1' compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile "com.blogspot.toomuchcoding:jsonassert:$jsonassertVersion" + compile 'org.assertj:assertj-core:[3.3.0,)' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') From fcbcd9e50f360ea2c29513bb31a49bf227e5ae76 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 14:52:40 +0100 Subject: [PATCH 299/719] Fixed test to take into account Java escape characters. --- .../codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index 2b712db6b6..980fb5fcef 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -483,7 +483,7 @@ class JsonToJsonPathsConverterSpec extends Specification { JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) then: pathAndValues.find { - it.method()== """.field("property2").matches("\\d+")""" && + it.method()== """.field("property2").matches("\\\\d+")""" && it.jsonPath() == """\$[?(@.property2 =~ /\\d+/)]""" } and: From 7e6cb3b9b348a1400e63bd0e9e5f2e2a11ed6a91 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 15:14:08 +0100 Subject: [PATCH 300/719] Fixed missing space. --- .../src/test/java/com/blogspot/toomuchcoding/MvcTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java index e9d083bde4..f8d460e160 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java @@ -13,6 +13,6 @@ public class MvcTest { } public void assertThatRejectionReasonIsNull(Object rejectionReason) { - assert rejectionReason== null; + assert rejectionReason == null; } } \ No newline at end of file From 44c78710a0b514aa2b90e8f40dcd1bf22d0f2d47 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 15:15:21 +0100 Subject: [PATCH 301/719] Fixed wrong line spacing. --- .../groovy/io/codearte/accurest/SingleTestGenerator.groovy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 6175152361..51210d3f49 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -15,8 +15,7 @@ import static io.codearte.accurest.util.NamesUtil.capitalize @Slf4j class SingleTestGenerator { - private static - final String JSON_ASSERT_STATIC_IMPORT = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson' + private static final String JSON_ASSERT_STATIC_IMPORT = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson' private static final String JSON_ASSERT_CLASS = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion' private final AccurestConfigProperties configProperties From 190cd5bc155f928057d27d542f1713b159885637 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 15:18:15 +0100 Subject: [PATCH 302/719] Switched to lineSuffix use. --- .../codearte/accurest/builder/JUnitMethodBodyBuilder.groovy | 4 +++- .../builder/JaxRsClientJUnitMethodBodyBuilder.groovy | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index 51cabcbade..bcec159597 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.builder import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked +import io.codearte.accurest.config.TestFramework import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Header @@ -10,6 +11,7 @@ import io.codearte.accurest.dsl.internal.NamedProperty import io.codearte.accurest.dsl.internal.Request import static groovy.json.StringEscapeUtils.escapeJava +import static io.codearte.accurest.config.TestFramework.JUNIT import static io.codearte.accurest.util.ContentUtils.getJavaMultipartFileParameterContent /** @@ -36,7 +38,7 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { @Override protected BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) { - blockBuilder.addAtTheEnd(';') + blockBuilder.addAtTheEnd(JUNIT.lineSuffix) return blockBuilder } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy index 79180caf54..67827a70b9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy @@ -1,10 +1,13 @@ package io.codearte.accurest.builder +import io.codearte.accurest.config.TestFramework import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.QueryParameter import io.codearte.accurest.dsl.internal.QueryParameters +import static io.codearte.accurest.config.TestFramework.JUNIT + /** * @author Olga Maciaszek-Sharma @since 21.02.16 @@ -31,7 +34,7 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { appendRequestWithRequiredResponseContentType(bb) appendHeaders(bb) appendMethodAndBody(bb) - bb.addAtTheEnd(';') + bb.addAtTheEnd(JUNIT.lineSuffix) bb.unindent() From 8279dceb6531465e820593b16b1e903324e816c5 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 20:49:39 +0100 Subject: [PATCH 303/719] Added improvement after code review: stripFirstChar(). Removed unused imports. Removed unnecessary TODO item. --- .../accurest/builder/JUnitMethodBodyBuilder.groovy | 1 - .../builder/JaxRsClientJUnitMethodBodyBuilder.groovy | 1 - .../codearte/accurest/builder/MethodBodyBuilder.groovy | 9 ++++++--- .../codearte/accurest/dsl/internal/QueryParameter.groovy | 8 ++++---- .../io/codearte/accurest/dsl/internal/UrlPath.groovy | 4 ++-- .../io/codearte/accurest/file/ContractFileScanner.groovy | 1 - .../accurest/builder/MockMvcMethodBodyBuilderSpec.groovy | 2 -- .../accurest/file/ContractFileScannerSpec.groovy | 1 - .../accurest/plugin/SampleJerseyProjectSpec.groovy | 4 ++-- .../io/codearte/accurest/plugin/SampleProjectSpec.groovy | 2 -- .../toomuchcoding/frauddetection/Application.java | 1 - .../test/java/com/blogspot/toomuchcoding/MvcTest.java | 2 +- .../test/java/com/blogspot/toomuchcoding/MvcTest.java | 2 -- 13 files changed, 15 insertions(+), 23 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index bcec159597..bd84b6ab41 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -3,7 +3,6 @@ package io.codearte.accurest.builder import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked -import io.codearte.accurest.config.TestFramework import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Header diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy index 67827a70b9..27c5d0f51a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy @@ -1,6 +1,5 @@ package io.codearte.accurest.builder -import io.codearte.accurest.config.TestFramework import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.QueryParameter diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index e8b9efb6e0..a78488d441 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -20,7 +20,6 @@ import io.codearte.accurest.util.JsonToJsonPathsConverter import io.codearte.accurest.util.MapConverter import static io.codearte.accurest.util.ContentUtils.extractValue -import static io.codearte.accurest.util.ContentUtils.getGroovyMultipartFileParameterContent import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader @@ -187,7 +186,7 @@ abstract class MethodBodyBuilder { protected void processText(BlockBuilder blockBuilder, String property, String value) { if (value.startsWith('$')) { - value = value.substring(1).replaceAll('\\$value', "responseBody$property") + value = stripFirstChar(value).replaceAll('\\$value', "responseBody$property") blockBuilder.addLine(value) addColonIfRequired(blockBuilder) } else { @@ -195,6 +194,10 @@ abstract class MethodBodyBuilder { } } + private String stripFirstChar(String s) { + return s.substring(1); + } + protected void processBodyElement(BlockBuilder blockBuilder, String property, Object value) { } @@ -210,7 +213,7 @@ abstract class MethodBodyBuilder { } protected String trimRepeatedQuotes(String toTrim) { - return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim // TODO: implement for JUnit + return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim } protected Object extractServerValueFromBody(bodyValue) { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy index 153fa6f297..c0ca01c97b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy @@ -1,10 +1,10 @@ -package io.codearte.accurest.dsl.internal; +package io.codearte.accurest.dsl.internal -import groovy.transform.CompileStatic; -import groovy.transform.EqualsAndHashCode; +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -import static io.codearte.accurest.util.ValidateUtils.validateServerValueIsAvailable; +import static io.codearte.accurest.util.ValidateUtils.validateServerValueIsAvailable @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy index 68d9bc0f7d..4b77520cc3 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy @@ -1,8 +1,8 @@ package io.codearte.accurest.dsl.internal -import groovy.transform.CompileStatic; +import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString; +import groovy.transform.ToString @ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy index 1e1e27c310..8c0ea132ec 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy @@ -2,7 +2,6 @@ package io.codearte.accurest.file import com.google.common.collect.ArrayListMultimap import com.google.common.collect.ListMultimap -import com.google.common.collect.Multimap import org.apache.commons.io.FilenameUtils import java.nio.file.FileSystem diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index d2390e5cca..ab3a0ae4c3 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1,9 +1,7 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.dsl.WireMockStubStrategy import io.codearte.accurest.dsl.WireMockStubVerifier -import io.codearte.accurest.file.Contract import spock.lang.Issue import spock.lang.Shared import spock.lang.Specification diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy index e02e06cc56..30a5def61c 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy @@ -1,7 +1,6 @@ package io.codearte.accurest.file import com.google.common.collect.ListMultimap -import com.google.common.collect.Multimap import spock.lang.Specification import java.nio.file.Path diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy index 9784abcb05..4c8c4026a1 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -6,7 +6,6 @@ import spock.lang.Stepwise import java.nio.file.Files import java.nio.file.Path -import static java.nio.charset.StandardCharsets.UTF_8 import static java.nio.charset.StandardCharsets.UTF_8 @Stepwise @@ -19,7 +18,8 @@ class SampleJerseyProjectSpec extends IntegrationSpec { void setup() { copyResources("functionalTest/sampleJerseyProject", "") - runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it + runTasksSuccessfully('clean') + //delete accidental output when previously importing SimpleBoot into Idea to tweak it } def "should pass basic flow for Spock"() { diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index 4ff481157f..9bb3c390f9 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -2,12 +2,10 @@ package io.codearte.accurest.plugin import nebula.test.IntegrationSpec import spock.lang.Stepwise -import spock.lang.Unroll import java.nio.file.Files import java.nio.file.Path -import static java.nio.charset.StandardCharsets.UTF_8 import static java.nio.charset.StandardCharsets.UTF_8 @Stepwise diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java index 2089bda142..99a72fbf26 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -1,6 +1,5 @@ package com.blogspot.toomuchcoding.frauddetection; -import org.glassfish.jersey.client.HttpUrlConnectorProvider; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java index d13134ecc8..d36d31e510 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java @@ -1,4 +1,5 @@ package com.blogspot.toomuchcoding; + import com.blogspot.toomuchcoding.frauddetection.Application; import com.blogspot.toomuchcoding.frauddetection.FraudRestApplication; import org.eclipse.jetty.server.Server; @@ -14,7 +15,6 @@ import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.UriBuilder; - import java.net.URI; import static org.springframework.util.SocketUtils.findAvailableTcpPort; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java index f8d460e160..084a65ebf5 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java @@ -1,8 +1,6 @@ package com.blogspot.toomuchcoding; -import com.blogspot.toomuchcoding.frauddetection.FraudDetectionController; import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; -import spock.lang.Specification; import org.junit.Before; public class MvcTest { From 8f61701d7d05ee128477a25dba3579a55fc030d6 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 20:56:10 +0100 Subject: [PATCH 304/719] Added AccurestIntegrationSpec. --- .../plugin/AccurestIntegrationSpec.groovy | 29 +++++++++++++++++++ .../plugin/SampleJerseyProjectSpec.groovy | 22 +------------- .../accurest/plugin/SampleProjectSpec.groovy | 21 +------------- 3 files changed, 31 insertions(+), 41 deletions(-) create mode 100644 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy new file mode 100644 index 0000000000..8454662519 --- /dev/null +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy @@ -0,0 +1,29 @@ +package io.codearte.accurest.plugin + +import nebula.test.IntegrationSpec + +import java.nio.file.Files +import java.nio.file.Path + +import static java.nio.charset.StandardCharsets.UTF_8 +import static java.nio.charset.StandardCharsets.UTF_8 + +/** + * @author Olga Maciaszek-Sharma + @since 23.02.16 + */ +class AccurestIntegrationSpec extends IntegrationSpec{ + + public static final String SPOCK = "targetFramework = 'Spock'" + public static final String JUNIT = "targetFramework = 'JUnit'" + public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" + public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + + protected void switchToJunitTestFramework() { + Path path = buildFile.toPath() + String content = new StringBuilder(new String(Files.readAllBytes(path), UTF_8)).replaceAll(SPOCK, JUNIT) + .replaceAll(MVC_SPEC, MVC_TEST) + Files.write(path, content.getBytes(UTF_8)) + } + +} diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy index 4c8c4026a1..d314e6c526 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -1,20 +1,9 @@ package io.codearte.accurest.plugin -import nebula.test.IntegrationSpec import spock.lang.Stepwise -import java.nio.file.Files -import java.nio.file.Path - -import static java.nio.charset.StandardCharsets.UTF_8 - @Stepwise -class SampleJerseyProjectSpec extends IntegrationSpec { - - public static final String SPOCK = "targetFramework = 'Spock'" - public static final String JUNIT = "targetFramework = 'JUnit'" - public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" - public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" +class SampleJerseyProjectSpec extends AccurestIntegrationSpec { void setup() { copyResources("functionalTest/sampleJerseyProject", "") @@ -37,13 +26,4 @@ class SampleJerseyProjectSpec extends IntegrationSpec { runTasksSuccessfully('check') } - - private void switchToJunitTestFramework() { - Path path = buildFile.toPath() - String content = new StringBuilder(new String(Files.readAllBytes(path), UTF_8)).replaceAll(SPOCK, JUNIT) - .replaceAll(MVC_SPEC, MVC_TEST) - Files.write(path, content.getBytes(UTF_8)) - } - - } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index 9bb3c390f9..fefe2d9869 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -1,20 +1,9 @@ package io.codearte.accurest.plugin -import nebula.test.IntegrationSpec import spock.lang.Stepwise -import java.nio.file.Files -import java.nio.file.Path - -import static java.nio.charset.StandardCharsets.UTF_8 - @Stepwise -class SampleProjectSpec extends IntegrationSpec { - - public static final String SPOCK = "targetFramework = 'Spock'" - public static final String JUNIT = "targetFramework = 'JUnit'" - public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" - public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" +class SampleProjectSpec extends AccurestIntegrationSpec { void setup() { copyResources("functionalTest/sampleProject", "") @@ -36,12 +25,4 @@ class SampleProjectSpec extends IntegrationSpec { runTasksSuccessfully('check') } - - private void switchToJunitTestFramework() { - Path path = buildFile.toPath() - String content = new StringBuilder(new String(Files.readAllBytes(path), UTF_8)).replaceAll(SPOCK, JUNIT) - .replaceAll(MVC_SPEC, MVC_TEST) - Files.write(path, content.getBytes(UTF_8)) - } - } From 9fa51611a12909ea14f6e89e5bacbd147bf4315c Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 21:40:19 +0100 Subject: [PATCH 305/719] Added more checks in tests. --- .../accurest/SingleTestGeneratorSpec.groovy | 3 ++- .../accurest/plugin/ScenarioProjectSpec.groovy | 12 ++++++++++-- .../java/com/blogspot/toomuchcoding/MvcTest.java | 16 ++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy index 7496f83446..d3f37399c2 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -20,7 +20,8 @@ class SingleTestGeneratorSpec extends Specification { static List jUnitClassStrings = ['package test;', 'import com.jayway.jsonpath.DocumentContext;', 'import com.jayway.jsonpath.JsonPath;', 'import org.junit.FixMethodOrder;', 'import org.junit.Ignore;', 'import org.junit.Test;', 'import org.junit.runners.MethodSorters;', 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson;', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*;', - '@FixMethodOrder(MethodSorters.NAME_ASCENDING)', '@Test', '@Ignore'] + '@FixMethodOrder(MethodSorters.NAME_ASCENDING)', '@Test', '@Ignore', 'mport com.jayway.restassured.module.mockmvc.specification.MockMvcRequestSpecification;', + 'import com.jayway.restassured.response.ResponseOptions;', 'import static org.assertj.core.api.Assertions.assertThat;'] static List spockClassStrings = ['package test', 'import com.jayway.jsonpath.DocumentContext', 'import com.jayway.jsonpath.JsonPath', 'import spock.lang.Ignore', 'import spock.lang.Specification', 'import spock.lang.Stepwise', diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy index ea7d0e27e3..9fafcc39e7 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy @@ -4,18 +4,26 @@ import nebula.test.IntegrationSpec import spock.lang.Stepwise @Stepwise -class ScenarioProjectSpec extends IntegrationSpec { +class ScenarioProjectSpec extends AccurestIntegrationSpec { void setup() { copyResources("functionalTest/scenarioProject", "") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } - def "should pass basic flow"() { + def "should pass basic flow for Spock"() { given: assert fileExists('build.gradle') expect: runTasksSuccessfully('check') } + def "should pass basic flow for JUnit"() { + given: + assert fileExists('build.gradle') + expect: + switchToJunitTestFramework() + runTasksSuccessfully('check') + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java new file mode 100644 index 0000000000..084a65ebf5 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java @@ -0,0 +1,16 @@ +package com.blogspot.toomuchcoding; + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; +import org.junit.Before; + +public class MvcTest { + + @Before + public void setup() { + RestAssuredMockMvc.standaloneSetup(new com.blogspot.toomuchcoding.frauddetection.FraudDetectionController()); + } + + public void assertThatRejectionReasonIsNull(Object rejectionReason) { + assert rejectionReason == null; + } +} \ No newline at end of file From c283a33dae99a945708da47b92b5e06d0e139b9e Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 21:51:34 +0100 Subject: [PATCH 306/719] Debug: verifying if lower assertj version will not cause Travis fail. --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 7edaf642d6..2c2ffa196b 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 @@ -30,7 +30,7 @@ class AccurestGradlePlugin implements Plugin { deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.5-beta") project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:jsonassert:${extension.getJsonAssertVersion()}") - project.dependencies.add("testCompile", "org.assertj:assertj-core:3.3.0") + project.dependencies.add("testCompile", "org.assertj:assertj-core:2.3.0") project.afterEvaluate { def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) diff --git a/build.gradle b/build.gradle index 1895c32f22..37a0cc8f9b 100644 --- a/build.gradle +++ b/build.gradle @@ -73,7 +73,7 @@ project(':accurest-core') { compile 'asm:asm:3.3.1' compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile "com.blogspot.toomuchcoding:jsonassert:$jsonassertVersion" - compile 'org.assertj:assertj-core:[3.3.0,)' + compile 'org.assertj:assertj-core:2.3.0' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') From ca393382a3750623b58f5514b2fde52355427f3f Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 23 Feb 2016 22:39:14 +0100 Subject: [PATCH 307/719] Switched from Java 8 forEach() to Groovy each{}. --- .../io/codearte/accurest/SingleTestGeneratorSpec.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy index d3f37399c2..5b026ce8dd 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -57,7 +57,7 @@ class SingleTestGeneratorSpec extends Specification { String clazz = testGenerator.buildClass([contract], "test", "test") then: - classStrings.forEach({ clazz.contains(it) }) + classStrings.each { clazz.contains(it) } where: testFramework | classStrings @@ -80,7 +80,7 @@ class SingleTestGeneratorSpec extends Specification { String clazz = testGenerator.buildClass([contract], "test", "test") then: - classStrings.forEach({ clazz.contains(it) }) + classStrings.each { clazz.contains(it) } where: testFramework | classStrings From 5f3fd885fd248d8342ec7877b31df8f7568f92da Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Wed, 24 Feb 2016 00:09:07 +0100 Subject: [PATCH 308/719] Release version: 1.0.0-RC2 [ci skip] From 507552003a9e2259c2bee39dc14e5a7aa8daf22a Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 29 Feb 2016 19:36:48 +0100 Subject: [PATCH 309/719] Release version: 1.0.0 [ci skip] From 3d898c3c2992399d6399d054e2474171c5f8f384 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 29 Feb 2016 19:36:48 +0100 Subject: [PATCH 310/719] Release version: 1.0.0 [ci skip] From f385df89361dff230dd6f5212565dfdbb9a30a38 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 29 Feb 2016 19:36:48 +0100 Subject: [PATCH 311/719] Release version: 1.0.0 [ci skip] From 10ccf4f28485a42b8d6fa9a3aa483212ed3719ba Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 11 Mar 2016 21:52:03 +0100 Subject: [PATCH 312/719] Bumped JSON Assert to 0.2.1 - changed groupid - changed code packages - found a bug in jsonassert that was fixed in 0.2.1 - updated JSONPath to 2.2.0 fixes #200 --- .../groovy/io/codearte/accurest/SingleTestGenerator.groovy | 4 ++-- .../codearte/accurest/config/AccurestConfigProperties.groovy | 2 +- .../codearte/accurest/dsl/WireMockRequestStubStrategy.groovy | 2 +- .../io/codearte/accurest/util/DelegatingJsonVerifiable.java | 2 +- .../accurest/util/FinishedDelegatingJsonVerifiable.java | 2 +- .../io/codearte/accurest/util/JsonToJsonPathsConverter.groovy | 2 +- .../codearte/accurest/util/MethodBufferingJsonVerifiable.java | 2 +- .../io/codearte/accurest/SingleTestGeneratorSpec.groovy | 4 ++-- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 2 +- .../src/test/resources/functionalTest/bootSimple/build.gradle | 2 +- build.gradle | 2 +- gradle.properties | 2 +- 12 files changed, 14 insertions(+), 14 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 51210d3f49..58faa81302 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -15,8 +15,8 @@ import static io.codearte.accurest.util.NamesUtil.capitalize @Slf4j class SingleTestGenerator { - private static final String JSON_ASSERT_STATIC_IMPORT = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson' - private static final String JSON_ASSERT_CLASS = 'com.blogspot.toomuchcoding.jsonassert.JsonAssertion' + private static final String JSON_ASSERT_STATIC_IMPORT = 'com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson' + private static final String JSON_ASSERT_CLASS = 'com.toomuchcoding.jsonassert.JsonAssertion' private final AccurestConfigProperties configProperties diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy index 88c6574471..9e89c8909e 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy @@ -35,7 +35,7 @@ class AccurestConfigProperties { String ruleClassForTests /** - * Which version of JSON Assert (com.blogspot.toomuchcoding:jsonassert) to use + * Which version of JSON Assert (com.toomuchcoding.jsonassert:jsonassert) to use */ String jsonAssertVersion = "+" diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index f1c618cbd0..194a405237 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -68,7 +68,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT, equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ] } else { - requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath()) } ?: null + requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath().replace("\\\\", "\\")) } ?: null } } else if (contentType == ContentType.XML) { requestPattern.bodyPatterns = [new ValuePattern(equalToXml: getMatchingStrategy(request.body.clientValue).clientValue.toString())] diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index 410375b385..bafc287877 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -1,6 +1,6 @@ package io.codearte.accurest.util; -import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; +import com.toomuchcoding.jsonassert.JsonVerifiable; import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java index 7167ac6a97..eb65cd73f4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java @@ -1,6 +1,6 @@ package io.codearte.accurest.util; -import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; +import com.toomuchcoding.jsonassert.JsonVerifiable; /** * @author Marcin Grzejszczak diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 9a66bf0561..8ab311fdb6 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -1,6 +1,6 @@ package io.codearte.accurest.util -import com.blogspot.toomuchcoding.jsonassert.JsonAssertion +import com.toomuchcoding.jsonassert.JsonAssertion import groovy.json.JsonOutput import groovy.json.JsonSlurper import io.codearte.accurest.dsl.internal.ExecutionProperty diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java index c46e0f61b7..49e0234cb0 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java @@ -1,6 +1,6 @@ package io.codearte.accurest.util; -import com.blogspot.toomuchcoding.jsonassert.JsonVerifiable; +import com.toomuchcoding.jsonassert.JsonVerifiable; /** * @author Marcin Grzejszczak diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy index 5b026ce8dd..222ab44ba4 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -19,13 +19,13 @@ class SingleTestGeneratorSpec extends Specification { static List jUnitClassStrings = ['package test;', 'import com.jayway.jsonpath.DocumentContext;', 'import com.jayway.jsonpath.JsonPath;', 'import org.junit.FixMethodOrder;', 'import org.junit.Ignore;', 'import org.junit.Test;', 'import org.junit.runners.MethodSorters;', - 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson;', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*;', + 'import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson;', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*;', '@FixMethodOrder(MethodSorters.NAME_ASCENDING)', '@Test', '@Ignore', 'mport com.jayway.restassured.module.mockmvc.specification.MockMvcRequestSpecification;', 'import com.jayway.restassured.response.ResponseOptions;', 'import static org.assertj.core.api.Assertions.assertThat;'] static List spockClassStrings = ['package test', 'import com.jayway.jsonpath.DocumentContext', 'import com.jayway.jsonpath.JsonPath', 'import spock.lang.Ignore', 'import spock.lang.Specification', 'import spock.lang.Stepwise', - 'import static com.blogspot.toomuchcoding.jsonassert.JsonAssertion.assertThatJson', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*', + 'import static com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson', 'import static com.jayway.restassured.module.mockmvc.RestAssuredMockMvc.*', '@Stepwise', '@Ignore'] def setup() { 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 2c2ffa196b..cd38e879bc 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 @@ -29,7 +29,7 @@ class AccurestGradlePlugin implements Plugin { createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.5-beta") - project.dependencies.add("testCompile", "com.blogspot.toomuchcoding:jsonassert:${extension.getJsonAssertVersion()}") + project.dependencies.add("testCompile", "com.toomuchcoding.jsonassert:jsonassert:${extension.getJsonAssertVersion()}") project.dependencies.add("testCompile", "org.assertj:assertj-core:2.3.0") project.afterEvaluate { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 6329484d1f..4c0f8a029f 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -37,7 +37,7 @@ dependencies { compile "org.springframework:spring-context-support:$springVersion" compile "org.codehaus.groovy:groovy-all:2.4.5" compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' - compile 'com.jayway.jsonpath:json-path-assert:2.0.0' + compile 'com.jayway.jsonpath:json-path-assert:2.2.0' testCompile "com.github.tomakehurst:wiremock:2.0.5-beta" testCompile "org.spockframework:spock-spring:1.0-groovy-2.4" diff --git a/build.gradle b/build.gradle index 37a0cc8f9b..313e58fb19 100644 --- a/build.gradle +++ b/build.gradle @@ -72,7 +72,7 @@ project(':accurest-core') { compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' compile 'asm:asm:3.3.1' compile "com.github.tomakehurst:wiremock:$wiremockVersion" - compile "com.blogspot.toomuchcoding:jsonassert:$jsonassertVersion" + compile "com.toomuchcoding.jsonassert:jsonassert:$jsonassertVersion" compile 'org.assertj:assertj-core:2.3.0' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' diff --git a/gradle.properties b/gradle.properties index fa9182de93..a6c2e2d210 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,4 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.5-beta -jsonassertVersion = 0.1.2 +jsonassertVersion = 0.2.1 From f3221f51b3838f3aa614c22ba4cd53b4adb033a3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 12 Mar 2016 23:55:56 +0100 Subject: [PATCH 313/719] Removed unnecessary closure from test --- .../io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 43324a794c..6288301bdb 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 @@ -22,7 +22,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie body( id: value( client('123'), - server({ regex('[0-9]+') }) + server(regex('[0-9]+')) ), surname: $( client('Kowalsky'), From fcb2bd1541f2570920bf8c22b012f4e9ba5fb309 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 20 Mar 2016 10:32:40 +0100 Subject: [PATCH 314/719] Bumped up jsonassert to 0.2.2 --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index a6c2e2d210..dfc935df68 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,4 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.5-beta -jsonassertVersion = 0.2.1 +jsonassertVersion = 0.2.2 \ No newline at end of file From ab8a5b03fcf3cf999530e75b36e7c36394a283bb Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 22 Mar 2016 08:46:49 +0100 Subject: [PATCH 315/719] Release version: 1.0.1 [ci skip] From 4d2d3c6f9723bc0dba92afa9e1a9870cfb898e76 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 22 Mar 2016 08:46:49 +0100 Subject: [PATCH 316/719] Release version: 1.0.1 [ci skip] From c36f7b0cf25efdb2bb6b19475612f51a6e8bb449 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 22 Mar 2016 08:46:49 +0100 Subject: [PATCH 317/719] Release version: 1.0.1 [ci skip] From bee524efbc41fc7e3ecec3a3ea3e53838868a4c3 Mon Sep 17 00:00:00 2001 From: Marcin Pilaczynski Date: Tue, 22 Mar 2016 20:16:24 +0100 Subject: [PATCH 318/719] #206 Fix file pattern matchers under Windows --- .../io/codearte/accurest/file/ContractFileScanner.groovy | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) mode change 100644 => 100755 accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy old mode 100644 new mode 100755 index 8c0ea132ec..0e898ba30e --- a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.file import com.google.common.collect.ArrayListMultimap import com.google.common.collect.ListMultimap import org.apache.commons.io.FilenameUtils +import org.apache.commons.lang3.SystemUtils import java.nio.file.FileSystem import java.nio.file.FileSystems @@ -30,7 +31,11 @@ class ContractFileScanner { private Set processPatterns(Set patterns, baseDir) { FileSystem fileSystem = FileSystems.getDefault() return patterns.collect({ - fileSystem.getPathMatcher(MATCH_PREFIX + baseDir.toString() + File.separator + it) + String syntaxAndPattern = MATCH_PREFIX + baseDir.toString() + File.separator + it + if (SystemUtils.IS_OS_WINDOWS) { + syntaxAndPattern = syntaxAndPattern.replace("\\", "\\\\") + } + fileSystem.getPathMatcher(syntaxAndPattern) }) as Set } From edb8a60a0f2c4fbe3cf22679b233518a962e08d6 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 25 Mar 2016 21:23:08 +0100 Subject: [PATCH 319/719] initial commit --- .gitignore | 3 + .mvn/wrapper/maven-wrapper.jar | Bin 0 -> 49519 bytes .mvn/wrapper/maven-wrapper.properties | 1 + mvnw | 234 ++++++++++++++++++++++++++ mvnw.cmd | 145 ++++++++++++++++ pom.xml | 12 ++ 6 files changed, 395 insertions(+) create mode 100644 .gitignore create mode 100644 .mvn/wrapper/maven-wrapper.jar create mode 100644 .mvn/wrapper/maven-wrapper.properties create mode 100755 mvnw create mode 100644 mvnw.cmd create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..d21bed913b --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.idea/ +*.iml +target diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..c6feb8bb6f76f2553e266ff8bf8867105154237e GIT binary patch literal 49519 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%0A$pwhjXzyA0ZzErH{1@M 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 literal 0 HcmV?d00001 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties new file mode 100644 index 0000000000..6637cedb28 --- /dev/null +++ b/.mvn/wrapper/maven-wrapper.properties @@ -0,0 +1 @@ +distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip \ No newline at end of file diff --git a/mvnw b/mvnw new file mode 100755 index 0000000000..fc7efd17d0 --- /dev/null +++ b/mvnw @@ -0,0 +1,234 @@ +#!/bin/sh +# ---------------------------------------------------------------------------- +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Maven2 Start Up Batch script +# +# Required ENV vars: +# ------------------ +# JAVA_HOME - location of a JDK home dir +# +# Optional ENV vars +# ----------------- +# M2_HOME - location of maven2's installed home dir +# MAVEN_OPTS - parameters passed to the Java VM when running Maven +# e.g. to debug Maven itself, use +# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +# MAVEN_SKIP_RC - flag to disable loading of mavenrc files +# ---------------------------------------------------------------------------- + +if [ -z "$MAVEN_SKIP_RC" ] ; then + + if [ -f /etc/mavenrc ] ; then + . /etc/mavenrc + fi + + if [ -f "$HOME/.mavenrc" ] ; then + . "$HOME/.mavenrc" + fi + +fi + +# OS specific support. $var _must_ be set to either true or false. +cygwin=false; +darwin=false; +mingw=false +case "`uname`" in + CYGWIN*) cygwin=true ;; + MINGW*) mingw=true;; + Darwin*) darwin=true + # + # Look for the Apple JDKs first to preserve the existing behaviour, and then look + # for the new JDKs provided by Oracle. + # + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then + # + # Apple JDKs + # + export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then + # + # Oracle JDKs + # + export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home + fi + + if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then + # + # Apple JDKs + # + export JAVA_HOME=`/usr/libexec/java_home` + fi + ;; +esac + +if [ -z "$JAVA_HOME" ] ; then + if [ -r /etc/gentoo-release ] ; then + JAVA_HOME=`java-config --jre-home` + fi +fi + +if [ -z "$M2_HOME" ] ; then + ## resolve links - $0 may be a link to maven's home + 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 + + saveddir=`pwd` + + M2_HOME=`dirname "$PRG"`/.. + + # make it fully qualified + M2_HOME=`cd "$M2_HOME" && pwd` + + cd "$saveddir" + # echo Using m2 at $M2_HOME +fi + +# For Cygwin, ensure paths are in UNIX format before anything is touched +if $cygwin ; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --unix "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --unix "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --unix "$CLASSPATH"` +fi + +# For Migwn, ensure paths are in UNIX format before anything is touched +if $mingw ; then + [ -n "$M2_HOME" ] && + M2_HOME="`(cd "$M2_HOME"; pwd)`" + [ -n "$JAVA_HOME" ] && + JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" + # TODO classpath? +fi + +if [ -z "$JAVA_HOME" ]; then + javaExecutable="`which javac`" + if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then + # readlink(1) is not available as standard on Solaris 10. + readLink=`which readlink` + if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then + if $darwin ; then + javaHome="`dirname \"$javaExecutable\"`" + javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" + else + javaExecutable="`readlink -f \"$javaExecutable\"`" + fi + javaHome="`dirname \"$javaExecutable\"`" + javaHome=`expr "$javaHome" : '\(.*\)/bin'` + JAVA_HOME="$javaHome" + export JAVA_HOME + fi + fi +fi + +if [ -z "$JAVACMD" ] ; then + 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 + else + JAVACMD="`which java`" + fi +fi + +if [ ! -x "$JAVACMD" ] ; then + echo "Error: JAVA_HOME is not defined correctly." >&2 + echo " We cannot execute $JAVACMD" >&2 + exit 1 +fi + +if [ -z "$JAVA_HOME" ] ; then + echo "Warning: JAVA_HOME environment variable is not set." +fi + +CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher + +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` +fi + +# traverses directory structure from process work directory to filesystem root +# first directory with .mvn subdirectory is considered project base directory +find_maven_basedir() { + local basedir=$(pwd) + local wdir=$(pwd) + while [ "$wdir" != '/' ] ; do + if [ -d "$wdir"/.mvn ] ; then + basedir=$wdir + break + fi + wdir=$(cd "$wdir/.."; pwd) + done + echo "${basedir}" +} + +# concatenates all lines of a file +concat_lines() { + if [ -f "$1" ]; then + echo "$(tr -s '\n' ' ' < "$1")" + fi +} + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" + +# Provide a "standardized" way to retrieve the CLI args that will +# work with both Windows and non-Windows executions. +MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" +export MAVEN_CMD_LINE_ARGS + +WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +exec "$JAVACMD" \ + $MAVEN_OPTS \ + -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ + "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ + ${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS + diff --git a/mvnw.cmd b/mvnw.cmd new file mode 100644 index 0000000000..001048081d --- /dev/null +++ b/mvnw.cmd @@ -0,0 +1,145 @@ +@REM ---------------------------------------------------------------------------- +@REM Licensed to the Apache Software Foundation (ASF) under one +@REM or more contributor license agreements. See the NOTICE file +@REM distributed with this work for additional information +@REM regarding copyright ownership. The ASF licenses this file +@REM to you under the Apache License, Version 2.0 (the +@REM "License"); you may not use this file except in compliance +@REM with the License. You may obtain a copy of the License at +@REM +@REM http://www.apache.org/licenses/LICENSE-2.0 +@REM +@REM Unless required by applicable law or agreed to in writing, +@REM software distributed under the License is distributed on an +@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +@REM KIND, either express or implied. See the License for the +@REM specific language governing permissions and limitations +@REM under the License. +@REM ---------------------------------------------------------------------------- + +@REM ---------------------------------------------------------------------------- +@REM Maven2 Start Up Batch script +@REM +@REM Required ENV vars: +@REM JAVA_HOME - location of a JDK home dir +@REM +@REM Optional ENV vars +@REM M2_HOME - location of maven2's installed home dir +@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven +@REM e.g. to debug Maven itself, use +@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 +@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files +@REM ---------------------------------------------------------------------------- + +@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' +@echo off +@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% + +@REM set %HOME% to equivalent of $HOME +if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") + +@REM Execute a user defined script before this one +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre +@REM check for pre script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" +if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" +:skipRcPre + +@setlocal + +set ERROR_CODE=0 + +@REM To isolate internal variables from possible post scripts, we use another setlocal +@setlocal + +@REM ==== START VALIDATION ==== +if not "%JAVA_HOME%" == "" goto OkJHome + +echo. +echo Error: JAVA_HOME not found in your environment. >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +:OkJHome +if exist "%JAVA_HOME%\bin\java.exe" goto init + +echo. +echo Error: JAVA_HOME is set to an invalid directory. >&2 +echo JAVA_HOME = "%JAVA_HOME%" >&2 +echo Please set the JAVA_HOME variable in your environment to match the >&2 +echo location of your Java installation. >&2 +echo. +goto error + +@REM ==== END VALIDATION ==== + +:init + +set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* + +@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". +@REM Fallback to current working directory if not found. + +set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% +IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir + +set EXEC_DIR=%CD% +set WDIR=%EXEC_DIR% +:findBaseDir +IF EXIST "%WDIR%"\.mvn goto baseDirFound +cd .. +IF "%WDIR%"=="%CD%" goto baseDirNotFound +set WDIR=%CD% +goto findBaseDir + +:baseDirFound +set MAVEN_PROJECTBASEDIR=%WDIR% +cd "%EXEC_DIR%" +goto endDetectBaseDir + +:baseDirNotFound +set MAVEN_PROJECTBASEDIR=%EXEC_DIR% +cd "%EXEC_DIR%" + +:endDetectBaseDir + +IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig + +@setlocal EnableExtensions EnableDelayedExpansion +for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a +@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% + +:endReadAdditionalConfig + +SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" + +set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +if ERRORLEVEL 1 goto error +goto end + +:error +set ERROR_CODE=1 + +:end +@endlocal & set ERROR_CODE=%ERROR_CODE% + +if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost +@REM check for post script, once with legacy .bat ending and once with .cmd ending +if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" +if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" +:skipRcPost + +@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' +if "%MAVEN_BATCH_PAUSE%" == "on" pause + +if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% + +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000000..1ca7979efb --- /dev/null +++ b/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + + io.codearte.accurest + accurest-maven-plugin + 1.0-SNAPSHOT + + + \ No newline at end of file From 8f1a3ea17b61e4d59d996e3b059b2c766aa2fc24 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 26 Mar 2016 16:46:47 +0100 Subject: [PATCH 320/719] Added stub-runner, stub-runner-spring, stub-runner-junit --- .travis.yml | 8 +- README.md | 14 ++ settings.gradle | 5 + stub-runner/stub-runner-junit/README.md | 42 +++++ stub-runner/stub-runner-junit/build.gradle | 15 ++ .../stubrunner/junit/AccurestRule.java | 158 +++++++++++++++++ .../stubrunner/junit/AccurestRuleSpec.groovy | 27 +++ .../junit/AccurestRuleSysPropsSpec.groovy | 33 ++++ .../src/test/resources/logback.xml | 14 ++ ...udDetectionServer-stubs-0.0.1-SNAPSHOT.jar | Bin 0 -> 1733 bytes ...udDetectionServer-stubs-0.0.1-SNAPSHOT.pom | 8 + .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++ .../maven-metadata-local.xml | 11 ++ .../loanIssuance-stubs-0.0.1-SNAPSHOT.jar | Bin 0 -> 587 bytes .../loanIssuance-stubs-0.0.1-SNAPSHOT.pom | 8 + .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++ .../maven-metadata-local.xml | 11 ++ stub-runner/stub-runner-spring/README.md | 32 ++++ stub-runner/stub-runner-spring/build.gradle | 18 ++ .../spring/StubRunnerConfiguration.java | 57 ++++++ .../spring/StubRunnerConfigurationSpec.groovy | 37 ++++ .../src/test/resources/application.yml | 2 + .../src/test/resources/logback.xml | 14 ++ ...udDetectionServer-stubs-0.0.1-SNAPSHOT.jar | Bin 0 -> 1733 bytes ...udDetectionServer-stubs-0.0.1-SNAPSHOT.pom | 8 + .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++ .../maven-metadata-local.xml | 11 ++ .../loanIssuance-stubs-0.0.1-SNAPSHOT.jar | Bin 0 -> 587 bytes .../loanIssuance-stubs-0.0.1-SNAPSHOT.pom | 8 + .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++ .../maven-metadata-local.xml | 11 ++ stub-runner/stub-runner/README.md | 88 ++++++++++ stub-runner/stub-runner/build.gradle | 73 ++++++++ .../accurest/stubrunner/Arguments.groovy | 27 +++ .../stubrunner/AvailablePortScanner.groovy | 73 ++++++++ .../stubrunner/BatchStubRunner.groovy | 52 ++++++ .../stubrunner/BatchStubRunnerFactory.groovy | 27 +++ .../stubrunner/MappingDescriptor.groovy | 27 +++ .../accurest/stubrunner/RunningStubs.groovy | 25 +++ .../stubrunner/StubConfiguration.groovy | 61 +++++++ .../accurest/stubrunner/StubDownloader.groovy | 165 ++++++++++++++++++ .../accurest/stubrunner/StubFinder.groovy | 21 +++ .../accurest/stubrunner/StubRepository.groovy | 49 ++++++ .../accurest/stubrunner/StubRunner.groovy | 58 ++++++ .../stubrunner/StubRunnerExecutor.groovy | 61 +++++++ .../stubrunner/StubRunnerFactory.groovy | 55 ++++++ .../accurest/stubrunner/StubRunnerMain.groovy | 74 ++++++++ .../stubrunner/StubRunnerOptions.groovy | 52 ++++++ .../accurest/stubrunner/StubRunning.groovy | 9 + .../accurest/stubrunner/StubServer.groovy | 68 ++++++++ .../stubrunner/util/StringUtils.groovy | 124 +++++++++++++ .../stubrunner/util/StubsParser.groovy | 38 ++++ .../stubrunner/util/ZipCategory.groovy | 56 ++++++ .../accurestStubrunnerGrapeConfig.xml | 12 ++ .../AvailablePortScannerSpec.groovy | 45 +++++ .../stubrunner/BatchStubRunnerSpec.groovy | 32 ++++ .../stubrunner/MappingDescriptorSpec.groovy | 23 +++ .../stubrunner/StubRepositorySpec.groovy | 34 ++++ .../stubrunner/StubRunnerExecutorSpec.groovy | 40 +++++ .../stubrunner/StubRunnerFactorySpec.groovy | 31 ++++ .../accurest/stubrunner/StubRunnerSpec.groovy | 39 +++++ .../accurest/stubrunner/StubServerSpec.groovy | 35 ++++ .../stubrunner/util/ZipCategorySpec.groovy | 24 +++ .../mappings/com/ofg/bar/bar.json | 13 ++ .../mappings/com/ofg/foo/bar/foobar.json | 13 ++ .../mappings/com/ofg/foo/foo.json | 13 ++ .../projects/brokers/brokers.json | 5 + .../brokers/nested/anotherDescriptor.json | 5 + .../projects/descriptor.json | 5 + .../src/test/resources/emptyrepo/.gitkeep | 0 .../stub-runner/src/test/resources/file.zip | Bin 0 -> 171 bytes .../src/test/resources/logback.xml | 14 ++ .../mappings/com/ofg/bye/admin/admin.json | 9 + .../repository/mappings/com/ofg/bye/bye.json | 13 ++ .../mappings/com/ofg/hello/README.md | 1 + .../mappings/com/ofg/hello/admin/admin.json | 9 + .../mappings/com/ofg/hello/hello.json | 13 ++ .../mappings/com/ofg/ping/ping.json | 13 ++ .../mappings/lv/com/ofg/bye/lv_bye.json | 13 ++ .../mappings/pl/com/ofg/bye/pl_bye.json | 13 ++ .../pl/com/ofg/bye/pl_overridden_bye.json | 14 ++ 81 files changed, 2363 insertions(+), 1 deletion(-) create mode 100644 stub-runner/stub-runner-junit/README.md create mode 100644 stub-runner/stub-runner-junit/build.gradle create mode 100644 stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java create mode 100644 stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy create mode 100644 stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy create mode 100644 stub-runner/stub-runner-junit/src/test/resources/logback.xml create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring/README.md create mode 100644 stub-runner/stub-runner-spring/build.gradle create mode 100644 stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java create mode 100644 stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy create mode 100644 stub-runner/stub-runner-spring/src/test/resources/application.yml create mode 100644 stub-runner/stub-runner-spring/src/test/resources/logback.xml create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner/README.md create mode 100644 stub-runner/stub-runner/build.gradle create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/Arguments.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MappingDescriptor.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunning.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StringUtils.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/ZipCategory.groovy create mode 100644 stub-runner/stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/util/ZipCategorySpec.groovy create mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/bar/bar.json create mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/bar/foobar.json create mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/foo.json create mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json create mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json create mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json create mode 100644 stub-runner/stub-runner/src/test/resources/emptyrepo/.gitkeep create mode 100644 stub-runner/stub-runner/src/test/resources/file.zip create mode 100644 stub-runner/stub-runner/src/test/resources/logback.xml create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/admin/admin.json create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/bye.json create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/README.md create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/admin/admin.json create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/hello.json create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/ping/ping.json create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/lv/com/ofg/bye/lv_bye.json create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_bye.json create mode 100644 stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_overridden_bye.json diff --git a/.travis.yml b/.travis.yml index 220272e2ee..14f8d62652 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,12 @@ language: java sudo: false +before_install: + - "export JAVA_OPTS='-Xmx1024m -XX:MaxPermSize=384m'" + - "rm -rf $HOME/.m2/repository/io/codearte/accurest/stubs" + - "mkdir $HOME/.m2/repository/io/codearte/accurest/ --parents" + - "cp -r stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs $HOME/.m2/repository/io/codearte/accurest/" + jdk: - oraclejdk7 - openjdk7 @@ -12,4 +18,4 @@ cache: - $HOME/.m2 install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --info --continue +script: ./gradlew clean check funcTest --stacktrace --info --continue --parallel diff --git a/README.md b/README.md index 923a398c25..a29b3523e7 100644 --- a/README.md +++ b/README.md @@ -19,3 +19,17 @@ For more information please go to the [Wiki](https://github.com/Codearte/accures ### Wiremock In order to use Accurest with Wiremock you have to have __Wiremock in version at least 2.0.0-beta__ . Of course the higher the better :) + +## Additional projects + +### Stub Runner + +Allows you to download WireMock stubs from the provided Maven repository and runs them in WireMock servers. + +### Stub Runner JUnit + +Stub Runner with JUnit rules + +### Stub Runner Spring + +Spring Configuration that automatically starts stubs upon Spring Context build up \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 7a36841ba8..762abc0c49 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,8 @@ include "accurest-core", "accurest-gradle-plugin", 'accurest-converters', 'accurest-testing-utils' +include ':stub-runner:stub-runner' +include ':stub-runner:stub-runner-spring' +include ':stub-runner:stub-runner-junit' rootProject.name = "accurest" +//to prevent StackOverflow in Sonar +project(":stub-runner").name = "stub-runner-root" \ No newline at end of file diff --git a/stub-runner/stub-runner-junit/README.md b/stub-runner/stub-runner-junit/README.md new file mode 100644 index 0000000000..32c824c182 --- /dev/null +++ b/stub-runner/stub-runner-junit/README.md @@ -0,0 +1,42 @@ +stub-runner-junit +================= + +Contains a JUnit Rule for Stub Runner. + +Example of usage: + +``` +class AccurestRuleSpec extends Specification { + + @ClassRule @Shared AccurestRule rule = new AccurestRule() + .repoRoot(AccurestRuleSpec.getResource("/m2repo").path) + .downloadStub("io.codearte.accurest.stubs", "loanIssuance") + .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") + + def 'should start WireMock servers'() { + expect: + rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null + rule.findStubUrl('loanIssuance') != null + rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + } +} +``` + +You can set the default value of the Maven repository by means of system property: + +``` +-Dstubrunner.stubs.repository.root=http://your.maven.repo.com +``` + +The list of configurable properties contains: + +| Name | Default value | Description | +|------|---------------|-------------| +| stubrunner.port.range.min | 10000 | Minimal value of a port for a WireMock server | +| stubrunner.port.range.max | 15000 | Maximum value of a port for a WireMock server | +| stubrunner.stubs.repository.root | | Address to your M2 repo (will point to local M2 repo if none is provided) | +| stubrunner.stubs.repository.root | | Address to your M2 repo (will point to local M2 repo if none is provided) | +| stubrunner.work-offline | false | Should try to connect to any repo to download stubs (especially good if there's no internet) | +| stubrunner.stubs | | Default comma separated list of stubs to download | + diff --git a/stub-runner/stub-runner-junit/build.gradle b/stub-runner/stub-runner-junit/build.gradle new file mode 100644 index 0000000000..d7156d14b9 --- /dev/null +++ b/stub-runner/stub-runner-junit/build.gradle @@ -0,0 +1,15 @@ +description = 'JUnit rule for stub-runner' + +dependencies { + compile project(':stub-runner-root:stub-runner') + + compile localGroovy() + compile 'junit:junit:4.12' + + testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + testCompile 'ch.qos.logback:logback-classic:1.1.3' +} diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java new file mode 100644 index 0000000000..b584b8ca7f --- /dev/null +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -0,0 +1,158 @@ +package io.codearte.accurest.stubrunner.junit; + +import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import io.codearte.accurest.stubrunner.BatchStubRunner; +import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; +import io.codearte.accurest.stubrunner.StubConfiguration; +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.StubRunnerOptions; +import io.codearte.accurest.stubrunner.util.StringUtils; +import io.codearte.accurest.stubrunner.util.StubsParser; + +/** + * JUnit class rule that allows you to download the provided stubs. + * + * @author Marcin Grzejszczak + */ +public class AccurestRule implements TestRule, StubFinder { + private static final String DELIMITER = ":"; + + private Set stubs = new HashSet(); + private StubRunnerOptions stubRunnerOptions = defaultStubRunnerOptions(); + private BatchStubRunner stubFinder; + + @Override + public Statement apply(final Statement base, Description description) { + return new Statement() { + @Override + public void evaluate() throws Throwable { + before(); + base.evaluate(); + stubFinder.close(); + } + + private void before() { + Collection dependencies = StubsParser.fromString(stubs, stubRunnerOptions.getStubsClassifier()); + stubFinder = new BatchStubRunnerFactory(stubRunnerOptions, dependencies) + .buildBatchStubRunner(); + stubFinder.runStubs(); + } + }; + } + + private StubRunnerOptions defaultStubRunnerOptions() { + Integer minPort = Integer.valueOf(System.getProperty("stubrunner.port.range.min", "10000")); + Integer maxPort = Integer.valueOf(System.getProperty("stubrunner.port.range.max", "15000")); + String repoRoot = System.getProperty("stubrunner.stubs.repository.root", ""); + String stubSuffix = System.getProperty("stubrunner.stubs.classifier", "stubs"); + Boolean workOffline = Boolean.parseBoolean(System.getProperty("stubrunner.work-offline", "false")); + String stubsToDownload = System.getProperty("stubrunner.stubs", ""); + if (StringUtils.hasText(stubsToDownload)) { + Collections.addAll(stubs, stubsToDownload.split(",")); + } + return new StubRunnerOptions(minPort, maxPort, repoRoot, workOffline, stubSuffix); + } + + /** + * Override all options + * + * @see StubRunnerOptions + */ + public AccurestRule options(StubRunnerOptions stubRunnerOptions) { + this.stubRunnerOptions = stubRunnerOptions; + return this; + } + + /** + * Min value of port for WireMock server + */ + public AccurestRule minPort(int minPort) { + this.stubRunnerOptions.setMinPortValue(minPort); + return this; + } + + /** + * Max value of port for WireMock server + */ + public AccurestRule maxPort(int maxPort) { + this.stubRunnerOptions.setMaxPortValue(maxPort); + return this; + } + + /** + * String URI of repository containing stubs + */ + public AccurestRule repoRoot(String repoRoot) { + this.stubRunnerOptions.setStubRepositoryRoot(repoRoot); + return this; + } + + /** + * Should download stubs or use only the local repository + */ + public AccurestRule workOffline(boolean workOffline) { + this.stubRunnerOptions.setWorkOffline(workOffline); + return this; + } + + /** + * Group Id, artifact Id and classifier of a single stub to download + */ + public AccurestRule downloadStub(String groupId, String artifactId, String classifier) { + stubs.add(groupId + DELIMITER + artifactId + DELIMITER + classifier); + return this; + } + + /** + * Group Id, artifact Id of a single stub to download. Default classifier will be picked. + */ + public AccurestRule downloadStub(String groupId, String artifactId) { + stubs.add(groupId + DELIMITER + artifactId); + return this; + } + + /** + * Ivy notation of a single stub to download. + */ + public AccurestRule downloadStub(String ivyNotation) { + stubs.add(ivyNotation); + return this; + } + + /** + * Stubs to download in Ivy notations + */ + public AccurestRule downloadStubs(String... ivyNotations) { + stubs.addAll(Arrays.asList(ivyNotations)); + return this; + } + + /** + * Stubs to download in Ivy notations + */ + public AccurestRule downloadStubs(List ivyNotations) { + stubs.addAll(ivyNotations); + return this; + } + + @Override + public URL findStubUrl(String groupId, String artifactId) { + return stubFinder.findStubUrl(groupId, artifactId); + } + + @Override + public URL findStubUrl(String ivyNotation) { + return stubFinder.findStubUrl(ivyNotation); + } +} diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy new file mode 100644 index 0000000000..755f8857c7 --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy @@ -0,0 +1,27 @@ +package io.codearte.accurest.stubrunner.junit + +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +class AccurestRuleSpec extends Specification { + + @ClassRule @Shared AccurestRule rule = new AccurestRule() + .repoRoot(AccurestRuleSpec.getResource("/m2repo").path) + .downloadStub("io.codearte.accurest.stubs", "loanIssuance") + .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") + + def 'should start WireMock servers'() { + expect: 'WireMocks are running' + rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null + rule.findStubUrl('loanIssuance') != null + rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: 'Stubs were registered' + "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + } +} diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy new file mode 100644 index 0000000000..77ab729acc --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy @@ -0,0 +1,33 @@ +package io.codearte.accurest.stubrunner.junit + +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification +import spock.util.environment.RestoreSystemProperties + +/** + * @author Marcin Grzejszczak + */ +@RestoreSystemProperties +class AccurestRuleSysPropsSpec extends Specification { + + static { + System.properties.setProperty("stubrunner.stubs.repository.root", AccurestRuleSysPropsSpec.getResource("/m2repo").path) + System.properties.setProperty("stubrunner.stubs.classifier", 'classifier that will be overridden') + } + + @ClassRule @Shared AccurestRule rule = new AccurestRule() + .downloadStub("io.codearte.accurest.stubs", "loanIssuance", "stubs") + .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:stubs") + + def 'should start WireMock servers'() { + expect: 'WireMocks are running' + rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null + rule.findStubUrl('loanIssuance') != null + rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: 'Stubs were registered' + "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + } +} diff --git a/stub-runner/stub-runner-junit/src/test/resources/logback.xml b/stub-runner/stub-runner-junit/src/test/resources/logback.xml new file mode 100644 index 0000000000..0cfb35f4cd --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..a29a63180218c9e81bc924a09c14be4b4619b519 GIT binary patch literal 1733 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^BlM4AaJ9Yi?peL1tch zF@~)`i{Q?a1G3=?(~1&HQ(RI@Qj<$E^YemJi^@`qFm#)($XO`C$iN^4^r0<5-NhOC zr8z0SiACAYIhm<>C62{@`6X^3d-Sr3^Yf-oIO})VK%nJ)EmwAHh=8K+>H4Ky0r>?A zO$Aw11}7IS*-_T<)+=;M`TJYGipPsKsJ^e*KX-200f{R=k^`j^g0Eeet+h?;9qZ!t zvu@jH8~kod&|iB|MC*IjpNTT7=4;(Qc1L2((z08Nly|b_aV(g>b<&r`ALgoew_iSP zAgt;oyx8qvnz5OTzux+F`FZc(Eq-`YsHR?8hFPfV^zyBnE?Mv;I$7=K*!IRp>_qXJ zulMJL%+}64am01g+70>>TvirL)Ua<4pQ>S;=cVc{J+s|zdV#TB{6y&&Rksd4%xkV) zw<{><`;G;?=GUxexCH83+b{7vSo~b?effXm)=aMT`kE}755s0yvge=3)bhN zHtRJ0_w^Uvp~dWh_1B^lfI+SW400|{&L}2ObW6#xm4R{M5 zg!I1K@Ejd<- zKQ^=2ShZI*X6bIB-Az;1sQWBA<)56Y+0`@C>Eyq#XA{d+Z}I6}FH_H`p7r2|`NM;u zv05vwV=lDKyp?az^SH0L?!>&N=jZ0!&fhob(2PT;Yj#yE6A1E-Nq#nMhVtg-y|;d) zPf^ej!3mD%0Kx{~4xCbXzdZgy$SsX# z0a{+VI=;Gkfk7LBR*~db; zfeD6@NrV}95d?HS5C|~5bp+Ay0tsCkdVvH|3<66UHGw2t8&dIvYy!4Y2&^4w@n6R> zAQN8HAZtS}GC^e$1c0>72QuN>u$EBhW}%l*Fw?d)-X&-jf$|F3Dv)o{b0)&70AOCl p?`%w~5cw3{9`uxmu;&CbarU63%K&dyHjokQK&S_FXd?@V2LP^BMu-3a literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..2a8b40b197 --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + io.codearte.accurest.stubs + fraudDetectionServer-stubs + 0.0.1-SNAPSHOT + diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..5e2fc1d528 --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer-stubs + 0.0.1-SNAPSHOT + + + true + + 20160326150924 + + diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml new file mode 100644 index 0000000000..46fa17218f --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml @@ -0,0 +1,11 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer-stubs + + + 0.0.1-SNAPSHOT + + 20160326150924 + + diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..12d6b10f29e2a1b6c25afea27910ef6af0c4f3ce GIT binary patch literal 587 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^Bm13@$;1F;Mc!xa{1tz+^=dFGg6cC{0rK{tss}~rw zA!r5Lr$(ivu9gb(Ce_6y<*k~;=VD;KRYlpJRp;G1sYNUzYpynC=c`K+U-=X=K6k9GE;P;Q_n7@0(vaR(mIfj}U@@YWGT z!-EoC8+uTJ6obH$Mol0I*M=0Z=q7+vBgYzu53=~LV;PW!2NJqA^w0$B0uoyq=Ob&w V61D-}tZX3FEI{}RNLw?4cmNRMhR*;1 literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..a296158345 --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + io.codearte.accurest.stubs + loanIssuance-stubs + 0.0.1-SNAPSHOT + diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..f33521f12d --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + loanIssuance-stubs + 0.0.1-SNAPSHOT + + + true + + 20160326150924 + + diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml new file mode 100644 index 0000000000..e990fad0bc --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml @@ -0,0 +1,11 @@ + + + io.codearte.accurest.stubs + loanIssuance-stubs + + + 0.0.1-SNAPSHOT + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring/README.md b/stub-runner/stub-runner-spring/README.md new file mode 100644 index 0000000000..2229814c9e --- /dev/null +++ b/stub-runner/stub-runner-spring/README.md @@ -0,0 +1,32 @@ +stub-runner-spring +======================= + +Sets up Spring configuration of the Stub Runner project. + +By providing a list of stubs inside your configuration file the Stub Runner automatically downloads +and registers in WireMock the selected stubs. + +If you want to find the URL of your stubbed dependency you can autowire the `StubFinder` interface and use +its methods as presented below: + +``` + @Autowired StubFinder stubFinder + + def 'should start WireMock servers'() { + expect: 'WireMocks are running' + stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null + stubFinder.findStubUrl('loanIssuance') != null + stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: 'Stubs were registered' + "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + } +``` + +for the following configuration file: + +``` +stubrunner.stubs.repository.root: classpath:m2repo +stubrunner.stubs: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer +``` \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/build.gradle b/stub-runner/stub-runner-spring/build.gradle new file mode 100644 index 0000000000..3df19ddb06 --- /dev/null +++ b/stub-runner/stub-runner-spring/build.gradle @@ -0,0 +1,18 @@ +description = 'Spring configuration for stub-runner' + +dependencies { + compile project(':stub-runner-root:stub-runner') + + compile localGroovy() + compile 'org.springframework:spring-context:[3.0.0.RELEASE,)' + + testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + testCompile 'org.springframework.boot:spring-boot-starter:1.3.3.RELEASE' + testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile 'org.spockframework:spock-spring:1.0-groovy-2.3' + testCompile 'ch.qos.logback:logback-classic:1.1.3' +} diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java new file mode 100644 index 0000000000..0f1c8d6939 --- /dev/null +++ b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java @@ -0,0 +1,57 @@ +package io.codearte.accurest.stubrunner.spring; + +import java.io.IOException; +import java.util.Set; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.Resource; + +import io.codearte.accurest.stubrunner.BatchStubRunner; +import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; +import io.codearte.accurest.stubrunner.StubConfiguration; +import io.codearte.accurest.stubrunner.StubRunner; +import io.codearte.accurest.stubrunner.StubRunnerOptions; +import io.codearte.accurest.stubrunner.StubRunning; +import io.codearte.accurest.stubrunner.util.StubsParser; + +/** + * Configuration that initializes a {@link BatchStubRunner} that runs {@link StubRunner} instance for each stub + */ +@Configuration +public class StubRunnerConfiguration { + + /** + * Bean that initializes stub runners, runs them and on shutdown closes them. Upon its instantiation + * JAR with stubs is downloaded and unpacked to a temporary folder and WireMock server are started + * for each of those stubs + * + * @param minPortValue min port value of the WireMock instance for stubs + * @param maxPortValue max port value of the WireMock instance for stubs + * @param stubRepositoryRoot root URL from where the JAR with stub mappings will be downloaded + * @param stubsSuffix classifier for the jar containing stubs + * @param workOffline forces offline work + * @param stubs comma separated list of stubs presented in Ivy notation + */ + @Bean(initMethod = "runStubs", destroyMethod = "close") + public StubRunning batchStubRunner( + @Value("${stubrunner.port.range.min:10000}") Integer minPortValue, + @Value("${stubrunner.port.range.max:15000}") Integer maxPortValue, + @Value("${stubrunner.stubs.repository.root:}") Resource stubRepositoryRoot, + @Value("${stubrunner.stubs.classifier:stubs}") String stubsSuffix, + @Value("${stubrunner.work-offline:false}") boolean workOffline, + @Value("${stubrunner.stubs:}") String stubs) throws IOException { + StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue, + maxPortValue, uriStringOrEmpty(stubRepositoryRoot), + stubRepositoryRoot == null || workOffline, stubsSuffix); + Set dependencies = StubsParser.fromString(stubs, stubsSuffix); + return new BatchStubRunnerFactory(stubRunnerOptions, dependencies) + .buildBatchStubRunner(); + } + + private String uriStringOrEmpty(Resource stubRepositoryRoot) throws IOException { + return stubRepositoryRoot != null ? stubRepositoryRoot.getURI().toString() : ""; + } + +} diff --git a/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy b/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy new file mode 100644 index 0000000000..2e3a749ecd --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy @@ -0,0 +1,37 @@ +package io.codearte.accurest.stubrunner.spring + +import io.codearte.accurest.stubrunner.StubFinder +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Import +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) +class StubRunnerConfigurationSpec extends Specification { + + @Autowired StubFinder stubFinder + + def 'should start WireMock servers'() { + expect: 'WireMocks are running' + stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null + stubFinder.findStubUrl('loanIssuance') != null + stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: 'Stubs were registered' + "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + } + + @Configuration + @Import(StubRunnerConfiguration) + @EnableAutoConfiguration + static class Config { + + } +} diff --git a/stub-runner/stub-runner-spring/src/test/resources/application.yml b/stub-runner/stub-runner-spring/src/test/resources/application.yml new file mode 100644 index 0000000000..4b48d59b25 --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo +stubrunner.stubs: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/src/test/resources/logback.xml b/stub-runner/stub-runner-spring/src/test/resources/logback.xml new file mode 100644 index 0000000000..0cfb35f4cd --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..a29a63180218c9e81bc924a09c14be4b4619b519 GIT binary patch literal 1733 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^BlM4AaJ9Yi?peL1tch zF@~)`i{Q?a1G3=?(~1&HQ(RI@Qj<$E^YemJi^@`qFm#)($XO`C$iN^4^r0<5-NhOC zr8z0SiACAYIhm<>C62{@`6X^3d-Sr3^Yf-oIO})VK%nJ)EmwAHh=8K+>H4Ky0r>?A zO$Aw11}7IS*-_T<)+=;M`TJYGipPsKsJ^e*KX-200f{R=k^`j^g0Eeet+h?;9qZ!t zvu@jH8~kod&|iB|MC*IjpNTT7=4;(Qc1L2((z08Nly|b_aV(g>b<&r`ALgoew_iSP zAgt;oyx8qvnz5OTzux+F`FZc(Eq-`YsHR?8hFPfV^zyBnE?Mv;I$7=K*!IRp>_qXJ zulMJL%+}64am01g+70>>TvirL)Ua<4pQ>S;=cVc{J+s|zdV#TB{6y&&Rksd4%xkV) zw<{><`;G;?=GUxexCH83+b{7vSo~b?effXm)=aMT`kE}755s0yvge=3)bhN zHtRJ0_w^Uvp~dWh_1B^lfI+SW400|{&L}2ObW6#xm4R{M5 zg!I1K@Ejd<- zKQ^=2ShZI*X6bIB-Az;1sQWBA<)56Y+0`@C>Eyq#XA{d+Z}I6}FH_H`p7r2|`NM;u zv05vwV=lDKyp?az^SH0L?!>&N=jZ0!&fhob(2PT;Yj#yE6A1E-Nq#nMhVtg-y|;d) zPf^ej!3mD%0Kx{~4xCbXzdZgy$SsX# z0a{+VI=;Gkfk7LBR*~db; zfeD6@NrV}95d?HS5C|~5bp+Ay0tsCkdVvH|3<66UHGw2t8&dIvYy!4Y2&^4w@n6R> zAQN8HAZtS}GC^e$1c0>72QuN>u$EBhW}%l*Fw?d)-X&-jf$|F3Dv)o{b0)&70AOCl p?`%w~5cw3{9`uxmu;&CbarU63%K&dyHjokQK&S_FXd?@V2LP^BMu-3a literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..2a8b40b197 --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + io.codearte.accurest.stubs + fraudDetectionServer-stubs + 0.0.1-SNAPSHOT + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..5e2fc1d528 --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer-stubs + 0.0.1-SNAPSHOT + + + true + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml new file mode 100644 index 0000000000..46fa17218f --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml @@ -0,0 +1,11 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer-stubs + + + 0.0.1-SNAPSHOT + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..12d6b10f29e2a1b6c25afea27910ef6af0c4f3ce GIT binary patch literal 587 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^Bm13@$;1F;Mc!xa{1tz+^=dFGg6cC{0rK{tss}~rw zA!r5Lr$(ivu9gb(Ce_6y<*k~;=VD;KRYlpJRp;G1sYNUzYpynC=c`K+U-=X=K6k9GE;P;Q_n7@0(vaR(mIfj}U@@YWGT z!-EoC8+uTJ6obH$Mol0I*M=0Z=q7+vBgYzu53=~LV;PW!2NJqA^w0$B0uoyq=Ob&w V61D-}tZX3FEI{}RNLw?4cmNRMhR*;1 literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..a296158345 --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + io.codearte.accurest.stubs + loanIssuance-stubs + 0.0.1-SNAPSHOT + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..f33521f12d --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + loanIssuance-stubs + 0.0.1-SNAPSHOT + + + true + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml new file mode 100644 index 0000000000..e990fad0bc --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml @@ -0,0 +1,11 @@ + + + io.codearte.accurest.stubs + loanIssuance-stubs + + + 0.0.1-SNAPSHOT + + 20160326150924 + + diff --git a/stub-runner/stub-runner/README.md b/stub-runner/stub-runner/README.md new file mode 100644 index 0000000000..c52bdf7b9e --- /dev/null +++ b/stub-runner/stub-runner/README.md @@ -0,0 +1,88 @@ +Stub-runner +=========== + +Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of +[Consumer Driven Contracts](http://martinfowler.com/articles/consumerDrivenContracts.html). + +### Running stubs + +#### Running using main app + +You can set the following options to the main class: + +``` +java -jar stub-runner.jar [options...] + -maxp (--maxPort) N : Maximum port value to be assigned to the + Wiremock instance. Defaults to 15000 + (default: 15000) + -minp (--minPort) N : Minimal port value to be assigned to the + Wiremock instance. Defaults to 10000 + (default: 10000) + -s (--stubs) VAL : Comma separated list of Ivy representation of + jars with stubs. Eg. groupid:artifactid1,group + id2:artifactid2:classifier + -sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you + keep your stubs (e.g. http://nexus.net/content + /repositories/repository) + -ss (--stubsSuffix) VAL : Suffix for the jar containing stubs (e.g. + 'stubs' if the stub jar would have a 'stubs' + classifier for stubs: foobar-stubs ). + Defaults to 'stubs' (default: stubs) + -wo (--workOffline) : Switch to work offline. Defaults to 'false' + (default: false) + +``` + +### Stub runner configuration + +You can configure the stub runner by either passing the full arguments list with the `-Pargs` like this: + +``` +./gradlew stub-runner-root:stub-runner:run -Pargs="-c pl -minp 10000 -maxp 10005 -s a:b:c,d:e,f:g:h" +``` + +or each parameter separately with a `-P` prefix and without the hyphen `-` in the name of the param + +``` +./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 +``` + +### Defining collaborators' stubs + +You can define global stubs under folder corresponding to groupid/artifactid of your collaborator + +``` +com/ofg/foo +``` + +By default stub definitions are stored in `mappings` directory inside stub repository. + +#### Stubbing collaborators + +For each collaborator defined in project metadata all collaborator mappings (stubs) available in repository are loaded. +Stubs are defined in JSON documents, whose syntax is defined in [WireMock documentation](http://wiremock.org/stubbing.html) + +Example: +```json +{ + "request": { + "method": "GET", + "url": "/ping" + }, + "response": { + "status": 200, + "body": "pong", + "headers": { + "Content-Type": "text/plain" + } + } +} +``` + +Stub definitions are stored in stub repository under the same path as collaborator fully qualified name. +Paths (as long it's inside the directory mentioned above) and names of documents containing stub definitions not play any +other role than describing stubs' role / purpose. + +#### Viewing registered mappings + +Every stubbed collaborator exposes list of defined mappings under `__/admin/` endpoint. \ No newline at end of file diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle new file mode 100644 index 0000000000..63c8faa6ff --- /dev/null +++ b/stub-runner/stub-runner/build.gradle @@ -0,0 +1,73 @@ +description = 'Runs stubs for service collaborators' + +apply plugin: 'application' +mainClassName = 'io.codearte.accurest.stubrunner.StubRunnerMain' + +dependencies { + compile 'org.apache.ivy:ivy:2.4.0' + compile localGroovy() + compile "com.github.tomakehurst:wiremock:$wiremockVersion" + compile 'javax.servlet:javax.servlet-api:3.1.0' + compile 'args4j:args4j:2.32' + compile 'com.nurkiewicz.asyncretry:asyncretry-jdk7:0.0.6' + + testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + testCompile 'ch.qos.logback:logback-classic:1.1.3' +} + +ext { + stubRepositoryRoot = getPropertyByEither('sr', 'stubRepositoryRoot') + stubsSuffix = getPropertyByEither('ss', 'stubsSuffix') + minPortValue = getPropertyByEither('minp', 'minPort') + maxPortValue = getPropertyByEither('maxp', 'maxPort') + skipLocalRepo = getPropertyByEither('wo', 'workOffline') + stubs = getPropertyByEither('s', 'stubs') + arguments = project.hasProperty('args') ? project.property('args') : [] + /* example of args: + '-minp 10000 -maxp 10005 -s ""groupid:artifactid1,groupid2:artifactid2" -sr http://dl.bintray.com/somelink/micro' + */ +} + +Object getPropertyByEither(String paramName1, String paramName2, Object defaultValue = null) { + return project.hasProperty(paramName1) ? project.property(paramName1) : + project.hasProperty(paramName2) ? project.property(paramName2) : defaultValue +} + +run { + main = 'io.codearte.accurest.stubrunner.StubRunnerMain' + List argumentList + if (arguments) { + argumentList = (arguments.split(' ') as List).findAll { it != null } + } else { + argumentList = parseArguments() + } + args = argumentList + if (args) { + println "Running task with args $args" + } +} + +List parseArguments() { + println "Trying to parse the project arguments" + List arguments = [] + appendToListIfNotNull(stubRepositoryRoot, '-sr', arguments) + appendToListIfNotNull(stubsSuffix, '-ss', arguments) + appendToListIfNotNull(minPortValue, '-minp', arguments) + appendToListIfNotNull(maxPortValue, '-maxp', arguments) + appendToListIfNotNull(skipLocalRepo, '-wo', arguments) + appendToListIfNotNull(stubs, '-s', arguments) + return arguments +} + +Object appendToListIfNotNull(String argument, String prefix, List list) { + if (argument != null) { + list << "$prefix" + if (!argument.isAllWhitespace()) { + list << argument + } + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/Arguments.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/Arguments.groovy new file mode 100644 index 0000000000..cccf0f91aa --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/Arguments.groovy @@ -0,0 +1,27 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import groovy.transform.ToString + +/** + * Arguments passed to the {@link StubRunner} application + * + * @see StubRunner + */ +@CompileStatic +@ToString(includeNames = true) +@PackageScope +class Arguments { + final StubRunnerOptions stubRunnerOptions + final String context + final String repositoryPath + final StubConfiguration stub + + Arguments(StubRunnerOptions stubRunnerOptions, String repositoryPath = "", StubConfiguration stub = null) { + this.stubRunnerOptions = stubRunnerOptions + this.context = context + this.repositoryPath = repositoryPath + this.stub = stub + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy new file mode 100644 index 0000000000..3b2df9f9b5 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy @@ -0,0 +1,73 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import groovy.util.logging.Slf4j + +/** + * Tries to execute a closure with an available port from the given range + */ +@CompileStatic +@Slf4j +@PackageScope +class AvailablePortScanner { + + private static final int MAX_RETRY_COUNT = 1000 + + private final int minPortNumber + private final int maxPortNumber + private final int maxRetryCount + + AvailablePortScanner(int minPortNumber, int maxPortNumber, int maxRetryCount = MAX_RETRY_COUNT) { + checkPortRanges(minPortNumber, maxPortNumber) + this.minPortNumber = minPortNumber + this.maxPortNumber = maxPortNumber + this.maxRetryCount = maxRetryCount + } + + private void checkPortRanges(int minPortNumber, int maxPortNumber) { + if (minPortNumber >= maxPortNumber) { + throw new InvalidPortRange(minPortNumber, maxPortNumber) + } + } + + public T tryToExecuteWithFreePort(Closure closure) { + for (i in (1..maxRetryCount)) { + try { + int numberOfPortsToBind = maxPortNumber - minPortNumber + int portToScan = new Random().nextInt(numberOfPortsToBind) + minPortNumber + checkIfPortIsAvailable(portToScan) + return executeLogicForAvailablePort(portToScan, closure) + } catch (BindException exception) { + log.debug("Failed to execute closure (try: $i/$maxRetryCount)", exception) + } + } + throw new NoPortAvailableException(minPortNumber, maxPortNumber) + } + + private T executeLogicForAvailablePort(int portToScan, Closure closure) { + log.debug("Trying to execute closure with port [$portToScan]") + return closure(portToScan) + } + + private void checkIfPortIsAvailable(int portToScan) { + ServerSocket socket = null + try { + socket = new ServerSocket(portToScan) + } finally { + socket.close() + } + } + + static class NoPortAvailableException extends RuntimeException { + protected NoPortAvailableException(int lowerBound, int upperBound) { + super("Could not find available port in range $lowerBound:$upperBound") + } + } + + static class InvalidPortRange extends RuntimeException { + protected InvalidPortRange(int lowerBound, int upperBound) { + super("Invalid bounds exceptions, min port [$lowerBound] is greater or equal to max port [$upperBound]") + } + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy new file mode 100644 index 0000000000..3281ca38a7 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy @@ -0,0 +1,52 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic + +/** + * Manages lifecycle of multiple {@link StubRunner} instances. + * + * @see StubRunner + */ +@CompileStatic +class BatchStubRunner implements StubRunning { + + private final Iterable stubRunners + + BatchStubRunner(Iterable stubRunners) { + this.stubRunners = stubRunners + } + + @Override + RunningStubs runStubs() { + Map appsAndPorts = stubRunners.inject([:]) { Map acc, StubRunner value -> + acc.putAll(value.runStubs().namesAndPorts) + return acc + } as Map + return new RunningStubs(appsAndPorts) + } + + @Override + URL findStubUrl(String groupId, String artifactId) { + return stubRunners.findResult(null) { StubRunner stubRunner -> + return stubRunner.findStubUrl(groupId, artifactId) + } as URL + } + + @Override + URL findStubUrl(String ivyNotation) { + String[] splitString = ivyNotation.split(":") + if (splitString.length > 3) { + throw new IllegalArgumentException("$ivyNotation is invalid") + } else if (splitString.length == 2) { + return findStubUrl(splitString[0], splitString[1]) + } + return findStubUrl(null, splitString[0]) + } + + @Override + void close() throws IOException { + stubRunners.each { + it.close() + } + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy new file mode 100644 index 0000000000..18652eb767 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy @@ -0,0 +1,27 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic + +/** + * Manages lifecycle of multiple {@link StubRunner} instances. + * + * @see StubRunner + * @see BatchStubRunner + */ +@CompileStatic +class BatchStubRunnerFactory { + + private final StubRunnerOptions stubRunnerOptions + private final Collection dependencies + + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies) { + this.stubRunnerOptions = stubRunnerOptions + this.dependencies = dependencies + } + + BatchStubRunner buildBatchStubRunner() { + StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, dependencies) + return new BatchStubRunner(stubRunnerFactory.createStubsFromServiceConfiguration()) + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MappingDescriptor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MappingDescriptor.groovy new file mode 100644 index 0000000000..18357b82a9 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MappingDescriptor.groovy @@ -0,0 +1,27 @@ +package io.codearte.accurest.stubrunner + +import com.github.tomakehurst.wiremock.stubbing.StubMapping +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.PackageScope +import groovy.transform.ToString + +/** + * Represents a single JSON file that was found in the folder with + * potential WireMock stubs + */ +@CompileStatic +@EqualsAndHashCode +@ToString(includePackage = false) +@PackageScope +class MappingDescriptor { + final File descriptor + + MappingDescriptor(File mappingDescriptor) { + this.descriptor = mappingDescriptor + } + + StubMapping getMapping() { + return StubMapping.buildFrom(descriptor.getText('UTF-8')) + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy new file mode 100644 index 0000000000..c2f0572d3f --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy @@ -0,0 +1,25 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode + +/** + * Structure representing executed stubs. Contains the configuration of each stub + * together with the port on which its executed. + */ +@EqualsAndHashCode +@CompileStatic +class RunningStubs { + final Map namesAndPorts + + RunningStubs(Map map) { + this.namesAndPorts = map + } + + @Override + String toString() { + return namesAndPorts.collect { + "Stub [${it.key.toColonSeparatedDependencyNotation()}] is running on port [${it.value}]" + }.join("\n") + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy new file mode 100644 index 0000000000..1ab0c82e0c --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy @@ -0,0 +1,61 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import io.codearte.accurest.stubrunner.util.StringUtils + +/** + * Represents a configuration of a single stub. The stub can be described + * by groupId:artifactId:classifier notation + */ +@CompileStatic +@EqualsAndHashCode +public class StubConfiguration { + private static final String STUB_COLON_DELIMITER = ":" + + final String groupId + final String artifactId + final String classifier + + public StubConfiguration(String groupId, String artifactId, String classifier) { + this.groupId = groupId + this.artifactId = artifactId + this.classifier = classifier + } + + public StubConfiguration(String stubPath, String defaultClassifier = "stubs") { + String[] parsedPath = parsedPathEmptyByDefault(stubPath, STUB_COLON_DELIMITER, defaultClassifier) + this.groupId = parsedPath[0] + this.artifactId = parsedPath[1] + this.classifier = parsedPath[2] + } + + private List parsedPathEmptyByDefault(String path, String delimiter, String defaultClassifier) { + String[] splitPath = path.split(delimiter) + String stubsGroupId = "" + String stubsArtifactId = "" + String stubsClassifier = "" + if (splitPath.length >= 2) { + stubsGroupId = splitPath[0] + stubsArtifactId = splitPath[1] + stubsClassifier = splitPath.length == 3 ? splitPath[2] : defaultClassifier + } + return [stubsGroupId, stubsArtifactId, stubsClassifier] + } + + private boolean isDefined() { + return StringUtils.hasText(groupId) && StringUtils.hasText(this.artifactId) + } + + boolean hasClassifier() { + return StringUtils.hasText(classifier) + } + + public String toColonSeparatedDependencyNotation() { + if(!isDefined()) { + return "" + } + return [groupId, artifactId, classifier].join(STUB_COLON_DELIMITER) + } + +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy new file mode 100644 index 0000000000..94171feb7e --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy @@ -0,0 +1,165 @@ +package io.codearte.accurest.stubrunner + +import groovy.grape.Grape +import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.util.ZipCategory + +import static java.nio.file.Files.createTempDirectory + +/** + * Downloads stubs from an external repository and unpacks them locally + */ +@Slf4j +class StubDownloader { + + private static final String LATEST_MODULE = '*' + private static final String REPOSITORY_NAME = 'dependency-repository' + private static final String STUB_RUNNER_TEMP_DIR_PREFIX = 'stub-runner' + private static final String GRAPE_CONFIG = 'grape.config' + private static final String STUB_RUNNER_GRAPE_CONFIG = "accurest.stubrunner.grape.config" + + /** + * Downloads stubs from an external repository and unpacks them locally. + * Depending on the switch either uses only local repository to check for + * stub presence. + * + * @param workOffline -flag that defines whether only local cache should be used + * @param stubRepositoryRoot - address of the repo from which deps should be grabbed + * @param stubsGroup - group name of the jar containing stubs + * @param stubsModule - artifact id with a classifier name of the jar containing stubs + * @return file where the stubs where unpacked + */ + File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String + stubsModule) { + log.warn("Downloading stubs for group [$stubsGroup] and module [$stubsModule] from repository [$stubRepositoryRoot]") + URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule) + if (!stubJarUri) { + log.warn("Failed to download stubs for group [$stubsGroup] and module [$stubsModule] from repository [$stubRepositoryRoot]") + return null + } + File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) + unzippedStubsDir.deleteOnExit() + Thread.addShutdownHook { + unzippedStubsDir.deleteDir() + } + return unzippedStubsDir + } + + private File unpackStubJarToATemporaryFolder(URI stubJarUri) { + File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(STUB_RUNNER_TEMP_DIR_PREFIX).toFile() + tmpDirWhereStubsWillBeUnzipped.deleteOnExit() + log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") + use(ZipCategory) { + new File(stubJarUri).unzipTo(tmpDirWhereStubsWillBeUnzipped) + } + return tmpDirWhereStubsWillBeUnzipped + } + + private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule) { + Map depToGrab = [group: stubsGroup, module: stubsModule, version: LATEST_MODULE, transitive: false] + String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) + initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) + String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) + try { + System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) + log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") + return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) + } finally { + restoreOldGrapeConfigIfApplicable(oldGrapeConfig) + } + } + + private DependencyResolver buildResolver(boolean workOffline) { + return workOffline ? new LocalOnlyDependencyResolver() : new RemoteDependencyResolver() + } + + private void initializeAccurestGrapeIfAbsent(String accurestGrapePath) { + File accurestGrape = new File(accurestGrapePath) + if (!accurestGrape.exists()) { + accurestGrape.parentFile.mkdirs() + accurestGrape.createNewFile() + accurestGrape.text = StubDownloader.class.getResource('/accurestStubrunnerGrapeConfig.xml').text + } + } + + private void restoreOldGrapeConfigIfApplicable(String oldGrapeConfig) { + if (oldGrapeConfig) { + System.setProperty(GRAPE_CONFIG, oldGrapeConfig) + } + } + + private String getDefaultAccurestGrapeConfigPath() { + return "${System.getProperty('user.home')}/.accurest/accurestStubrunnerGrapeConfig.xml" + } + + /** + * Dependency resolver providing {@link URI} to remote dependencies. + */ + @Slf4j + private class RemoteDependencyResolver extends DependencyResolver { + + URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { + try { + return doResolveRemoteDependency(stubRepositoryRoot, depToGrab) + } catch (UnknownHostException e) { + failureHandler(stubRepositoryRoot, "unknown host error -> ${e.message}", e) + } catch (Exception e) { + failureHandler(stubRepositoryRoot, "connection error -> ${e.message}", e) + } + } + + private URI doResolveRemoteDependency(String stubRepositoryRoot, Map depToGrab) { + Grape.addResolver(name: REPOSITORY_NAME, root: stubRepositoryRoot) + log.info("Resolving dependency ${depToGrab} location in remote repository...") + return resolveDependencyLocation(depToGrab) + } + + private void failureHandler(String stubRepository, String reason, Exception cause) { + log.warn("Unable to resolve dependency in stub repository [$stubRepository]. Reason: [$reason]", cause) + } + + } + + /** + * Dependency resolver that first checks if a dependency is available in the local repository. + * If not, it will try to provide {@link URI} from the remote repository. + * + * @see RemoteDependencyResolver + */ + @Slf4j + private class LocalOnlyDependencyResolver extends DependencyResolver { + + URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { + try { + log.info("Resolving dependency ${depToGrab} location in local repository...") + return resolveDependencyLocation(depToGrab) + } catch (Exception e) { //Grape throws ordinary RuntimeException + log.warn("Unable to find dependency $depToGrab in local repository, trying $stubRepositoryRoot") + log.debug("Unable to find dependency $depToGrab in local repository: ${e.getClass()}: ${e.message}") + return null + } + } + } + + /** + * Base class of dependency resolvers providing {@link URI} to required dependency. + */ + abstract class DependencyResolver { + + /** + * Returns {@link URI} to a dependency. + * + * @param stubRepositoryRoot root of the repository where the dependency should be found + * @param depToGrab parameters describing dependency to search for + * + * @return {@link URI} to dependency + */ + abstract URI resolveDependency(String stubRepositoryRoot, Map depToGrab) + + URI resolveDependencyLocation(Map depToGrab) { + return Grape.resolve([classLoader: new GroovyClassLoader()], depToGrab).first() + } + + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy new file mode 100644 index 0000000000..f608436c2a --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy @@ -0,0 +1,21 @@ +package io.codearte.accurest.stubrunner + +interface StubFinder { + /** + * For the given groupId and artifactId tries to find the matching + * URL of the running stub. + * + * @param groupId - might be null. In that case a search only via artifactId takes place + * @return URL of a running stub or null if not found + */ + URL findStubUrl(String groupId, String artifactId) + + /** + * For the given Ivy notation {@code groupId:artifactId} tries to find the matching + * URL of the running stub. You can also pass only {@code artifactId}. + * + * @param ivyNotation - Ivy representation of the Maven artifact + * @return URL of a running stub or null if not found + */ + URL findStubUrl(String ivyNotation) +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy new file mode 100644 index 0000000000..147b24b390 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy @@ -0,0 +1,49 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope + +/** + * Wraps the folder with WireMock mappings. + */ +@CompileStatic +@PackageScope +class StubRepository { + + private final File path + + StubRepository(File repository) { + if (!repository.isDirectory()) { + throw new FileNotFoundException('Missing descriptor repository') + } + this.path = repository + } + + /** + * Returns the list of WireMock JSON files wrapped in {@link MappingDescriptor} + */ + List getProjectDescriptors() { + List mappingDescriptors = [] + mappingDescriptors.addAll(contextDescriptors()) + return mappingDescriptors + } + + private List contextDescriptors() { + return path.exists() ? collectMappingDescriptors(path) : [] + } + + private List collectMappingDescriptors(File descriptorsDirectory) { + List mappingDescriptors = [] + descriptorsDirectory.eachFileRecurse { File file -> + if (isMappingDescriptor(file)) { + mappingDescriptors << new MappingDescriptor(file) + } + } + return mappingDescriptors + } + + private static boolean isMappingDescriptor(File file) { + return file.isFile() && file.name.endsWith('.json') + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy new file mode 100644 index 0000000000..fd580d3e99 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -0,0 +1,58 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j + +/** + * Represents a single instance of ready-to-run stubs. + * Can run the stubs and then will return the name of the collaborator together with + * its URI. + * Can also be queried if the current groupid and artifactid are matching the + * corresponding running stub. + */ +@Slf4j +@CompileStatic +class StubRunner implements StubRunning { + + private StubRunnerExecutor localStubRunner + private final Arguments arguments + private final StubRepository stubRepository + + StubRunner(Arguments arguments) { + this.arguments = arguments + this.stubRepository = new StubRepository(new File(arguments.repositoryPath)) + } + + @Override + RunningStubs runStubs() { + AvailablePortScanner portScanner = new AvailablePortScanner(arguments.stubRunnerOptions.minPortValue, + arguments.stubRunnerOptions.maxPortValue) + localStubRunner = new StubRunnerExecutor(portScanner) + registerShutdownHook() + return localStubRunner.runStubs(stubRepository, arguments.stub) + } + + @Override + URL findStubUrl(String groupId, String artifactId) { + return localStubRunner.findStubUrl(groupId, artifactId) + } + + @Override + URL findStubUrl(String ivyNotation) { + String[] splitString = ivyNotation.split(":") + if (splitString.length == 1) { + throw new IllegalArgumentException("$ivyNotation is invalid") + } + return findStubUrl(splitString[0], splitString[1]) + } + + private void registerShutdownHook() { + Runnable stopAllServers = { this.close() } + Runtime.runtime.addShutdownHook(new Thread(stopAllServers)) + } + + @Override + void close() throws IOException { + localStubRunner?.shutdown() + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy new file mode 100644 index 0000000000..a12707c12b --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -0,0 +1,61 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j + +/** + * Runs stubs for a particular {@link StubServer} + */ +@CompileStatic +@Slf4j +class StubRunnerExecutor implements StubFinder { + + private final AvailablePortScanner portScanner + private StubServer stubServer + + StubRunnerExecutor(AvailablePortScanner portScanner) { + this.portScanner = portScanner + } + + RunningStubs runStubs(StubRepository repository, StubConfiguration stubConfiguration) { + startStubServers(stubConfiguration, repository) + RunningStubs runningCollaborators = + new RunningStubs([(stubServer.stubConfiguration): stubServer.port]) + log.info("All stubs are now running [${runningCollaborators.toString()}") + return runningCollaborators + } + + void shutdown() { + stubServer?.stop() + } + + @Override + URL findStubUrl(String groupId, String artifactId) { + if(!groupId) { + return returnStubUrlIfMatches(stubServer.stubConfiguration.artifactId == artifactId) + } + return returnStubUrlIfMatches(stubServer.stubConfiguration.artifactId == artifactId && + stubServer.stubConfiguration.groupId == groupId) + } + + @Override + URL findStubUrl(String ivyNotation) { + String[] splitString = ivyNotation.split(":") + if (splitString.length == 1) { + throw new IllegalArgumentException("$ivyNotation is invalid") + } + return findStubUrl(splitString[0], splitString[1]) + } + + private URL returnStubUrlIfMatches(boolean condition) { + return condition ? stubServer.stubUrl : null + } + + private void startStubServers(StubConfiguration stubConfiguration, StubRepository repository) { + List mappings = repository.getProjectDescriptors() + stubServer = portScanner.tryToExecuteWithFreePort { int availablePort -> + return new StubServer(availablePort, stubConfiguration, mappings).start() + } + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy new file mode 100644 index 0000000000..d62b876a26 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -0,0 +1,55 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import groovy.util.logging.Slf4j +/** + * Factory of StubRunners. Basing on the options and passed collaborators + * downloads the stubs and returns a list of corresponding stub runners. + */ +@Slf4j +@CompileStatic +@PackageScope +class StubRunnerFactory { + + private final StubRunnerOptions stubRunnerOptions + private final Collection collaborators + private final StubDownloader stubDownloader + + StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators) { + this(stubRunnerOptions, collaborators, new StubDownloader()) + } + + protected StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators, + StubDownloader stubDownloader) { + this.stubRunnerOptions = stubRunnerOptions + this.collaborators = collaborators + this.stubDownloader = stubDownloader + } + + Collection createStubsFromServiceConfiguration() { + return collaborators.collect { StubConfiguration stubsConfiguration -> + final File unzipedStubDir = stubDownloader.downloadAndUnpackStubJar(stubRunnerOptions.workOffline, + stubRunnerOptions.stubRepositoryRoot, + stubsConfiguration.groupId, "$stubsConfiguration.artifactId${getStubDefinitionSuffix(stubsConfiguration)}") + return createStubRunner(unzipedStubDir, stubsConfiguration) + }.findAll { it != null } + } + + private String getStubDefinitionSuffix(StubConfiguration stubsConfiguration) { + return stubsConfiguration.hasClassifier() ? "-${stubsConfiguration.classifier}" : "" + } + + private StubRunner createStubRunner(File unzipedStubDir, StubConfiguration stubsConfiguration) { + if (!unzipedStubDir) { + return null + } + return createStubRunner(unzipedStubDir, stubsConfiguration, stubRunnerOptions) + } + + private StubRunner createStubRunner(File unzippedStubsDir, StubConfiguration stubsConfiguration, + StubRunnerOptions stubRunnerOptions) { + return new StubRunner(new Arguments(stubRunnerOptions, unzippedStubsDir.path, stubsConfiguration)) + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy new file mode 100644 index 0000000000..86002bf2db --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy @@ -0,0 +1,74 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.util.StubsParser +import org.kohsuke.args4j.CmdLineException +import org.kohsuke.args4j.CmdLineParser +import org.kohsuke.args4j.Option + +import static org.kohsuke.args4j.OptionHandlerFilter.ALL + +@Slf4j +@CompileStatic +class StubRunnerMain { + + @Option(name = "-sr", aliases = ['--stubRepositoryRoot'], usage = "Location of a Jar containing server where you keep your stubs (e.g. http://nexus.net/content/repositories/repository)", required = true) + private String stubRepositoryRoot + + @Option(name = "-ss", aliases = ['--stubsSuffix'], usage = "Suffix for the jar containing stubs (e.g. 'stubs' if the stub jar would have a 'stubs' classifier for stubs: foobar-stubs ). Defaults to 'stubs'") + private String stubsSuffix = 'stubs' + + @Option(name = "-minp", aliases = ['--minPort'], usage = "Minimal port value to be assigned to the WireMock instance. Defaults to 10000") + private Integer minPortValue = 10000 + + @Option(name = "-maxp", aliases = ['--maxPort'], usage = "Maximum port value to be assigned to the WireMock instance. Defaults to 15000") + private Integer maxPortValue = 15000 + + @Option(name = "-wo", aliases = ['--workOffline'], usage = "Switch to work offline. Defaults to 'false'") + private Boolean workOffline = Boolean.FALSE + + @Option(name = "-s", aliases = ['--stubs'], usage = 'Comma separated list of Ivy representation of jars with stubs. Eg. groupid:artifactid1,groupid2:artifactid2:classifier') + private String stubs + + private final Arguments arguments + + StubRunnerMain(String[] args) { + CmdLineParser parser = new CmdLineParser(this) + try { + parser.parseArgument(args) + this.arguments = new Arguments(new StubRunnerOptions(minPortValue, maxPortValue, stubRepositoryRoot, + workOffline, stubsSuffix)) + } catch (CmdLineException e) { + printErrorMessage(e, parser) + throw e + } + } + + private void printErrorMessage(CmdLineException e, CmdLineParser parser) { + System.err.println(e.getMessage()) + System.err.println("java -jar stub-runner.jar [options...] ") + parser.printUsage(System.err) + System.err.println() + System.err.println("Example: java -jar stub-runner.jar ${parser.printExample(ALL)}") + } + + static void main(String[] args) { + new StubRunnerMain(args).execute() + } + + private void execute() { + try { + log.debug("Launching StubRunner with args: $arguments") + // TODO: Pass StubsToRun either from String or File + Collection collaborators = StubsParser.fromString(stubs, stubsSuffix) + BatchStubRunner stubRunner = new BatchStubRunnerFactory(arguments.stubRunnerOptions, collaborators).buildBatchStubRunner() + RunningStubs runningCollaborators = stubRunner.runStubs() + log.info(runningCollaborators.toString()) + } catch (Exception e) { + log.error("An exception occurred while trying to execute the stubs", e) + throw e + } + } + +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy new file mode 100644 index 0000000000..8e6b3d7cd0 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy @@ -0,0 +1,52 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.ToString + +/** + * Technical options related to running StubRunner + */ +@ToString(includeNames = true) +@CompileStatic +class StubRunnerOptions { + + /** + * min port value of the WireMock instance for the given collaborator + */ + Integer minPortValue = 10000 + + /** + * max port value of the WireMock instance for the given collaborator + */ + Integer maxPortValue = 15000 + + /** + * root URL from where the JAR with stub mappings will be downloaded + */ + String stubRepositoryRoot + + /** + * avoids local repository in dependency resolution + */ + boolean workOffline = false + + /** + * stub definition suffix + */ + String stubsClassifier = "stubs" + + StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, + boolean workOffline, String stubsClassifier) { + this.minPortValue = minPortValue + this.maxPortValue = maxPortValue + this.stubRepositoryRoot = stubRepositoryRoot + this.workOffline = workOffline + this.stubsClassifier = stubsClassifier + } + + StubRunnerOptions(String stubRepositoryRoot) { + this.stubRepositoryRoot = stubRepositoryRoot + } + + StubRunnerOptions() {} +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunning.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunning.groovy new file mode 100644 index 0000000000..15941448b4 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunning.groovy @@ -0,0 +1,9 @@ +package io.codearte.accurest.stubrunner + +interface StubRunning extends Closeable, StubFinder { + /** + * Runs the stubs and returns the {@link RunningStubs} + */ + RunningStubs runStubs() + +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy new file mode 100644 index 0000000000..830a3a22f5 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy @@ -0,0 +1,68 @@ +package io.codearte.accurest.stubrunner + +import com.github.tomakehurst.wiremock.WireMockServer +import com.github.tomakehurst.wiremock.client.WireMock +import com.github.tomakehurst.wiremock.core.WireMockConfiguration +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import groovy.util.logging.Slf4j + +@CompileStatic +@Slf4j +@PackageScope +class StubServer { + private WireMockServer wireMockServer + final StubConfiguration stubConfiguration + final Collection mappings + + StubServer(int port, StubConfiguration stubConfiguration, Collection mappings) { + this.stubConfiguration = stubConfiguration + this.mappings = mappings + this.wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(port)) + } + + StubServer start() { + wireMockServer.start() + log.info("Started stub server for project ${stubConfiguration.toColonSeparatedDependencyNotation()} on port ${wireMockServer.port()}") + registerStubMappings() + return this + } + + void stop() { + wireMockServer.stop() + } + + int getPort() { + return wireMockServer.port() + } + + URL getStubUrl() { + return new URL("http://localhost:$port") + } + + private void registerStubMappings() { + WireMock wireMock = new WireMock('localhost', wireMockServer.port()) + registerDefaultHealthChecks(wireMock) + registerStubs(mappings, wireMock) + } + + private void registerDefaultHealthChecks(WireMock wireMock) { + registerHealthCheck(wireMock, '/ping') + registerHealthCheck(wireMock, '/health') + } + + private void registerStubs(Collection sortedMappings, WireMock wireMock) { + sortedMappings.each { MappingDescriptor mappingDescriptor -> + try { + wireMock.register(mappingDescriptor.mapping) + log.debug("Registered stub mappings from $mappingDescriptor.descriptor") + } catch (Exception e) { + log.warn("Failed to register the stub mapping [$mappingDescriptor]", e) + } + } + } + + private void registerHealthCheck(WireMock wireMock, String url, String body = 'OK') { + wireMock.register(WireMock.get(WireMock.urlEqualTo(url)).willReturn(WireMock.aResponse().withBody(body).withStatus(200))) + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StringUtils.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StringUtils.groovy new file mode 100644 index 0000000000..16b8f35db1 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StringUtils.groovy @@ -0,0 +1,124 @@ +package io.codearte.accurest.stubrunner.util + +/** + * Utils ported from Apache Commons + * + * @author Marcin Grzejszczak + */ +class StringUtils { + public static String EMPTY = "" + private static int INDEX_NOT_FOUND = -1 + + // Empty checks + //----------------------------------------------------------------------- + /** + *

Checks if a String is empty ("") or null.

+ * + *
+	 * StringUtils.isEmpty(null)      = true
+	 * StringUtils.isEmpty("")        = true
+	 * StringUtils.isEmpty(" ")       = false
+	 * StringUtils.isEmpty("bob")     = false
+	 * StringUtils.isEmpty("  bob  ") = false
+	 * 
+ * + *

NOTE: This method changed in Lang version 2.0. + * It no longer trims the String. + * That functionality is available in isBlank().

+ * + * @param str the String to check, may be null + * @return true if the String is empty or null + */ + public static boolean isEmpty(String str) { + return str == null || str.length() == 0; + } + + static boolean isNotEmpty(String string) { + return string != null && !string.empty + } + + static boolean hasText(String string) { + return isNotEmpty(string) && !string.allWhitespace + } + + /** + *

Gets the substring before the last occurrence of a separator. + * The separator is not returned.

+ * + *

A null string input will return null. + * An empty ("") string input will return the empty string. + * An empty or null separator will return the input string.

+ * + *

If nothing is found, the string input is returned.

+ * + *
+	 * StringUtils.substringBeforeLast(null, *)      = null
+	 * StringUtils.substringBeforeLast("", *)        = ""
+	 * StringUtils.substringBeforeLast("abcba", "b") = "abc"
+	 * StringUtils.substringBeforeLast("abc", "c")   = "ab"
+	 * StringUtils.substringBeforeLast("a", "a")     = ""
+	 * StringUtils.substringBeforeLast("a", "z")     = "a"
+	 * StringUtils.substringBeforeLast("a", null)    = "a"
+	 * StringUtils.substringBeforeLast("a", "")      = "a"
+	 * 
+ * + * @param str the String to get a substring from, may be null + * @param separator the String to search for, may be null + * @return the substring before the last occurrence of the separator, + * null if null String input + * @since 2.0 + */ + public static String substringBeforeLast(String str, String separator) { + if (isEmpty(str) || isEmpty(separator)) { + return str; + } + int pos = str.lastIndexOf(separator); + if (pos == INDEX_NOT_FOUND) { + return str; + } + return str.substring(0, pos); + } + + /** + *

Gets the substring after the last occurrence of a separator. + * The separator is not returned.

+ * + *

A null string input will return null. + * An empty ("") string input will return the empty string. + * An empty or null separator will return the empty string if + * the input string is not null.

+ * + *

If nothing is found, the empty string is returned.

+ * + *
+	 * StringUtils.substringAfterLast(null, *)      = null
+	 * StringUtils.substringAfterLast("", *)        = ""
+	 * StringUtils.substringAfterLast(*, "")        = ""
+	 * StringUtils.substringAfterLast(*, null)      = ""
+	 * StringUtils.substringAfterLast("abc", "a")   = "bc"
+	 * StringUtils.substringAfterLast("abcba", "b") = "a"
+	 * StringUtils.substringAfterLast("abc", "c")   = ""
+	 * StringUtils.substringAfterLast("a", "a")     = ""
+	 * StringUtils.substringAfterLast("a", "z")     = ""
+	 * 
+ * + * @param str the String to get a substring from, may be null + * @param separator the String to search for, may be null + * @return the substring after the last occurrence of the separator, + * null if null String input + * @since 2.0 + */ + public static String substringAfterLast(String str, String separator) { + if (isEmpty(str)) { + return str; + } + if (isEmpty(separator)) { + return EMPTY; + } + int pos = str.lastIndexOf(separator); + if (pos == INDEX_NOT_FOUND || pos == (str.length() - separator.length())) { + return EMPTY; + } + return str.substring(pos + separator.length()); + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy new file mode 100644 index 0000000000..9749dec904 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy @@ -0,0 +1,38 @@ +package io.codearte.accurest.stubrunner.util + +import groovy.transform.CompileStatic +import io.codearte.accurest.stubrunner.StubConfiguration + +/** + * Utility to parse string into a list of configuration of stubs + */ +@CompileStatic +class StubsParser { + + /** + * The string is expected to be a map with entry called "stubs" + * that contains a list of Strings in the format + * + *
    + *
  • groupid:artifactid:classifier
  • + *
  • groupid:artifactid
  • + *
+ * + * In the latter case the provided default stub classifier will be passed. + * + * Example: + * + * "a:b,c:d:e" + */ + static Set fromString(String list, String defaultClassifier) { + return list.split(',').findAll { it }.collect { String string -> + new StubConfiguration(string, defaultClassifier) + } as Set + } + + static Set fromString(Collection collection, String defaultClassifier) { + return collection.findAll { it }.collect { String string -> + new StubConfiguration(string, defaultClassifier) + } as Set + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/ZipCategory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/ZipCategory.groovy new file mode 100644 index 0000000000..1877da70d4 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/ZipCategory.groovy @@ -0,0 +1,56 @@ +package io.codearte.accurest.stubrunner.util + +import groovy.transform.CompileStatic + +import java.util.zip.ZipEntry +import java.util.zip.ZipInputStream + +/** + * Based on https://github.com/timyates/groovy-common-extensions. + * + * Category for {@link File} that adds a method that allows you to unzip + * a given file to a specified location + * + */ +@CompileStatic +class ZipCategory { + + /** + * Unzips this file. If the destination + * directory is not provided, it will fall back to this file's parent directory. + * + * @param self + * @param destination (optional), the destination directory where this file's content will be unzipped to. + * @return a {@link Collection} of unzipped {@link File} objects. + */ + static Collection unzipTo(File self, File destination) { + checkUnzipDestination(destination) + // if destination directory is not given, we'll fall back to the parent directory of 'self' + if (destination == null) destination = new File(self.parent) + List unzippedFiles = [] + final ZipInputStream zipInput = new ZipInputStream(new FileInputStream(self)) + zipInput.withStream { + ZipEntry entry + while (entry = zipInput.nextEntry) { + if (!entry.isDirectory()) { + final File file = new File(destination, entry.name) + file.parentFile?.mkdirs() + FileOutputStream output = new FileOutputStream(file) + output.withStream { + output << zipInput + } + unzippedFiles << file + } else { + final File dir = new File(destination, entry.name) + dir.mkdirs() + unzippedFiles << dir + } + } + } + return unzippedFiles + } + + private static void checkUnzipDestination(File file) { + if (file && !file.isDirectory()) throw new IllegalArgumentException("'destination' has to be a directory.") + } +} diff --git a/stub-runner/stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml b/stub-runner/stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml new file mode 100644 index 0000000000..2054715610 --- /dev/null +++ b/stub-runner/stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy new file mode 100644 index 0000000000..7e7aee8b69 --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy @@ -0,0 +1,45 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +class AvailablePortScannerSpec extends Specification { + + private static final int MIN_PORT = 8989 + private static final int MAX_PORT = 8990 + private static final int MAX_RETRY_COUNT_FOR_NEGATIVE_SCENARIOS = 2 + + def 'should execute given closure with the next available port number'() { + given: + AvailablePortScanner portScanner = new AvailablePortScanner(MIN_PORT, MAX_PORT) + when: + int usedPort = portScanner.tryToExecuteWithFreePort { int port -> port } + then: + noExceptionThrown() + usedPort == MIN_PORT + } + + def 'should throw exception when improper range has been provided'() { + when: + new AvailablePortScanner(minPort, maxPort, MAX_RETRY_COUNT_FOR_NEGATIVE_SCENARIOS) + then: + def ex = thrown(AvailablePortScanner.InvalidPortRange) + ex.message == "Invalid bounds exceptions, min port [$minPort] is greater or equal to max port [$maxPort]" + where: + minPort | maxPort + MIN_PORT | MIN_PORT + MAX_PORT | MIN_PORT + + } + + def 'should throw exception when there is no available port'() { + given: + AvailablePortScanner portScanner = new AvailablePortScanner(MIN_PORT, MAX_PORT, MAX_RETRY_COUNT_FOR_NEGATIVE_SCENARIOS) + when: + portScanner.tryToExecuteWithFreePort { + throw new BindException('Bind exception from closure') + } + then: + def ex = thrown(AvailablePortScanner.NoPortAvailableException) + ex.message == "Could not find available port in range $MIN_PORT:$MAX_PORT" + } +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy new file mode 100644 index 0000000000..71935f62f9 --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy @@ -0,0 +1,32 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +class BatchStubRunnerSpec extends Specification { + + static final String KNOWN_STUB_PATH = 'group:knownArtifact' + static final String UNKNOWN_STUB_PATH = 'group:unknownArtifact' + static final URL KNOWN_STUB_URL = new URL('http://localhost:8080') + + def 'should provide stub URL from enclosed stub runner'() { + given: + BatchStubRunner batchStubRunner = new BatchStubRunner(runners()) + expect: + batchStubRunner.findStubUrl(KNOWN_STUB_PATH) == KNOWN_STUB_URL + } + + def 'should return empty optional for unknown stub path'() { + given: + BatchStubRunner batchStubRunner = new BatchStubRunner(runners()) + expect: + !batchStubRunner.findStubUrl(UNKNOWN_STUB_PATH) + } + + Collection runners() { + StubRunner runner = Mock(StubRunner) + runner.findStubUrl("group", "knownArtifact") >> KNOWN_STUB_URL + runner.findStubUrl("group", "unknownArtifact") >> null + return [runner] + } + +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy new file mode 100644 index 0000000000..394cabf2d8 --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy @@ -0,0 +1,23 @@ +package io.codearte.accurest.stubrunner + +import com.github.tomakehurst.wiremock.http.RequestMethod +import spock.lang.Specification + +class MappingDescriptorSpec extends Specification { + public static + final File MAPPING_DESCRIPTOR = new File('src/test/resources/repository/mappings/com/ofg/ping/ping.json') + + def 'should describe stub mapping'() { + given: + MappingDescriptor mappingDescriptor = new MappingDescriptor(MAPPING_DESCRIPTOR) + + expect: + with(mappingDescriptor.mapping) { + request.method == RequestMethod.GET + request.url == '/ping' + response.status == 200 + response.body == 'pong' + response.headers.contentTypeHeader.mimeTypePart() == 'text/plain' + } + } +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy new file mode 100644 index 0000000000..337508fce0 --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy @@ -0,0 +1,34 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +class StubRepositorySpec extends Specification { + public static + final File REPOSITORY_LOCATION = new File('src/test/resources/repository') + + def 'should retrieve all descriptors for given project'() { + given: + StubRepository repository = new StubRepository(REPOSITORY_LOCATION) + int expectedDescriptorsSize = 8 + when: + List descriptors = repository.getProjectDescriptors() + then: + descriptors.size() == expectedDescriptorsSize + } + + def 'should return empty list if files are missing'() { + given: + StubRepository repository = new StubRepository(new File('src/test/resources/emptyrepo')) + when: + List descriptors = repository.getProjectDescriptors() + then: + descriptors.empty + } + + def 'should throw an exception if directory with mappings is missing'() { + when: + new StubRepository(new File('src/test/resources/nonexistingrepo')) + then: + thrown(FileNotFoundException) + } +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy new file mode 100644 index 0000000000..7b086f7458 --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy @@ -0,0 +1,40 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +class StubRunnerExecutorSpec extends Specification { + + static final URL EXPECTED_STUB_URL = new URL('http://localhost:8999') + static final int MIN_PORT = 8999 + static final int MAX_PORT = 9000 + + private AvailablePortScanner portScanner + private StubRepository repository + private StubConfiguration stub = new StubConfiguration("group:artifact", "stubs") + + def setup() { + portScanner = new AvailablePortScanner(MIN_PORT, MAX_PORT) + repository = new StubRepository(new File('src/test/resources/repository')) + } + + def 'should provide URL for given relative path of stub'() { + given: + StubRunnerExecutor executor = new StubRunnerExecutor(portScanner) + when: + executor.runStubs(repository, stub) + then: + executor.findStubUrl("group", "artifact") == EXPECTED_STUB_URL + cleanup: + executor.shutdown() + } + + def 'should provide no URL for unknown dependency path'() { + given: + StubRunnerExecutor executor = new StubRunnerExecutor(portScanner) + when: + executor.runStubs(repository, stub) + then: + !executor.findStubUrl("unkowngroup", "unknownartifact") + } + +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy new file mode 100644 index 0000000000..d7cf552c8c --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy @@ -0,0 +1,31 @@ +package io.codearte.accurest.stubrunner + +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification + +class StubRunnerFactorySpec extends Specification { + + @Rule + TemporaryFolder folder = new TemporaryFolder() + + Collection collaborators = [new StubConfiguration("a:b"), new StubConfiguration("c:d")] + StubDownloader downloader = Mock(StubDownloader) + StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(stubRepositoryRoot: 'http://sth.net') + StubRunnerFactory factory = new StubRunnerFactory(stubRunnerOptions, collaborators, downloader) + + def "Should download stub definitions many times"() { + given: + folder.newFolder("mappings") + 2 * downloader.downloadAndUnpackStubJar(_, _, _, _) >> folder.root + stubRunnerOptions.stubRepositoryRoot = folder.root.absolutePath + when: + Collection stubRunners = collectOnlyPresentValues(factory.createStubsFromServiceConfiguration()) + then: + stubRunners.size() == 2 + } + + private List collectOnlyPresentValues(Collection stubRunners) { + return stubRunners.findAll { it != null } + } +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy new file mode 100644 index 0000000000..1d63e28bfd --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy @@ -0,0 +1,39 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +class StubRunnerSpec extends Specification { + + private static final int MIN_PORT = 8111 + private static final int MAX_PORT = 8112 + private static final URL EXPECTED_STUB_URL = new URL("http://localhost:$MIN_PORT") + + def 'should provide stub URL for provided groupid and artifactId'() { + given: + StubRunner runner = new StubRunner(argumentsWithProjectDefinition()) + when: + runner.runStubs() + then: + runner.findStubUrl("groupId", "artifactId") == EXPECTED_STUB_URL + cleanup: + runner.close() + } + + def 'should provide stub URL if only artifactId was passed'() { + given: + StubRunner runner = new StubRunner(argumentsWithProjectDefinition()) + when: + runner.runStubs() + then: + runner.findStubUrl(null, "artifactId") == EXPECTED_STUB_URL + cleanup: + runner.close() + } + + Arguments argumentsWithProjectDefinition() { + StubConfiguration stubConfiguration = new StubConfiguration("groupId", "artifactId", "classifier") + StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue: MIN_PORT, maxPortValue: MAX_PORT) + return new Arguments(stubRunnerOptions, 'src/test/resources/repository', stubConfiguration) + } + +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy new file mode 100644 index 0000000000..14d71ac9e3 --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy @@ -0,0 +1,35 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +class StubServerSpec extends Specification { + static final int STUB_SERVER_PORT = 12180 + static final URL EXPECTED_URL = new URL("http://localhost:$STUB_SERVER_PORT") + + File repository = new File('src/test/resources/repository/mappings/com/ofg/bye') + StubConfiguration stubConfiguration = new StubConfiguration("a:b") + + def 'should register stub mappings upon server start'() { + given: + List mappingDescriptors = new StubRepository(repository).getProjectDescriptors() + StubServer pingStubServer = new StubServer(STUB_SERVER_PORT, stubConfiguration, mappingDescriptors) + when: + pingStubServer.start() + then: + "http://localhost:$pingStubServer.port/bye".toURL().text == 'Goodbye world!' + cleanup: + pingStubServer.stop() + } + + def 'should provide stub server URL'() { + given: + List mappingDescriptors = new StubRepository(repository).getProjectDescriptors() + StubServer pingStubServer = new StubServer(STUB_SERVER_PORT, stubConfiguration, mappingDescriptors) + when: + pingStubServer.start() + then: + pingStubServer.stubUrl == EXPECTED_URL + cleanup: + pingStubServer.stop() + } +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/util/ZipCategorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/util/ZipCategorySpec.groovy new file mode 100644 index 0000000000..2a3f5e16ef --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/util/ZipCategorySpec.groovy @@ -0,0 +1,24 @@ +package io.codearte.accurest.stubrunner.util + +import groovy.util.logging.Slf4j +import spock.lang.Specification + +@Slf4j +class ZipCategorySpec extends Specification { + + def 'should unzip a file to the specified location'() { + given: + File zipFile = new File(ZipCategorySpec.classLoader.getResource('file.zip').toURI()) + File tempDir = File.createTempDir() + tempDir.deleteOnExit() + when: + use(ZipCategory) { + zipFile.unzipTo(tempDir) + } + then: + tempDir.listFiles().find { + it.name == 'file.txt' + }?.text?.trim() == 'test' + } + +} diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/bar/bar.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/bar/bar.json new file mode 100644 index 0000000000..0b71cbf35e --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/bar/bar.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/bar" + }, + "response": { + "status": 200, + "body": "bar", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/bar/foobar.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/bar/foobar.json new file mode 100644 index 0000000000..e231b2c0c5 --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/bar/foobar.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/foobar" + }, + "response": { + "status": 200, + "body": "foobar", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/foo.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/foo.json new file mode 100644 index 0000000000..209061ef5e --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/foo.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/foo" + }, + "response": { + "status": 200, + "body": "foo", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json new file mode 100644 index 0000000000..bfc64f392c --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json @@ -0,0 +1,5 @@ +{ + "pl": [ + "com/ofg/bar" + ] +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json new file mode 100644 index 0000000000..fe635a1b3a --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json @@ -0,0 +1,5 @@ +{ + "pl": [ + "com/ofg/foo/bar" + ] +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json new file mode 100644 index 0000000000..7ecd1e1ed6 --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json @@ -0,0 +1,5 @@ +{ + "pl": [ + "com/ofg/foo" + ] +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/emptyrepo/.gitkeep b/stub-runner/stub-runner/src/test/resources/emptyrepo/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/stub-runner/stub-runner/src/test/resources/file.zip b/stub-runner/stub-runner/src/test/resources/file.zip new file mode 100644 index 0000000000000000000000000000000000000000..3da3a912405f9967ebedebe02f41ce44b66ddd5e GIT binary patch literal 171 zcmWIWW@h1H0D)76LW?TkIfXruL1mY!)AQr+{R*11^Mh1AZvVqhw0-+y}b_a17 E0OX(`8~^|S literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner/src/test/resources/logback.xml b/stub-runner/stub-runner/src/test/resources/logback.xml new file mode 100644 index 0000000000..0cfb35f4cd --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/admin/admin.json b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/admin/admin.json new file mode 100644 index 0000000000..f730b7e3cf --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/admin/admin.json @@ -0,0 +1,9 @@ +{ + "request": { + "method": "GET", + "url": "/admin" + }, + "response": { + "status": 401 + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/bye.json b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/bye.json new file mode 100644 index 0000000000..1a65830d4a --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/bye.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/bye" + }, + "response": { + "status": 200, + "body": "Goodbye world!", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/README.md b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/README.md new file mode 100644 index 0000000000..484f8efe77 --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/README.md @@ -0,0 +1 @@ +### Hello service stub \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/admin/admin.json b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/admin/admin.json new file mode 100644 index 0000000000..f730b7e3cf --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/admin/admin.json @@ -0,0 +1,9 @@ +{ + "request": { + "method": "GET", + "url": "/admin" + }, + "response": { + "status": 401 + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/hello.json b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/hello.json new file mode 100644 index 0000000000..3cd9f7374b --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/hello.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/hello" + }, + "response": { + "status": 200, + "body": "Hello world!", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/ping/ping.json b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/ping/ping.json new file mode 100644 index 0000000000..db01229c52 --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/ping/ping.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/ping" + }, + "response": { + "status": 200, + "body": "pong", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/lv/com/ofg/bye/lv_bye.json b/stub-runner/stub-runner/src/test/resources/repository/mappings/lv/com/ofg/bye/lv_bye.json new file mode 100644 index 0000000000..a062cd4674 --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/lv/com/ofg/bye/lv_bye.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/lv/bye" + }, + "response": { + "status": 200, + "body": "Another goodbye world!", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_bye.json b/stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_bye.json new file mode 100644 index 0000000000..b7c5e4ebc9 --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_bye.json @@ -0,0 +1,13 @@ +{ + "request": { + "method": "GET", + "url": "/pl/bye" + }, + "response": { + "status": 200, + "body": "pl-bye", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_overridden_bye.json b/stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_overridden_bye.json new file mode 100644 index 0000000000..9c54c98914 --- /dev/null +++ b/stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_overridden_bye.json @@ -0,0 +1,14 @@ +{ + + "request": { + "method": "GET", + "url": "/bye" + }, + "response": { + "status": 200, + "body": "overridden-bye", + "headers": { + "Content-Type": "text/plain" + } + } +} \ No newline at end of file From efcc2b73fa70cbb7fbc7747f0918bab1db2920ea Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 26 Mar 2016 16:53:40 +0100 Subject: [PATCH 321/719] Updated stub-runner docs --- stub-runner/stub-runner-junit/README.md | 2 +- stub-runner/stub-runner/README.md | 17 +++-------------- 2 files changed, 4 insertions(+), 15 deletions(-) diff --git a/stub-runner/stub-runner-junit/README.md b/stub-runner/stub-runner-junit/README.md index 32c824c182..761c3f431f 100644 --- a/stub-runner/stub-runner-junit/README.md +++ b/stub-runner/stub-runner-junit/README.md @@ -23,7 +23,7 @@ class AccurestRuleSpec extends Specification { } ``` -You can set the default value of the Maven repository by means of system property: +You can set the default value of the Maven repository by means of a system property: ``` -Dstubrunner.stubs.repository.root=http://your.maven.repo.com diff --git a/stub-runner/stub-runner/README.md b/stub-runner/stub-runner/README.md index c52bdf7b9e..78a8ce5829 100644 --- a/stub-runner/stub-runner/README.md +++ b/stub-runner/stub-runner/README.md @@ -44,22 +44,13 @@ You can configure the stub runner by either passing the full arguments list with or each parameter separately with a `-P` prefix and without the hyphen `-` in the name of the param ``` -./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -``` - -### Defining collaborators' stubs - -You can define global stubs under folder corresponding to groupid/artifactid of your collaborator - -``` -com/ofg/foo +./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h ``` By default stub definitions are stored in `mappings` directory inside stub repository. -#### Stubbing collaborators +#### Stubs -For each collaborator defined in project metadata all collaborator mappings (stubs) available in repository are loaded. Stubs are defined in JSON documents, whose syntax is defined in [WireMock documentation](http://wiremock.org/stubbing.html) Example: @@ -79,9 +70,7 @@ Example: } ``` -Stub definitions are stored in stub repository under the same path as collaborator fully qualified name. -Paths (as long it's inside the directory mentioned above) and names of documents containing stub definitions not play any -other role than describing stubs' role / purpose. +In the provided JAR file we're harvesting all JSON files and try to put them inside running WireMock instance. #### Viewing registered mappings From bee0e4437107e8d139b1df63dce3e2221f8f60a0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 26 Mar 2016 16:57:36 +0100 Subject: [PATCH 322/719] Updated stub-runner-junit docs --- stub-runner/stub-runner-junit/README.md | 19 +++++++++++-------- stub-runner/stub-runner/README.md | 1 - 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/stub-runner/stub-runner-junit/README.md b/stub-runner/stub-runner-junit/README.md index 761c3f431f..985bd8d743 100644 --- a/stub-runner/stub-runner-junit/README.md +++ b/stub-runner/stub-runner-junit/README.md @@ -14,12 +14,15 @@ class AccurestRuleSpec extends Specification { .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") def 'should start WireMock servers'() { - expect: - rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - rule.findStubUrl('loanIssuance') != null - rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null - } + expect: 'WireMocks are running' + rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null + rule.findStubUrl('loanIssuance') != null + rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: 'Stubs were registered' + "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + } } ``` @@ -36,7 +39,7 @@ The list of configurable properties contains: | stubrunner.port.range.min | 10000 | Minimal value of a port for a WireMock server | | stubrunner.port.range.max | 15000 | Maximum value of a port for a WireMock server | | stubrunner.stubs.repository.root | | Address to your M2 repo (will point to local M2 repo if none is provided) | -| stubrunner.stubs.repository.root | | Address to your M2 repo (will point to local M2 repo if none is provided) | -| stubrunner.work-offline | false | Should try to connect to any repo to download stubs (especially good if there's no internet) | +| stubrunner.stubs.classifier | stubs | Default classifier for the JARs containing stubs | +| stubrunner.work-offline | false | Should try to connect to any repo to download stubs (useful if there's no internet) | | stubrunner.stubs | | Default comma separated list of stubs to download | diff --git a/stub-runner/stub-runner/README.md b/stub-runner/stub-runner/README.md index 78a8ce5829..bd148045da 100644 --- a/stub-runner/stub-runner/README.md +++ b/stub-runner/stub-runner/README.md @@ -47,7 +47,6 @@ or each parameter separately with a `-P` prefix and without the hyphen `-` in th ./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h ``` -By default stub definitions are stored in `mappings` directory inside stub repository. #### Stubs From dc7c350e5a06bc52abac9c92f5c4bc21779424d5 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 25 Mar 2016 22:42:47 +0100 Subject: [PATCH 323/719] generating wiremock stubs from accurest contracts --- pom.xml | 100 ++++++++++++++++++ .../accurest/maven/GenerateStubsMojo.java | 55 ++++++++++ .../accurest/maven/PluginUnitTest.java | 35 ++++++ src/test/projects/basic/pom.xml | 19 ++++ .../src/test/resources/stubs/Sample.groovy | 18 ++++ src/test/projects/example/pom.xml | 20 ++++ 6 files changed, 247 insertions(+) create mode 100644 src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java create mode 100644 src/test/java/io/codearte/accurest/maven/PluginUnitTest.java create mode 100644 src/test/projects/basic/pom.xml create mode 100644 src/test/projects/basic/src/test/resources/stubs/Sample.groovy create mode 100644 src/test/projects/example/pom.xml diff --git a/pom.xml b/pom.xml index 1ca7979efb..5417aad6a9 100644 --- a/pom.xml +++ b/pom.xml @@ -8,5 +8,105 @@ accurest-maven-plugin 1.0-SNAPSHOT + takari-maven-plugin + + 3.3.3 + + + + 3.2.5 + 3.4 + + + + + io.codearte.accurest + accurest-core + 1.0.1 + + + io.codearte.accurest + accurest-converters + 1.0.1 + + + ch.qos.logback + logback-classic + 1.1.6 + test + + + + + org.codehaus.groovy + groovy-all + 2.4.6 + + + + org.apache.maven + maven-core + ${mavenVersion} + test + + + org.apache.maven + maven-compat + ${mavenVersion} + test + + + javax.inject + javax.inject + 1 + provided + + + org.apache.maven + maven-plugin-api + ${mavenVersion} + provided + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${mavenPluginPluginVersion} + provided + + + + io.takari.maven.plugins + takari-plugin-testing + 2.8.0 + test + + + + junit + junit + 4.12 + test + + + + + + + + + + io.takari.maven.plugins + takari-lifecycle-plugin + 1.11.12 + true + + none + + + + + + +
\ No newline at end of file diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java new file mode 100644 index 0000000000..499311cf65 --- /dev/null +++ b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -0,0 +1,55 @@ +package io.codearte.accurest.maven; + +import java.io.File; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import io.codearte.accurest.config.AccurestConfigProperties; +import io.codearte.accurest.wiremock.DslToWireMockClientConverter; +import io.codearte.accurest.wiremock.RecursiveFilesConverter; + +@Mojo(name = "generateStubs", defaultPhase = LifecyclePhase.PROCESS_RESOURCES) +public class GenerateStubsMojo extends AbstractMojo { + + @Parameter(defaultValue = "${basedir}") + protected File baseDir; + + @Parameter(defaultValue = "${project.build.directory}") + protected File projectBuildDirectory; + + @Parameter(property = "mappingsDir", defaultValue = "mappings", required = false) + private String mappingsDir = "mappings"; + + public void execute() throws MojoExecutionException, MojoFailureException { + getLog().info(""); + getLog().info("*** Accurest Maven Plugin ***"); + getLog().info(""); + + File stubsOutputDir = new File(projectBuildDirectory, mappingsDir); + + getLog().info("baseDir = " + baseDir); + getLog().info("projectBuildDirectory = " + projectBuildDirectory); + getLog().info("mappings = " + mappingsDir); + + AccurestConfigProperties configProperties = new AccurestConfigProperties(); + + File contractsDslDir = new File(baseDir, "/src/test/resources/stubs"); + + configProperties.setContractsDslDir(contractsDslDir); + configProperties.setBasePackageForTests("io.codearte.accurest.tests"); + configProperties.setStubsOutputDir(stubsOutputDir); + getLog().info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion"); + getLog().info(String.format("From '%s' to '%s'", contractsDslDir, stubsOutputDir)); + + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), + configProperties); + converter.processFiles(); + + } + +} diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java new file mode 100644 index 0000000000..1d402cf58e --- /dev/null +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -0,0 +1,35 @@ +package io.codearte.accurest.maven; + +import static io.takari.maven.testing.TestResources.assertFilesPresent; + +import java.io.File; + +import org.junit.Rule; +import org.junit.Test; + +import io.takari.maven.testing.TestMavenRuntime; +import io.takari.maven.testing.TestResources; + +public class PluginUnitTest { + + @Rule + public final TestResources resources = new TestResources(); + + @Rule + public final TestMavenRuntime maven = new TestMavenRuntime(); + + @Test + public void shouldGenerateWarlockStubsInDefaultLocation() throws Exception { + File basedir = resources.getBasedir("basic"); + maven.executeMojo(basedir, "generateStubs"); + assertFilesPresent(basedir, "target/mappings/Sample.json"); + } + + @Test + public void shouldGenerateWarlockStubsInSelectedLocation() throws Exception { + File basedir = resources.getBasedir("basic"); + maven.executeMojo(basedir, "generateStubs", TestMavenRuntime.newParameter("mappingsDir", "foo")); + assertFilesPresent(basedir, "target/foo/Sample.json"); + } + +} diff --git a/src/test/projects/basic/pom.xml b/src/test/projects/basic/pom.xml new file mode 100644 index 0000000000..fed7b7d67e --- /dev/null +++ b/src/test/projects/basic/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + io.codearte.accurest.sample + sample-project + 0.1 + + + + + io.codearte.accurest + accurest-maven-plugin + + + + + \ No newline at end of file diff --git a/src/test/projects/basic/src/test/resources/stubs/Sample.groovy b/src/test/projects/basic/src/test/resources/stubs/Sample.groovy new file mode 100644 index 0000000000..673ab7bd8d --- /dev/null +++ b/src/test/projects/basic/src/test/resources/stubs/Sample.groovy @@ -0,0 +1,18 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'POST' + url('/users') { + + } + headers { + header 'Content-Type': 'application/json' + } + body '''{ "login" : "john", "name": "John The Contract" }''' + } + response { + status 200 + headers { + header 'Location': '/users/john' + } + } +} \ No newline at end of file diff --git a/src/test/projects/example/pom.xml b/src/test/projects/example/pom.xml new file mode 100644 index 0000000000..faa1b92be3 --- /dev/null +++ b/src/test/projects/example/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + + io.codearte.accurest.sample + sample-project + 0.1 + + + + + io.codearte.accurest + accurest-maven-plugin + ${it-plugin.version} + + + + + \ No newline at end of file From 872940d0a97d5a8c199844bd874ea6d6eed80baa Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 26 Mar 2016 19:07:53 +0100 Subject: [PATCH 324/719] integration testing --- pom.xml | 14 ++++---- .../accurest/maven/PluginIntegrationTest.java | 36 +++++++++++++++++++ .../{example => basic-with-execution}/pom.xml | 9 ++++- .../src/test/resources/stubs/Sample.groovy | 18 ++++++++++ 4 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java rename src/test/projects/{example => basic-with-execution}/pom.xml (78%) create mode 100644 src/test/projects/basic-with-execution/src/test/resources/stubs/Sample.groovy diff --git a/pom.xml b/pom.xml index 5417aad6a9..a8473b110f 100644 --- a/pom.xml +++ b/pom.xml @@ -56,12 +56,7 @@ ${mavenVersion} test - - javax.inject - javax.inject - 1 - provided - + org.apache.maven maven-plugin-api @@ -81,6 +76,13 @@ 2.8.0 test + + io.takari.maven.plugins + takari-plugin-integration-testing + 2.8.0 + pom + test + junit diff --git a/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java new file mode 100644 index 0000000000..839ddb36a6 --- /dev/null +++ b/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java @@ -0,0 +1,36 @@ +package io.codearte.accurest.maven; + +import java.io.File; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import io.takari.maven.testing.TestResources; +import io.takari.maven.testing.executor.MavenRuntime; +import io.takari.maven.testing.executor.MavenVersions; +import io.takari.maven.testing.executor.junit.MavenJUnitTestRunner; + +@RunWith(MavenJUnitTestRunner.class) +@MavenVersions({ "3.3.3" }) +public class PluginIntegrationTest { + + @Rule + public final TestResources resources = new TestResources(); + + private final MavenRuntime maven; + + public PluginIntegrationTest(MavenRuntime.MavenRuntimeBuilder mavenBuilder) throws Exception { + this.maven = mavenBuilder.withCliOptions("-B", "-U").build(); + } + + @Test + public void test() throws Exception { + File basedir = resources.getBasedir("basic-with-execution"); + maven.forProject(basedir) + .withCliOption("-X") + .execute("package") + .assertErrorFreeLog() + .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion"); + } +} \ No newline at end of file diff --git a/src/test/projects/example/pom.xml b/src/test/projects/basic-with-execution/pom.xml similarity index 78% rename from src/test/projects/example/pom.xml rename to src/test/projects/basic-with-execution/pom.xml index faa1b92be3..3cbb096806 100644 --- a/src/test/projects/example/pom.xml +++ b/src/test/projects/basic-with-execution/pom.xml @@ -13,8 +13,15 @@ io.codearte.accurest accurest-maven-plugin ${it-plugin.version} + true + + + + generateStubs + + + -
\ No newline at end of file diff --git a/src/test/projects/basic-with-execution/src/test/resources/stubs/Sample.groovy b/src/test/projects/basic-with-execution/src/test/resources/stubs/Sample.groovy new file mode 100644 index 0000000000..673ab7bd8d --- /dev/null +++ b/src/test/projects/basic-with-execution/src/test/resources/stubs/Sample.groovy @@ -0,0 +1,18 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'POST' + url('/users') { + + } + headers { + header 'Content-Type': 'application/json' + } + body '''{ "login" : "john", "name": "John The Contract" }''' + } + response { + status 200 + headers { + header 'Location': '/users/john' + } + } +} \ No newline at end of file From 940f79185bd796f9189adea7201aa08308dd3c77 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 26 Mar 2016 21:04:59 +0100 Subject: [PATCH 325/719] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 14f8d62652..2e6e565f5f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,4 +18,4 @@ cache: - $HOME/.m2 install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --info --continue --parallel +script: ./gradlew clean check funcTest --stacktrace --info --continue From dd2d203742a1fb864902d60da0b3478ddccbb701 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 26 Mar 2016 20:48:02 +0100 Subject: [PATCH 326/719] generating specs --- .../accurest/maven/GenerateSpecsMojo.java | 47 ++++++++++++ .../accurest/maven/GenerateStubsMojo.java | 25 ++----- .../accurest/maven/PluginIntegrationTest.java | 11 ++- .../accurest/maven/PluginUnitTest.java | 11 ++- .../projects/basic-with-execution/pom.xml | 71 +++++++++++++++++++ 5 files changed, 141 insertions(+), 24 deletions(-) create mode 100644 src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java new file mode 100644 index 0000000000..aba7bb50b2 --- /dev/null +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -0,0 +1,47 @@ +package io.codearte.accurest.maven; + +import static java.lang.String.format; + +import java.io.File; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import io.codearte.accurest.AccurestException; +import io.codearte.accurest.TestGenerator; +import io.codearte.accurest.config.AccurestConfigProperties; + +@Mojo(name = "generateSpecs", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) +public class GenerateSpecsMojo extends AbstractMojo { + + @Parameter(defaultValue = "${basedir}") + protected File baseDir; + + @Parameter(defaultValue = "${project.build.directory}") + protected File projectBuildDirectory; + + public void execute() throws MojoExecutionException, MojoFailureException { + AccurestConfigProperties config = new AccurestConfigProperties(); + + config.setContractsDslDir(new File(baseDir, "/src/test/resources/stubs")); + config.setBasePackageForTests("io.codearte.accurest.tests"); + config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, "/generated-sources/accurest")); + + getLog().info("Accurest Plugin: Invoking test sources generation"); + getLog().info(format("Registering %s as test source directory", config.getGeneratedTestSourcesDir())); + + try { + TestGenerator generator = new TestGenerator(config); + int generatedClasses = generator.generate(); + getLog().info(String.format("Generated %s test classes.", generatedClasses)); + } catch (AccurestException e) { + throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e); + } + + } + +} diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index 499311cf65..5ba6ed76fb 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -26,30 +26,15 @@ public class GenerateStubsMojo extends AbstractMojo { private String mappingsDir = "mappings"; public void execute() throws MojoExecutionException, MojoFailureException { - getLog().info(""); - getLog().info("*** Accurest Maven Plugin ***"); - getLog().info(""); + AccurestConfigProperties config = new AccurestConfigProperties(); + config.setContractsDslDir(new File(baseDir, "/src/test/resources/stubs")); + config.setStubsOutputDir(new File(projectBuildDirectory, mappingsDir)); - File stubsOutputDir = new File(projectBuildDirectory, mappingsDir); - - getLog().info("baseDir = " + baseDir); - getLog().info("projectBuildDirectory = " + projectBuildDirectory); - getLog().info("mappings = " + mappingsDir); - - AccurestConfigProperties configProperties = new AccurestConfigProperties(); - - File contractsDslDir = new File(baseDir, "/src/test/resources/stubs"); - - configProperties.setContractsDslDir(contractsDslDir); - configProperties.setBasePackageForTests("io.codearte.accurest.tests"); - configProperties.setStubsOutputDir(stubsOutputDir); getLog().info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion"); - getLog().info(String.format("From '%s' to '%s'", contractsDslDir, stubsOutputDir)); + getLog().info(String.format("From '%s' to '%s'", config.getContractsDslDir(), config.getStubsOutputDir())); - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), - configProperties); + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); converter.processFiles(); - } } diff --git a/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java index 839ddb36a6..a786df3778 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java @@ -25,12 +25,19 @@ public class PluginIntegrationTest { } @Test - public void test() throws Exception { + public void shouldCreateStubs() throws Exception { File basedir = resources.getBasedir("basic-with-execution"); maven.forProject(basedir) .withCliOption("-X") .execute("package") - .assertErrorFreeLog() .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion"); } + + @Test + public void shouldCreateSpecs() throws Exception { + File basedir = resources.getBasedir("basic-with-execution"); + maven.forProject(basedir) + .execute("package") + .assertLogText("Accurest Plugin: Invoking test sources generation"); + } } \ No newline at end of file diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 1d402cf58e..d1e0bf696c 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -19,17 +19,24 @@ public class PluginUnitTest { public final TestMavenRuntime maven = new TestMavenRuntime(); @Test - public void shouldGenerateWarlockStubsInDefaultLocation() throws Exception { + public void shouldGenerateWiremockStubsInDefaultcLocation() throws Exception { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "generateStubs"); assertFilesPresent(basedir, "target/mappings/Sample.json"); } @Test - public void shouldGenerateWarlockStubsInSelectedLocation() throws Exception { + public void shouldGenerateWiremockStubsInSelectedLocation() throws Exception { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "generateStubs", TestMavenRuntime.newParameter("mappingsDir", "foo")); assertFilesPresent(basedir, "target/foo/Sample.json"); } + @Test + public void shouldGenerateContractSpecificationInDefaultLocation() throws Exception { + File basedir = resources.getBasedir("basic"); + maven.executeMojo(basedir, "generateSpecs"); + assertFilesPresent(basedir, + "target/generated-sources/accurest/io/codearte/accurest/tests/AccurestSpec.groovy"); + } } diff --git a/src/test/projects/basic-with-execution/pom.xml b/src/test/projects/basic-with-execution/pom.xml index 3cbb096806..2238e43e53 100644 --- a/src/test/projects/basic-with-execution/pom.xml +++ b/src/test/projects/basic-with-execution/pom.xml @@ -7,6 +7,45 @@ sample-project 0.1 + + + + org.spockframework + spock-core + 1.0-groovy-2.4 + test + + + com.jayway.restassured + rest-assured + 2.9.0 + test + + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + test + + + com.github.tomakehurst + wiremock + 2.0.4-beta + test + + + com.toomuchcoding.jsonassert + jsonassert + 0.2.2 + test + + + org.assertj + assertj-core + 2.3.0 + + + @@ -18,10 +57,42 @@ generateStubs + generateSpecs + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.5 + + + + testCompile + + + + + + + ${project.build.directory}/generated-sources/accurest + + **/*.groovy + + + + + + + maven-surefire-plugin + 2.19 + + + **/*Spec.java + + +
\ No newline at end of file From 0c69a9dd2f10a314a11b1cdb2eecd71b1e64f85d Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 26 Mar 2016 21:35:11 +0100 Subject: [PATCH 327/719] pom cleanup --- pom.xml | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index a8473b110f..b1b4c79a65 100644 --- a/pom.xml +++ b/pom.xml @@ -11,7 +11,7 @@ takari-maven-plugin - 3.3.3 + 3.2.5 @@ -37,7 +37,6 @@ test - org.codehaus.groovy groovy-all @@ -83,19 +82,14 @@ pom test - junit junit 4.12 test - - - - io.takari.maven.plugins @@ -105,10 +99,7 @@ none - - -
\ No newline at end of file From 14742aed277b7edbe48e1baf6d08d04cd7d5b5ce Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 27 Mar 2016 01:47:09 +0100 Subject: [PATCH 328/719] Updated the tests, extended StubFinding contract --- .travis.yml | 2 +- stub-runner/stub-runner-junit/README.md | 4 ++ .../stubrunner/junit/AccurestRule.java | 6 ++ .../stubrunner/junit/AccurestRuleSpec.groovy | 11 +++- .../junit/AccurestRuleSysPropsSpec.groovy | 5 +- stub-runner/stub-runner-spring/README.md | 20 ++++--- .../spring/StubRunnerConfiguration.java | 11 ++-- .../spring/StubRunnerConfigurationSpec.groovy | 8 ++- .../stubrunner/BatchStubRunner.groovy | 5 ++ .../accurest/stubrunner/RunningStubs.groovy | 58 ++++++++++++++++++- .../accurest/stubrunner/StubFinder.groovy | 5 ++ .../accurest/stubrunner/StubRunner.groovy | 5 ++ .../stubrunner/StubRunnerExecutor.groovy | 5 ++ .../stubrunner/StubRunnerExecutorSpec.groovy | 4 ++ 14 files changed, 128 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2e6e565f5f..14f8d62652 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,4 +18,4 @@ cache: - $HOME/.m2 install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --info --continue +script: ./gradlew clean check funcTest --stacktrace --info --continue --parallel diff --git a/stub-runner/stub-runner-junit/README.md b/stub-runner/stub-runner-junit/README.md index 985bd8d743..83a6a51adf 100644 --- a/stub-runner/stub-runner-junit/README.md +++ b/stub-runner/stub-runner-junit/README.md @@ -19,6 +19,10 @@ class AccurestRuleSpec extends Specification { rule.findStubUrl('loanIssuance') != null rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: + rule.findAllRunningStubs().isPresent('loanIssuance') + rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') + rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') and: 'Stubs were registered' "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index b584b8ca7f..6236e5d710 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -14,6 +14,7 @@ import org.junit.runners.model.Statement; import io.codearte.accurest.stubrunner.BatchStubRunner; import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; +import io.codearte.accurest.stubrunner.RunningStubs; import io.codearte.accurest.stubrunner.StubConfiguration; import io.codearte.accurest.stubrunner.StubFinder; import io.codearte.accurest.stubrunner.StubRunnerOptions; @@ -155,4 +156,9 @@ public class AccurestRule implements TestRule, StubFinder { public URL findStubUrl(String ivyNotation) { return stubFinder.findStubUrl(ivyNotation); } + + @Override + public RunningStubs findAllRunningStubs() { + return stubFinder.findAllRunningStubs(); + } } diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy index 755f8857c7..a5dbf056e1 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy @@ -9,8 +9,13 @@ import spock.lang.Specification */ class AccurestRuleSpec extends Specification { + static { + System.properties.setProperty("stubrunner.stubs.repository.root", "") + System.properties.setProperty("stubrunner.stubs.classifier", 'stubs') + } + @ClassRule @Shared AccurestRule rule = new AccurestRule() - .repoRoot(AccurestRuleSpec.getResource("/m2repo").path) + .repoRoot(AccurestRuleSpec.getResource("/m2repo").toURI().toString()) .downloadStub("io.codearte.accurest.stubs", "loanIssuance") .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") @@ -20,6 +25,10 @@ class AccurestRuleSpec extends Specification { rule.findStubUrl('loanIssuance') != null rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: + rule.findAllRunningStubs().isPresent('loanIssuance') + rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') + rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') and: 'Stubs were registered' "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy index 77ab729acc..2dc4fe0939 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy @@ -12,7 +12,7 @@ import spock.util.environment.RestoreSystemProperties class AccurestRuleSysPropsSpec extends Specification { static { - System.properties.setProperty("stubrunner.stubs.repository.root", AccurestRuleSysPropsSpec.getResource("/m2repo").path) + System.properties.setProperty("stubrunner.stubs.repository.root", AccurestRuleSysPropsSpec.getResource("/m2repo").toURI().toString()) System.properties.setProperty("stubrunner.stubs.classifier", 'classifier that will be overridden') } @@ -29,5 +29,8 @@ class AccurestRuleSysPropsSpec extends Specification { and: 'Stubs were registered' "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + cleanup: + System.properties.setProperty("stubrunner.stubs.repository.root", "") + System.properties.setProperty("stubrunner.stubs.classifier", 'stubs') } } diff --git a/stub-runner/stub-runner-spring/README.md b/stub-runner/stub-runner-spring/README.md index 2229814c9e..c6d26a1386 100644 --- a/stub-runner/stub-runner-spring/README.md +++ b/stub-runner/stub-runner-spring/README.md @@ -13,14 +13,18 @@ its methods as presented below: @Autowired StubFinder stubFinder def 'should start WireMock servers'() { - expect: 'WireMocks are running' - stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null - and: 'Stubs were registered' - "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + expect: 'WireMocks are running' + stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null + stubFinder.findStubUrl('loanIssuance') != null + stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: + stubFinder.findAllRunningStubs().isPresent('loanIssuance') + stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') + stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') + and: 'Stubs were registered' + "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' } ``` diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java index 0f1c8d6939..ebc373b762 100644 --- a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java +++ b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java @@ -34,7 +34,7 @@ public class StubRunnerConfiguration { * @param workOffline forces offline work * @param stubs comma separated list of stubs presented in Ivy notation */ - @Bean(initMethod = "runStubs", destroyMethod = "close") + @Bean(destroyMethod = "close") public StubRunning batchStubRunner( @Value("${stubrunner.port.range.min:10000}") Integer minPortValue, @Value("${stubrunner.port.range.max:15000}") Integer maxPortValue, @@ -42,12 +42,13 @@ public class StubRunnerConfiguration { @Value("${stubrunner.stubs.classifier:stubs}") String stubsSuffix, @Value("${stubrunner.work-offline:false}") boolean workOffline, @Value("${stubrunner.stubs:}") String stubs) throws IOException { - StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue, - maxPortValue, uriStringOrEmpty(stubRepositoryRoot), + StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue, maxPortValue, uriStringOrEmpty(stubRepositoryRoot), stubRepositoryRoot == null || workOffline, stubsSuffix); Set dependencies = StubsParser.fromString(stubs, stubsSuffix); - return new BatchStubRunnerFactory(stubRunnerOptions, dependencies) - .buildBatchStubRunner(); + BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, dependencies).buildBatchStubRunner(); + // TODO: Consider running it in a separate thread + batchStubRunner.runStubs(); + return batchStubRunner; } private String uriStringOrEmpty(Resource stubRepositoryRoot) throws IOException { diff --git a/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy b/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy index 2e3a749ecd..b43cd14143 100644 --- a/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy +++ b/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy @@ -23,6 +23,10 @@ class StubRunnerConfigurationSpec extends Specification { stubFinder.findStubUrl('loanIssuance') != null stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + and: + stubFinder.findAllRunningStubs().isPresent('loanIssuance') + stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') + stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') and: 'Stubs were registered' "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' @@ -31,7 +35,5 @@ class StubRunnerConfigurationSpec extends Specification { @Configuration @Import(StubRunnerConfiguration) @EnableAutoConfiguration - static class Config { - - } + static class Config {} } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy index 3281ca38a7..a29a799eaf 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy @@ -43,6 +43,11 @@ class BatchStubRunner implements StubRunning { return findStubUrl(null, splitString[0]) } + @Override + RunningStubs findAllRunningStubs() { + return new RunningStubs(stubRunners.collect { StubRunner runner -> runner.findAllRunningStubs() }) + } + @Override void close() throws IOException { stubRunners.each { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy index c2f0572d3f..c856dd9dd2 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy @@ -10,10 +10,64 @@ import groovy.transform.EqualsAndHashCode @EqualsAndHashCode @CompileStatic class RunningStubs { - final Map namesAndPorts + final Map namesAndPorts = [:] RunningStubs(Map map) { - this.namesAndPorts = map + this.namesAndPorts.putAll(map) + } + + RunningStubs(Collection runningStubs) { + runningStubs.each { + this.namesAndPorts.putAll(it.namesAndPorts) + } + } + + Integer getPort(String artifactId) { + def strings = artifactId.split(':') + if (strings.length == 1) { + return namesAndPorts.entrySet().find { + it.key.artifactId == artifactId + }?.value + } else if(strings.length == 2) { + return namesAndPorts.entrySet().find { + it.key.groupId == strings[0] && it.key.artifactId == strings[1] + }?.value + } + return namesAndPorts.entrySet().find { + it.key.groupId == strings[0] && + it.key.artifactId == strings[1] && + it.key.classifier == strings[2] + }?.value + } + + Integer getPort(String groupId, String artifactId) { + return namesAndPorts.entrySet().find { + it.key.artifactId == artifactId && it.key.groupId == groupId + }?.value + } + + boolean isPresent(String artifactId) { + def strings = artifactId.split(':') + if (strings.length == 1) { + return namesAndPorts.entrySet().find { + it.key.artifactId == artifactId + } + } else if(strings.length == 2) { + return namesAndPorts.entrySet().find { + it.key.groupId == strings[0] && it.key.artifactId == strings[1] + } + } + return namesAndPorts.entrySet().find { + it.key.groupId == strings[0] && + it.key.artifactId == strings[1] && + it.key.classifier == strings[2] + } + } + + boolean isPresent(String groupId, String artifactId) { + return namesAndPorts.entrySet().find { + it.key.artifactId == artifactId && it.key.groupId == groupId + } } @Override diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy index f608436c2a..f67825bcef 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy @@ -18,4 +18,9 @@ interface StubFinder { * @return URL of a running stub or null if not found */ URL findStubUrl(String ivyNotation) + + /** + * Returns all running stubs + */ + RunningStubs findAllRunningStubs() } \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy index fd580d3e99..0777d7d56a 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -46,6 +46,11 @@ class StubRunner implements StubRunning { return findStubUrl(splitString[0], splitString[1]) } + @Override + RunningStubs findAllRunningStubs() { + return localStubRunner.findAllRunningStubs() + } + private void registerShutdownHook() { Runnable stopAllServers = { this.close() } Runtime.runtime.addShutdownHook(new Thread(stopAllServers)) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index a12707c12b..a398a3ec4b 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -47,6 +47,11 @@ class StubRunnerExecutor implements StubFinder { return findStubUrl(splitString[0], splitString[1]) } + @Override + RunningStubs findAllRunningStubs() { + return new RunningStubs([(stubServer.stubConfiguration) : stubServer.port]) + } + private URL returnStubUrlIfMatches(boolean condition) { return condition ? stubServer.stubUrl : null } diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy index 7b086f7458..ce378588a5 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy @@ -24,6 +24,10 @@ class StubRunnerExecutorSpec extends Specification { executor.runStubs(repository, stub) then: executor.findStubUrl("group", "artifact") == EXPECTED_STUB_URL + and: + executor.findAllRunningStubs().isPresent('artifact') + executor.findAllRunningStubs().isPresent('group', 'artifact') + executor.findAllRunningStubs().isPresent('group:artifact') cleanup: executor.shutdown() } From 2d01dacdcf1be3f7e1aadc8755c49c3be63de718 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 27 Mar 2016 01:57:26 +0100 Subject: [PATCH 329/719] Trying to fix Travis --- .travis.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 14f8d62652..59f9ee2ebe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,5 @@ jdk: - openjdk7 - oraclejdk8 -cache: - directories: - - $HOME/.gradle - - $HOME/.m2 - install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --info --continue --parallel +script: ./gradlew clean check funcTest --stacktrace --info --continue From 60bc33b157911a724d6939ec9e453b8b7956b5a3 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 27 Mar 2016 07:38:11 +0200 Subject: [PATCH 330/719] configurable contracts directory --- .../accurest/maven/GenerateSpecsMojo.java | 5 ++++- .../accurest/maven/GenerateStubsMojo.java | 5 ++++- .../accurest/maven/PluginUnitTest.java | 7 +++++++ .../projects/customContractsLocation/pom.xml | 19 +++++++++++++++++++ .../src/foo/Sample.groovy | 18 ++++++++++++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 src/test/projects/customContractsLocation/pom.xml create mode 100644 src/test/projects/customContractsLocation/src/foo/Sample.groovy diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index aba7bb50b2..9019e87d68 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -24,10 +24,13 @@ public class GenerateSpecsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}") protected File projectBuildDirectory; + @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs", required = false) + private String contractsDir = "/src/test/resources/stubs"; + public void execute() throws MojoExecutionException, MojoFailureException { AccurestConfigProperties config = new AccurestConfigProperties(); - config.setContractsDslDir(new File(baseDir, "/src/test/resources/stubs")); + config.setContractsDslDir(new File(baseDir, contractsDir)); config.setBasePackageForTests("io.codearte.accurest.tests"); config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, "/generated-sources/accurest")); diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index 5ba6ed76fb..4fed9aa6c8 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -25,9 +25,12 @@ public class GenerateStubsMojo extends AbstractMojo { @Parameter(property = "mappingsDir", defaultValue = "mappings", required = false) private String mappingsDir = "mappings"; + @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs", required = false) + private String contractsDir = "/src/test/resources/stubs"; + public void execute() throws MojoExecutionException, MojoFailureException { AccurestConfigProperties config = new AccurestConfigProperties(); - config.setContractsDslDir(new File(baseDir, "/src/test/resources/stubs")); + config.setContractsDslDir(new File(baseDir, contractsDir)); config.setStubsOutputDir(new File(projectBuildDirectory, mappingsDir)); getLog().info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion"); diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index d1e0bf696c..d25fad2751 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -32,6 +32,13 @@ public class PluginUnitTest { assertFilesPresent(basedir, "target/foo/Sample.json"); } + @Test + public void shouldGenerateWiremockStubsInSelectedLocation2() throws Exception { + File basedir = resources.getBasedir("customContractsLocation"); + maven.executeMojo(basedir, "generateStubs", TestMavenRuntime.newParameter("contractsDir", "src/foo")); + assertFilesPresent(basedir, "target/mappings/Sample.json"); + } + @Test public void shouldGenerateContractSpecificationInDefaultLocation() throws Exception { File basedir = resources.getBasedir("basic"); diff --git a/src/test/projects/customContractsLocation/pom.xml b/src/test/projects/customContractsLocation/pom.xml new file mode 100644 index 0000000000..fed7b7d67e --- /dev/null +++ b/src/test/projects/customContractsLocation/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + io.codearte.accurest.sample + sample-project + 0.1 + + + + + io.codearte.accurest + accurest-maven-plugin + + + + + \ No newline at end of file diff --git a/src/test/projects/customContractsLocation/src/foo/Sample.groovy b/src/test/projects/customContractsLocation/src/foo/Sample.groovy new file mode 100644 index 0000000000..673ab7bd8d --- /dev/null +++ b/src/test/projects/customContractsLocation/src/foo/Sample.groovy @@ -0,0 +1,18 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'POST' + url('/users') { + + } + headers { + header 'Content-Type': 'application/json' + } + body '''{ "login" : "john", "name": "John The Contract" }''' + } + response { + status 200 + headers { + header 'Location': '/users/john' + } + } +} \ No newline at end of file From 30c534a4e879fe13b8b01b5fb2507569a7dbefca Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 27 Mar 2016 08:07:31 +0200 Subject: [PATCH 331/719] Trying to fix Travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 59f9ee2ebe..2030365ea0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java sudo: false before_install: - - "export JAVA_OPTS='-Xmx1024m -XX:MaxPermSize=384m'" + - "export JAVA_OPTS='-Xmx1512m -XX:MaxPermSize=512m'" - "rm -rf $HOME/.m2/repository/io/codearte/accurest/stubs" - "mkdir $HOME/.m2/repository/io/codearte/accurest/ --parents" - "cp -r stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs $HOME/.m2/repository/io/codearte/accurest/" @@ -13,4 +13,4 @@ jdk: - oraclejdk8 install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --info --continue +script: ./gradlew clean check funcTest --stacktrace --info --continue --parallel From 987613f8a71294ec0b28b867a3bb29d63af40ec3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 27 Mar 2016 08:40:45 +0200 Subject: [PATCH 332/719] Trying to fix Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 2030365ea0..08dc9f7070 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java sudo: false before_install: - - "export JAVA_OPTS='-Xmx1512m -XX:MaxPermSize=512m'" + - "export JAVA_OPTS='-Xmx1256m -XX:MaxPermSize=400m'" - "rm -rf $HOME/.m2/repository/io/codearte/accurest/stubs" - "mkdir $HOME/.m2/repository/io/codearte/accurest/ --parents" - "cp -r stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs $HOME/.m2/repository/io/codearte/accurest/" From bdfe70e9208bd8ab381d261d935c4e8a2692bb55 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 27 Mar 2016 09:26:03 +0200 Subject: [PATCH 333/719] more configuration options --- .../accurest/maven/GenerateSpecsMojo.java | 18 ++++++++++++------ .../accurest/maven/GenerateStubsMojo.java | 8 ++++---- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 9019e87d68..4d68e341d9 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -19,20 +19,26 @@ import io.codearte.accurest.config.AccurestConfigProperties; public class GenerateSpecsMojo extends AbstractMojo { @Parameter(defaultValue = "${basedir}") - protected File baseDir; + private File baseDir; @Parameter(defaultValue = "${project.build.directory}") - protected File projectBuildDirectory; + private File projectBuildDirectory; @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs", required = false) - private String contractsDir = "/src/test/resources/stubs"; + private String contractsDir; + + @Parameter(property = "generatedTestSourcesDir", defaultValue = "/generated-sources/accurest", required = false) + private String generatedTestSourcesDir; + + @Parameter(property = "basePackageForTests", defaultValue = "io.codearte.accurest.tests", required = false) + private String basePackageForTests; public void execute() throws MojoExecutionException, MojoFailureException { AccurestConfigProperties config = new AccurestConfigProperties(); config.setContractsDslDir(new File(baseDir, contractsDir)); - config.setBasePackageForTests("io.codearte.accurest.tests"); - config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, "/generated-sources/accurest")); + config.setBasePackageForTests(basePackageForTests); + config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); getLog().info("Accurest Plugin: Invoking test sources generation"); getLog().info(format("Registering %s as test source directory", config.getGeneratedTestSourcesDir())); @@ -40,7 +46,7 @@ public class GenerateSpecsMojo extends AbstractMojo { try { TestGenerator generator = new TestGenerator(config); int generatedClasses = generator.generate(); - getLog().info(String.format("Generated %s test classes.", generatedClasses)); + getLog().info(format("Generated %s test classes.", generatedClasses)); } catch (AccurestException e) { throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e); } diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index 4fed9aa6c8..852cc64f91 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -17,16 +17,16 @@ import io.codearte.accurest.wiremock.RecursiveFilesConverter; public class GenerateStubsMojo extends AbstractMojo { @Parameter(defaultValue = "${basedir}") - protected File baseDir; + private File baseDir; @Parameter(defaultValue = "${project.build.directory}") - protected File projectBuildDirectory; + private File projectBuildDirectory; @Parameter(property = "mappingsDir", defaultValue = "mappings", required = false) - private String mappingsDir = "mappings"; + private String mappingsDir; @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs", required = false) - private String contractsDir = "/src/test/resources/stubs"; + private String contractsDir; public void execute() throws MojoExecutionException, MojoFailureException { AccurestConfigProperties config = new AccurestConfigProperties(); From 76710cff32f9d9ffa239c6dc6f7c444ad83447f2 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 27 Mar 2016 09:27:14 +0200 Subject: [PATCH 334/719] removed default parameters --- .../io/codearte/accurest/maven/GenerateSpecsMojo.java | 9 ++++++--- .../io/codearte/accurest/maven/GenerateStubsMojo.java | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 4d68e341d9..54052809db 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -24,15 +24,18 @@ public class GenerateSpecsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}") private File projectBuildDirectory; - @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs", required = false) + @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs") private String contractsDir; - @Parameter(property = "generatedTestSourcesDir", defaultValue = "/generated-sources/accurest", required = false) + @Parameter(property = "generatedTestSourcesDir", defaultValue = "/generated-sources/accurest") private String generatedTestSourcesDir; - @Parameter(property = "basePackageForTests", defaultValue = "io.codearte.accurest.tests", required = false) + @Parameter(property = "basePackageForTests", defaultValue = "io.codearte.accurest.tests") private String basePackageForTests; + public GenerateSpecsMojo() { + } + public void execute() throws MojoExecutionException, MojoFailureException { AccurestConfigProperties config = new AccurestConfigProperties(); diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index 852cc64f91..3cfd8e82cc 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -22,10 +22,10 @@ public class GenerateStubsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}") private File projectBuildDirectory; - @Parameter(property = "mappingsDir", defaultValue = "mappings", required = false) + @Parameter(property = "mappingsDir", defaultValue = "mappings") private String mappingsDir; - @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs", required = false) + @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs") private String contractsDir; public void execute() throws MojoExecutionException, MojoFailureException { From fd3d7deac3733415da493db85db48d8dba1416c2 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 27 Mar 2016 10:15:48 +0200 Subject: [PATCH 335/719] cleaup --- .../java/io/codearte/accurest/maven/GenerateSpecsMojo.java | 6 +++--- .../java/io/codearte/accurest/maven/GenerateStubsMojo.java | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 54052809db..6dba5b62bf 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -18,10 +18,10 @@ import io.codearte.accurest.config.AccurestConfigProperties; @Mojo(name = "generateSpecs", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) public class GenerateSpecsMojo extends AbstractMojo { - @Parameter(defaultValue = "${basedir}") + @Parameter(defaultValue = "${basedir}", readonly = true) private File baseDir; - @Parameter(defaultValue = "${project.build.directory}") + @Parameter(defaultValue = "${project.build.directory}", readonly = true) private File projectBuildDirectory; @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs") @@ -44,7 +44,7 @@ public class GenerateSpecsMojo extends AbstractMojo { config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); getLog().info("Accurest Plugin: Invoking test sources generation"); - getLog().info(format("Registering %s as test source directory", config.getGeneratedTestSourcesDir())); + getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); try { TestGenerator generator = new TestGenerator(config); diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index 3cfd8e82cc..bf32bcd1d4 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -16,10 +16,10 @@ import io.codearte.accurest.wiremock.RecursiveFilesConverter; @Mojo(name = "generateStubs", defaultPhase = LifecyclePhase.PROCESS_RESOURCES) public class GenerateStubsMojo extends AbstractMojo { - @Parameter(defaultValue = "${basedir}") + @Parameter(defaultValue = "${basedir}", readonly = true) private File baseDir; - @Parameter(defaultValue = "${project.build.directory}") + @Parameter(defaultValue = "${project.build.directory}", readonly = true) private File projectBuildDirectory; @Parameter(property = "mappingsDir", defaultValue = "mappings") From 79d03cd88ecab669b82094c09c0ee4fd21f5f566 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 27 Mar 2016 10:24:00 +0200 Subject: [PATCH 336/719] travis integration --- .travis.yml | 9 +++++++++ pom.xml | 28 ++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..df5da30d05 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,9 @@ +language: java + +jdk: + - oraclejdk8 + +script: ./mvnw package + +after_success: + - ./mvnw clean test jacoco:report coveralls:report \ No newline at end of file diff --git a/pom.xml b/pom.xml index b1b4c79a65..f79cc2bdf6 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,9 @@ 3.2.5 3.4 + + 1.7 + UTF-8 @@ -100,6 +103,31 @@ none + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + prepare-agent + + prepare-agent + + + + report + + report + + + + + + + org.eluder.coveralls + coveralls-maven-plugin + 4.1.0 +
\ No newline at end of file From ee4506f526cea4a27e0e3954f391210519de830c Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 27 Mar 2016 10:30:48 +0200 Subject: [PATCH 337/719] badges and readme --- README.md | 20 +++++++++++++++++++ .../projects/basic-with-execution/pom.xml | 1 - 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000000..a9c736eb4c --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) + +Accurest Maven Plugin +==== + +Sample usage +---- + + + io.codearte.accurest + accurest-maven-plugin + + + + generateStubs + generateSpecs + + + + \ No newline at end of file diff --git a/src/test/projects/basic-with-execution/pom.xml b/src/test/projects/basic-with-execution/pom.xml index 2238e43e53..9c253f6045 100644 --- a/src/test/projects/basic-with-execution/pom.xml +++ b/src/test/projects/basic-with-execution/pom.xml @@ -52,7 +52,6 @@ io.codearte.accurest accurest-maven-plugin ${it-plugin.version} - true From b38fdf698b1a437dd525cb0797843bfad82f6ad5 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 27 Mar 2016 14:44:51 +0200 Subject: [PATCH 338/719] project configuration --- pom.xml | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/pom.xml b/pom.xml index f79cc2bdf6..65d8ecaf95 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,35 @@ UTF-8 + + + Apache 2 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + + scm:git:https://github.com/Codearte/accurest-maven-plugin.git + scm:git:git@github.com:Codearte/accurest-maven-plugin.git + https://github.com/Codearte/accurest-maven-plugin + HEAD + + + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + http://oss.sonatype.org/content/repositories/snapshots + + + sonatype-nexus-staging + Nexus Release Repository + http://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + io.codearte.accurest @@ -130,4 +159,34 @@ + + + + release + + + performRelease + true + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + + +
\ No newline at end of file From 98bbba0f0319106c689fe32d9239d1b963d091da Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 27 Mar 2016 19:45:18 +0200 Subject: [PATCH 339/719] syntax highlighting --- README.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index a9c736eb4c..2c7a064785 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,22 @@ [![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) -Accurest Maven Plugin +Accurate REST Maven Plugin ==== Sample usage ---- - - io.codearte.accurest - accurest-maven-plugin - - - - generateStubs - generateSpecs - - - - \ No newline at end of file +```xml + + io.codearte.accurest + accurest-maven-plugin + + + + generateStubs + generateSpecs + + + + +``` \ No newline at end of file From 5911ad42f0b9c7d50055f21023cd7c81b6e8fdc4 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 11:26:03 +0200 Subject: [PATCH 340/719] Use /generated-test-sources/ - this is standard location used by default IntelliJ and others. --- src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java | 2 +- src/test/java/io/codearte/accurest/maven/PluginUnitTest.java | 2 +- src/test/projects/basic-with-execution/pom.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 6dba5b62bf..971f4e03ed 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -27,7 +27,7 @@ public class GenerateSpecsMojo extends AbstractMojo { @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs") private String contractsDir; - @Parameter(property = "generatedTestSourcesDir", defaultValue = "/generated-sources/accurest") + @Parameter(property = "generatedTestSourcesDir", defaultValue = "/generated-test-sources/accurest") private String generatedTestSourcesDir; @Parameter(property = "basePackageForTests", defaultValue = "io.codearte.accurest.tests") diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index d25fad2751..ff4c7a9a69 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -44,6 +44,6 @@ public class PluginUnitTest { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "generateSpecs"); assertFilesPresent(basedir, - "target/generated-sources/accurest/io/codearte/accurest/tests/AccurestSpec.groovy"); + "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestSpec.groovy"); } } diff --git a/src/test/projects/basic-with-execution/pom.xml b/src/test/projects/basic-with-execution/pom.xml index 9c253f6045..ccbd71803d 100644 --- a/src/test/projects/basic-with-execution/pom.xml +++ b/src/test/projects/basic-with-execution/pom.xml @@ -75,7 +75,7 @@ - ${project.build.directory}/generated-sources/accurest + ${project.build.directory}/generated-test-sources/accurest **/*.groovy From cdd991616d4dba7af062ab3a2c99c89a7443a6a9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 28 Mar 2016 11:36:40 +0200 Subject: [PATCH 341/719] Added JUnit rule test --- stub-runner/stub-runner-junit/build.gradle | 2 + .../junit/AccurestRuleJUnitTest.java | 51 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java diff --git a/stub-runner/stub-runner-junit/build.gradle b/stub-runner/stub-runner-junit/build.gradle index d7156d14b9..fa14799646 100644 --- a/stub-runner/stub-runner-junit/build.gradle +++ b/stub-runner/stub-runner-junit/build.gradle @@ -12,4 +12,6 @@ dependencies { testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile 'ch.qos.logback:logback-classic:1.1.3' + testCompile 'org.assertj:assertj-core:2.3.0' + testCompile 'org.apache.commons:commons-io:1.3.2' } diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java new file mode 100644 index 0000000000..b22f1f60fe --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java @@ -0,0 +1,51 @@ +package io.codearte.accurest.stubrunner.junit; + +import java.io.InputStream; +import java.net.URI; + +import org.apache.commons.io.IOUtils; +import org.junit.ClassRule; +import org.junit.Test; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public class AccurestRuleJUnitTest { + + @ClassRule public static AccurestRule rule = new AccurestRule() + .repoRoot(repoRoot()) + .downloadStub("io.codearte.accurest.stubs", "loanIssuance") + .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); + + @Test + public void should_start_wiremock_servers() throws Exception { + // expect: 'WireMocks are running' + then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")); + then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull(); + // and: + then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); + then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue(); + then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue(); + // and: 'Stubs were registered' + then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); + then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); + } + + private static String repoRoot() { + try { + return AccurestRuleJUnitTest.class.getResource("/m2repo").toURI().toString(); + } catch (Exception e) { + return ""; + } + } + + private String httpGet(String url) throws Exception { + try(InputStream stream = URI.create(url).toURL().openStream()) { + return IOUtils.toString(stream); + } + } +} From e210ca226d42cf5168d86494c96351e4adc9b9fc Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 28 Mar 2016 11:43:46 +0200 Subject: [PATCH 342/719] Added tests for RunningStubs --- .../stubrunner/RunningStubsSpec.groovy | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy new file mode 100644 index 0000000000..d9cf63516b --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy @@ -0,0 +1,61 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +class RunningStubsSpec extends Specification { + RunningStubs runningStubs = new RunningStubs([(new StubConfiguration('a', 'b', 'c')) : 100]) + + def "should get port by group and artifact id"() { + expect: + runningStubs.getPort('a', 'b') == 100 + } + + def "should get port by artifact id"() { + expect: + runningStubs.getPort('b') == 100 + } + + def "should get port by group and artifact id in Ivy notation"() { + expect: + runningStubs.getPort('a:b') == 100 + } + + def "should get port by group, artifact id and classifier in Ivy notation"() { + expect: + runningStubs.getPort('a:b:c') == 100 + } + + def "should return null if no stub has been found"() { + expect: + runningStubs.getPort('missing artifact id') == null + } + + def "should find stub by group and artifact id"() { + expect: + runningStubs.isPresent('a', 'b') + } + + def "should find stub by artifact id"() { + expect: + runningStubs.isPresent('b') + } + + def "should find stub by group and artifact id in Ivy notation"() { + expect: + runningStubs.isPresent('a:b') + } + + def "should find stub by group, artifact id and classifier in Ivy notation"() { + expect: + runningStubs.isPresent('a:b:c') + } + + def "should return false if no stub has been found"() { + expect: + runningStubs.isPresent('missing artifact id') == false + } + +} From 8d129cb53365268ade9f1fb00876381d3f84d95f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 28 Mar 2016 12:18:56 +0200 Subject: [PATCH 343/719] Trying to fix Travis --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 08dc9f7070..6e9800ac21 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,7 @@ language: java sudo: false before_install: - - "export JAVA_OPTS='-Xmx1256m -XX:MaxPermSize=400m'" + - "export JAVA_OPTS='-Xmx1024m -XX:MaxPermSize=256m'" - "rm -rf $HOME/.m2/repository/io/codearte/accurest/stubs" - "mkdir $HOME/.m2/repository/io/codearte/accurest/ --parents" - "cp -r stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs $HOME/.m2/repository/io/codearte/accurest/" @@ -13,4 +13,4 @@ jdk: - oraclejdk8 install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --info --continue --parallel +script: ./gradlew clean check funcTest --stacktrace --info --continue From 3b624d1f370409ce5c47384f6dccca1a4980a679 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 28 Mar 2016 12:19:24 +0200 Subject: [PATCH 344/719] Trying to fix Travis --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 6e9800ac21..8f075cb917 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: java -sudo: false +sudo: required +dist: trusty before_install: - "export JAVA_OPTS='-Xmx1024m -XX:MaxPermSize=256m'" From 646f279dd7f1be4b441da3f468bf82aa2e33355a Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 12:55:49 +0200 Subject: [PATCH 345/719] bootSimple integratio test converted from gradle --- pom.xml | 1 - .../accurest/maven/GenerateSpecsMojo.java | 5 + .../accurest/maven/PluginIntegrationTest.java | 9 ++ .../projects/basic-with-execution/pom.xml | 9 ++ src/test/projects/bootSimple/pom.xml | 153 ++++++++++++++++++ .../ofg/twitter/place/PairIdController.groovy | 36 +++++ .../groovy/com/ofg/twitter/place/Tweet.java | 13 ++ .../sample/SampleSimpleBootApplication.java | 12 ++ .../src/main/resources/application.properties | 0 .../ofg/twitter/place/AcceptanceSpec.groovy | 23 +++ .../ofg/twitter/place/BaseMockMvcSpec.groovy | 16 ++ .../SampleSimpleBootApplicationTests.java | 16 ++ .../src/test/resources/logback-test.groovy | 14 ++ .../stubs/collerate_PlacesFrom_Tweet.groovy | 18 +++ .../resources/stubs/moreComplexVersion.groovy | 21 +++ 15 files changed, 345 insertions(+), 1 deletion(-) create mode 100644 src/test/projects/bootSimple/pom.xml create mode 100644 src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy create mode 100644 src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java create mode 100644 src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java create mode 100644 src/test/projects/bootSimple/src/main/resources/application.properties create mode 100644 src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy create mode 100644 src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy create mode 100644 src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java create mode 100644 src/test/projects/bootSimple/src/test/resources/logback-test.groovy create mode 100644 src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy create mode 100644 src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy diff --git a/pom.xml b/pom.xml index 65d8ecaf95..72faff14f2 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,6 @@ 3.2.5 3.4 - 1.7 UTF-8 diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 971f4e03ed..3b26bf5617 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -33,6 +33,9 @@ public class GenerateSpecsMojo extends AbstractMojo { @Parameter(property = "basePackageForTests", defaultValue = "io.codearte.accurest.tests") private String basePackageForTests; + @Parameter(property = "baseClassForTests", required = true) + private String baseClassForTests; + public GenerateSpecsMojo() { } @@ -42,9 +45,11 @@ public class GenerateSpecsMojo extends AbstractMojo { config.setContractsDslDir(new File(baseDir, contractsDir)); config.setBasePackageForTests(basePackageForTests); config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); + config.setBaseClassForTests(baseClassForTests); getLog().info("Accurest Plugin: Invoking test sources generation"); getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); + getLog().info(format("Using %s as base class for tests", config.getBaseClassForTests())); try { TestGenerator generator = new TestGenerator(config); diff --git a/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java index a786df3778..5f3b2626f0 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java @@ -40,4 +40,13 @@ public class PluginIntegrationTest { .execute("package") .assertLogText("Accurest Plugin: Invoking test sources generation"); } + + @Test + public void shouldBuildAndTestSimpleBootProject() throws Exception { + File basedir = resources.getBasedir("bootSimple"); + maven.forProject(basedir) + .execute("package") + .assertErrorFreeLog() + .assertLogText("Accurest Plugin: Invoking test sources generation"); + } } \ No newline at end of file diff --git a/src/test/projects/basic-with-execution/pom.xml b/src/test/projects/basic-with-execution/pom.xml index ccbd71803d..8f5f9d6b65 100644 --- a/src/test/projects/basic-with-execution/pom.xml +++ b/src/test/projects/basic-with-execution/pom.xml @@ -60,6 +60,9 @@ + + com.ofg.twitter.place.BaseMockMvcSpec + org.codehaus.gmavenplus @@ -74,6 +77,12 @@ + + ${project.basedir}/src/test/groovy + + **/*.groovy + + ${project.build.directory}/generated-test-sources/accurest diff --git a/src/test/projects/bootSimple/pom.xml b/src/test/projects/bootSimple/pom.xml new file mode 100644 index 0000000000..187d737361 --- /dev/null +++ b/src/test/projects/bootSimple/pom.xml @@ -0,0 +1,153 @@ + + + 4.0.0 + + io.codearte.sample + sample-simple-boot + 0.0.1-SNAPSHOT + jar + + sample-simple-boot + Demo project for Spring Boot + + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + + + + + UTF-8 + 1.8 + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + org.codehaus.groovy + groovy-all + + + + + org.spockframework + spock-core + 1.0-groovy-2.4 + test + + + com.jayway.restassured + rest-assured + 2.9.0 + test + + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + test + + + com.github.tomakehurst + wiremock + 2.0.4-beta + test + + + com.toomuchcoding.jsonassert + jsonassert + 0.2.2 + test + + + org.assertj + assertj-core + 2.3.0 + test + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + io.codearte.accurest + accurest-maven-plugin + ${it-plugin.version} + + + + generateStubs + generateSpecs + + + + + com.ofg.twitter.place.BaseMockMvcSpec + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.5 + + + + addSources + addTestSources + generateStubs + compile + testGenerateStubs + testCompile + removeStubs + removeTestStubs + + + + + + + ${project.basedir}/src/test/groovy + + **/*.groovy + + + + ${project.build.directory}/generated-test-sources/accurest + + **/*.groovy + + + + + + + maven-surefire-plugin + 2.19 + + + **/*Spec.java + + + + + + + + diff --git a/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy new file mode 100644 index 0000000000..3a7671793c --- /dev/null +++ b/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy @@ -0,0 +1,36 @@ +package com.ofg.twitter.place + +import groovy.transform.TypeChecked +import groovy.util.logging.Slf4j +import org.springframework.http.MediaType +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestBody +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +import static org.springframework.web.bind.annotation.RequestMethod.PUT + +@Slf4j +@RestController +@RequestMapping('/api') +@TypeChecked +class PairIdController { + + @RequestMapping( + value = '{pairId}', + method = PUT, + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE) + String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { + log.info("Inside PairIdController, doing very important logic") + if (tweets?.text != ["Gonna see you at Warsaw"]) { + throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") + } + return """ + { + "path" : "/api/$pairId", + "correlationId" : 123456 + } + """ + } +} diff --git a/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java b/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java new file mode 100644 index 0000000000..5d1e9c2835 --- /dev/null +++ b/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java @@ -0,0 +1,13 @@ +package com.ofg.twitter.place; + +public class Tweet { + private String text; + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } +} diff --git a/src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java b/src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java new file mode 100644 index 0000000000..1ef9cf14fa --- /dev/null +++ b/src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java @@ -0,0 +1,12 @@ +package io.codearte.sample; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SampleSimpleBootApplication { + + public static void main(String[] args) { + SpringApplication.run(SampleSimpleBootApplication.class, args); + } +} diff --git a/src/test/projects/bootSimple/src/main/resources/application.properties b/src/test/projects/bootSimple/src/main/resources/application.properties new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy b/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy new file mode 100644 index 0000000000..3c244ce6cd --- /dev/null +++ b/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy @@ -0,0 +1,23 @@ +package com.ofg.twitter.place + +import com.ofg.twitter.place.PairIdController +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import spock.lang.Specification + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +class AcceptanceSpec extends Specification { + + def "should have controller up and running"() { + given: + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PairIdController()).build() + expect: + mockMvc.perform(put("/api/${1}"). + contentType(MediaType.APPLICATION_JSON). + content("""[{"text":"Gonna see you at Warsaw"}]""")). + andExpect(status().isOk()) + } +} diff --git a/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy b/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy new file mode 100644 index 0000000000..b85a44721d --- /dev/null +++ b/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy @@ -0,0 +1,16 @@ +package com.ofg.twitter.place + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import com.ofg.twitter.place.PairIdController +import spock.lang.Specification + +abstract class BaseMockMvcSpec extends Specification { + + def setup() { + RestAssuredMockMvc.standaloneSetup(new PairIdController()) + } + + void isProperCorrelationId(Integer correlationId) { + assert correlationId == 123456 + } +} diff --git a/src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java b/src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java new file mode 100644 index 0000000000..345f6ef841 --- /dev/null +++ b/src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java @@ -0,0 +1,16 @@ +package io.codearte.sample; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.SpringApplicationConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +@RunWith(SpringJUnit4ClassRunner.class) +@SpringApplicationConfiguration(classes = SampleSimpleBootApplication.class) +public class SampleSimpleBootApplicationTests { + + @Test + public void contextLoads() { + } + +} diff --git a/src/test/projects/bootSimple/src/test/resources/logback-test.groovy b/src/test/projects/bootSimple/src/test/resources/logback-test.groovy new file mode 100644 index 0000000000..315c39c794 --- /dev/null +++ b/src/test/projects/bootSimple/src/test/resources/logback-test.groovy @@ -0,0 +1,14 @@ +import ch.qos.logback.classic.encoder.PatternLayoutEncoder +import ch.qos.logback.core.ConsoleAppender + +String console = "CONSOLE" +String logPattern = "%d{yyyy-MM-dd HH:mm:ss.SSSZ, Europe/Warsaw} | %-5level | %X{correlationId} | %thread | %logger{1} | %m%n" + +appender(console, ConsoleAppender) { + encoder(PatternLayoutEncoder) { + pattern = logPattern + } +} + +root(INFO, [console]) +logger("com.ofg", DEBUG) diff --git a/src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy b/src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy new file mode 100644 index 0000000000..826f71b791 --- /dev/null +++ b/src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy @@ -0,0 +1,18 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'PUT' + url '/api/12' + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] +''' + } + response { + status 200 + } +} \ No newline at end of file diff --git a/src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy b/src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy new file mode 100644 index 0000000000..943fbc23b9 --- /dev/null +++ b/src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy @@ -0,0 +1,21 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] +''' + } + response { + body ( + path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), + correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) + ) + status 200 + } +} \ No newline at end of file From 1b9e1cf24dd1229b5fb1ace53096a5191e593369 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 13:16:58 +0200 Subject: [PATCH 346/719] contracts directory instead of stubs --- README.md | 16 +++++++++++++++- .../accurest/maven/GenerateSpecsMojo.java | 2 +- .../accurest/maven/GenerateStubsMojo.java | 6 +++--- .../codearte/accurest/maven/PluginUnitTest.java | 14 +++++++------- .../resources/{stubs => contracts}/Sample.groovy | 0 .../resources/{stubs => contracts}/Sample.groovy | 0 src/test/projects/bootSimple/pom.xml | 1 + .../pom.xml | 0 .../src/test/resources/stubs}/Sample.groovy | 0 9 files changed, 27 insertions(+), 12 deletions(-) rename src/test/projects/basic-with-execution/src/test/resources/{stubs => contracts}/Sample.groovy (100%) rename src/test/projects/basic/src/test/resources/{stubs => contracts}/Sample.groovy (100%) rename src/test/projects/{customContractsLocation => withStubs}/pom.xml (100%) rename src/test/projects/{customContractsLocation/src/foo => withStubs/src/test/resources/stubs}/Sample.groovy (100%) diff --git a/README.md b/README.md index 2c7a064785..2338faf156 100644 --- a/README.md +++ b/README.md @@ -19,4 +19,18 @@ Sample usage -``` \ No newline at end of file +``` + + +``` + +Project default directories +--- + +Contract definitions (_contractsDir_): + + /src/test/resources/contracts + +Generated accurest specifications (_generatedTestSourcesDir_): + + /target/generated-test-sources/accurest diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 3b26bf5617..670b68f619 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -24,7 +24,7 @@ public class GenerateSpecsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}", readonly = true) private File projectBuildDirectory; - @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs") + @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/contracts") private String contractsDir; @Parameter(property = "generatedTestSourcesDir", defaultValue = "/generated-test-sources/accurest") diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index bf32bcd1d4..608cb18d3b 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -22,12 +22,12 @@ public class GenerateStubsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}", readonly = true) private File projectBuildDirectory; + @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/contracts") + private String contractsDir; + @Parameter(property = "mappingsDir", defaultValue = "mappings") private String mappingsDir; - @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/stubs") - private String contractsDir; - public void execute() throws MojoExecutionException, MojoFailureException { AccurestConfigProperties config = new AccurestConfigProperties(); config.setContractsDslDir(new File(baseDir, contractsDir)); diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index ff4c7a9a69..71ed604edf 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -25,6 +25,13 @@ public class PluginUnitTest { assertFilesPresent(basedir, "target/mappings/Sample.json"); } + @Test + public void shouldGenerateWiremockFromStubsDirectory() throws Exception { + File basedir = resources.getBasedir("withStubs"); + maven.executeMojo(basedir, "generateStubs", TestMavenRuntime.newParameter("contractsDir", "/src/test/resources/stubs")); + assertFilesPresent(basedir, "target/mappings/Sample.json"); + } + @Test public void shouldGenerateWiremockStubsInSelectedLocation() throws Exception { File basedir = resources.getBasedir("basic"); @@ -32,13 +39,6 @@ public class PluginUnitTest { assertFilesPresent(basedir, "target/foo/Sample.json"); } - @Test - public void shouldGenerateWiremockStubsInSelectedLocation2() throws Exception { - File basedir = resources.getBasedir("customContractsLocation"); - maven.executeMojo(basedir, "generateStubs", TestMavenRuntime.newParameter("contractsDir", "src/foo")); - assertFilesPresent(basedir, "target/mappings/Sample.json"); - } - @Test public void shouldGenerateContractSpecificationInDefaultLocation() throws Exception { File basedir = resources.getBasedir("basic"); diff --git a/src/test/projects/basic-with-execution/src/test/resources/stubs/Sample.groovy b/src/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy similarity index 100% rename from src/test/projects/basic-with-execution/src/test/resources/stubs/Sample.groovy rename to src/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy diff --git a/src/test/projects/basic/src/test/resources/stubs/Sample.groovy b/src/test/projects/basic/src/test/resources/contracts/Sample.groovy similarity index 100% rename from src/test/projects/basic/src/test/resources/stubs/Sample.groovy rename to src/test/projects/basic/src/test/resources/contracts/Sample.groovy diff --git a/src/test/projects/bootSimple/pom.xml b/src/test/projects/bootSimple/pom.xml index 187d737361..0a5de4800d 100644 --- a/src/test/projects/bootSimple/pom.xml +++ b/src/test/projects/bootSimple/pom.xml @@ -100,6 +100,7 @@ com.ofg.twitter.place.BaseMockMvcSpec + /src/test/resources/stubs diff --git a/src/test/projects/customContractsLocation/pom.xml b/src/test/projects/withStubs/pom.xml similarity index 100% rename from src/test/projects/customContractsLocation/pom.xml rename to src/test/projects/withStubs/pom.xml diff --git a/src/test/projects/customContractsLocation/src/foo/Sample.groovy b/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy similarity index 100% rename from src/test/projects/customContractsLocation/src/foo/Sample.groovy rename to src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy From 290b97e2aea44b2cedfafe991cf8ecb7fdf50567 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 13:19:06 +0200 Subject: [PATCH 347/719] formatting --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2338faf156..148e14a36f 100644 --- a/README.md +++ b/README.md @@ -27,10 +27,10 @@ Sample usage Project default directories --- -Contract definitions (_contractsDir_): +_contractsDir_ - contract definitions: /src/test/resources/contracts -Generated accurest specifications (_generatedTestSourcesDir_): +_generatedTestSourcesDir_ - Generated accurest specifications: /target/generated-test-sources/accurest From 3977f352f319036dd1e5dad720c8b30afdb9963b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 13:19:37 +0200 Subject: [PATCH 348/719] fix --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 148e14a36f..1e3b88a936 100644 --- a/README.md +++ b/README.md @@ -22,8 +22,6 @@ Sample usage ``` -``` - Project default directories --- From 252cf3e06828bd3dd69460671c04e3d788c9870c Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 13:29:08 +0200 Subject: [PATCH 349/719] fix simpleBoot it test --- .../io/codearte/accurest/maven/PluginIntegrationTest.java | 3 ++- src/test/projects/bootSimple/pom.xml | 7 +------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java index 5f3b2626f0..9cb929fd10 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java @@ -47,6 +47,7 @@ public class PluginIntegrationTest { maven.forProject(basedir) .execute("package") .assertErrorFreeLog() - .assertLogText("Accurest Plugin: Invoking test sources generation"); + .assertLogText("Accurest Plugin: Invoking test sources generation") + .assertLogText("Generated 1 test classes."); } } \ No newline at end of file diff --git a/src/test/projects/bootSimple/pom.xml b/src/test/projects/bootSimple/pom.xml index 0a5de4800d..79ce6f2a4d 100644 --- a/src/test/projects/bootSimple/pom.xml +++ b/src/test/projects/bootSimple/pom.xml @@ -100,7 +100,7 @@ com.ofg.twitter.place.BaseMockMvcSpec - /src/test/resources/stubs + /src/test/resources/stubs @@ -111,13 +111,8 @@ addSources - addTestSources - generateStubs compile - testGenerateStubs testCompile - removeStubs - removeTestStubs From 7c4f6de2d1a5d78d5445fb20abdbfcadf94dc5c0 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 14:06:47 +0200 Subject: [PATCH 350/719] base class for tests is optional --- .../java/io/codearte/accurest/maven/GenerateSpecsMojo.java | 2 +- src/test/projects/basic-with-execution/pom.xml | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 670b68f619..0634c94508 100644 --- a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -33,7 +33,7 @@ public class GenerateSpecsMojo extends AbstractMojo { @Parameter(property = "basePackageForTests", defaultValue = "io.codearte.accurest.tests") private String basePackageForTests; - @Parameter(property = "baseClassForTests", required = true) + @Parameter(property = "baseClassForTests") private String baseClassForTests; public GenerateSpecsMojo() { diff --git a/src/test/projects/basic-with-execution/pom.xml b/src/test/projects/basic-with-execution/pom.xml index 8f5f9d6b65..40d5b17c72 100644 --- a/src/test/projects/basic-with-execution/pom.xml +++ b/src/test/projects/basic-with-execution/pom.xml @@ -60,9 +60,6 @@ - - com.ofg.twitter.place.BaseMockMvcSpec - org.codehaus.gmavenplus From 2f39d77fcc594f955dba020afdca8f960325c93f Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 17:12:29 +0200 Subject: [PATCH 351/719] publishing stubs to repository --- README.md | 46 +++++ maven-plugin/pom.xml | 126 ++++++++++++ .../accurest/maven/GenerateSpecsMojo.java | 0 .../accurest/maven/GenerateStubsMojo.java | 0 .../accurest/maven/PluginIntegrationTest.java | 0 .../accurest/maven/PluginUnitTest.java | 0 .../projects/basic-with-execution/pom.xml | 0 .../test/resources/contracts/Sample.groovy | 0 .../src}/test/projects/basic/pom.xml | 0 .../test/resources/contracts/Sample.groovy | 0 .../src}/test/projects/bootSimple/pom.xml | 70 +++---- .../ofg/twitter/place/PairIdController.groovy | 0 .../groovy/com/ofg/twitter/place/Tweet.java | 0 .../sample/SampleSimpleBootApplication.java | 0 .../src/main/resources/application.properties | 0 .../ofg/twitter/place/AcceptanceSpec.groovy | 0 .../ofg/twitter/place/BaseMockMvcSpec.groovy | 0 .../SampleSimpleBootApplicationTests.java | 0 .../src/test/resources/logback-test.groovy | 0 .../stubs/collerate_PlacesFrom_Tweet.groovy | 0 .../resources/stubs/moreComplexVersion.groovy | 0 .../src}/test/projects/withStubs/pom.xml | 0 .../src/test/resources/stubs/Sample.groovy | 0 pom.xml | 180 ++++++++---------- stubs-assembly-descriptor/pom.xml | 15 ++ .../src/main/resources/assemblies/stubs.xml | 19 ++ test-deps/pom.xml | 48 +++++ 27 files changed, 359 insertions(+), 145 deletions(-) create mode 100644 maven-plugin/pom.xml rename {src => maven-plugin/src}/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java (100%) rename {src => maven-plugin/src}/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java (100%) rename {src => maven-plugin/src}/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java (100%) rename {src => maven-plugin/src}/test/java/io/codearte/accurest/maven/PluginUnitTest.java (100%) rename {src => maven-plugin/src}/test/projects/basic-with-execution/pom.xml (100%) rename {src => maven-plugin/src}/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy (100%) rename {src => maven-plugin/src}/test/projects/basic/pom.xml (100%) rename {src => maven-plugin/src}/test/projects/basic/src/test/resources/contracts/Sample.groovy (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/pom.xml (73%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/main/resources/application.properties (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/test/resources/logback-test.groovy (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy (100%) rename {src => maven-plugin/src}/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy (100%) rename {src => maven-plugin/src}/test/projects/withStubs/pom.xml (100%) rename {src => maven-plugin/src}/test/projects/withStubs/src/test/resources/stubs/Sample.groovy (100%) create mode 100644 stubs-assembly-descriptor/pom.xml create mode 100644 stubs-assembly-descriptor/src/main/resources/assemblies/stubs.xml create mode 100644 test-deps/pom.xml diff --git a/README.md b/README.md index 1e3b88a936..31ea088395 100644 --- a/README.md +++ b/README.md @@ -32,3 +32,49 @@ _contractsDir_ - contract definitions: _generatedTestSourcesDir_ - Generated accurest specifications: /target/generated-test-sources/accurest + +Publishing wiremock stubs (projectF-stubs.jar) +--- + +Project configuration + +```xml + + io.codearte.accurest + accurest-maven-plugin + ${accurest.version} + + + + generateStubs + + + + + + maven-assembly-plugin + 2.6 + + + io.codearte.accurest + stubs-assembly-descriptor + ${accurest.version} + + + + + package + + single + + + + + + stubs + + + +``` + +Deploy to artifact repository using `mvn deploy` diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml new file mode 100644 index 0000000000..19ccaca94b --- /dev/null +++ b/maven-plugin/pom.xml @@ -0,0 +1,126 @@ + + + 4.0.0 + + + io.codearte.accurest + accurest-maven-project + 1.0-SNAPSHOT + + + accurest-maven-plugin + takari-maven-plugin + + + + io.codearte.accurest + accurest-core + 1.0.1 + + + io.codearte.accurest + accurest-converters + 1.0.1 + + + ch.qos.logback + logback-classic + 1.1.6 + test + + + + org.codehaus.groovy + groovy-all + 2.4.6 + + + + org.apache.maven + maven-core + ${mavenVersion} + test + + + org.apache.maven + maven-compat + ${mavenVersion} + test + + + + org.apache.maven + maven-plugin-api + ${mavenVersion} + provided + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${mavenPluginPluginVersion} + provided + + + + io.takari.maven.plugins + takari-plugin-testing + 2.8.0 + test + + + io.takari.maven.plugins + takari-plugin-integration-testing + 2.8.0 + pom + test + + + junit + junit + 4.12 + test + + + + + + io.takari.maven.plugins + takari-lifecycle-plugin + 1.11.12 + true + + none + + + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + prepare-agent + + prepare-agent + + + + report + + report + + + + + + + org.eluder.coveralls + coveralls-maven-plugin + 4.1.0 + + + + + + \ No newline at end of file diff --git a/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java similarity index 100% rename from src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java rename to maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java similarity index 100% rename from src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java rename to maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java diff --git a/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java similarity index 100% rename from src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java rename to maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java similarity index 100% rename from src/test/java/io/codearte/accurest/maven/PluginUnitTest.java rename to maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java diff --git a/src/test/projects/basic-with-execution/pom.xml b/maven-plugin/src/test/projects/basic-with-execution/pom.xml similarity index 100% rename from src/test/projects/basic-with-execution/pom.xml rename to maven-plugin/src/test/projects/basic-with-execution/pom.xml diff --git a/src/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy b/maven-plugin/src/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy similarity index 100% rename from src/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy rename to maven-plugin/src/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy diff --git a/src/test/projects/basic/pom.xml b/maven-plugin/src/test/projects/basic/pom.xml similarity index 100% rename from src/test/projects/basic/pom.xml rename to maven-plugin/src/test/projects/basic/pom.xml diff --git a/src/test/projects/basic/src/test/resources/contracts/Sample.groovy b/maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy similarity index 100% rename from src/test/projects/basic/src/test/resources/contracts/Sample.groovy rename to maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy diff --git a/src/test/projects/bootSimple/pom.xml b/maven-plugin/src/test/projects/bootSimple/pom.xml similarity index 73% rename from src/test/projects/bootSimple/pom.xml rename to maven-plugin/src/test/projects/bootSimple/pom.xml index 79ce6f2a4d..7dadbb7344 100644 --- a/src/test/projects/bootSimple/pom.xml +++ b/maven-plugin/src/test/projects/bootSimple/pom.xml @@ -21,6 +21,7 @@ UTF-8 1.8 + ${it-plugin.version} @@ -28,55 +29,22 @@ org.springframework.boot spring-boot-starter-web - org.springframework.boot spring-boot-starter-test test - org.codehaus.groovy groovy-all - - org.spockframework - spock-core - 1.0-groovy-2.4 - test - - - com.jayway.restassured - rest-assured - 2.9.0 - test - - - com.jayway.restassured - spring-mock-mvc - 2.9.0 - test - - - com.github.tomakehurst - wiremock - 2.0.4-beta - test - - - com.toomuchcoding.jsonassert - jsonassert - 0.2.2 - test - - - org.assertj - assertj-core - 2.3.0 - test + io.codearte.accurest + accurest-test-deps + ${accurest.version} + pom @@ -89,7 +57,7 @@ io.codearte.accurest accurest-maven-plugin - ${it-plugin.version} + ${accurest.version} @@ -142,8 +110,30 @@ + + maven-assembly-plugin + 2.6 + + + io.codearte.accurest + stubs-assembly-descriptor + ${accurest.version} + + + + + package + + single + + + + + + stubs + + + - -
diff --git a/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/maven-plugin/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy similarity index 100% rename from src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy rename to maven-plugin/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy diff --git a/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java b/maven-plugin/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java similarity index 100% rename from src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java rename to maven-plugin/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java diff --git a/src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java b/maven-plugin/src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java similarity index 100% rename from src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java rename to maven-plugin/src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java diff --git a/src/test/projects/bootSimple/src/main/resources/application.properties b/maven-plugin/src/test/projects/bootSimple/src/main/resources/application.properties similarity index 100% rename from src/test/projects/bootSimple/src/main/resources/application.properties rename to maven-plugin/src/test/projects/bootSimple/src/main/resources/application.properties diff --git a/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy b/maven-plugin/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy similarity index 100% rename from src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy rename to maven-plugin/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy diff --git a/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy b/maven-plugin/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy similarity index 100% rename from src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy rename to maven-plugin/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy diff --git a/src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java b/maven-plugin/src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java similarity index 100% rename from src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java rename to maven-plugin/src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java diff --git a/src/test/projects/bootSimple/src/test/resources/logback-test.groovy b/maven-plugin/src/test/projects/bootSimple/src/test/resources/logback-test.groovy similarity index 100% rename from src/test/projects/bootSimple/src/test/resources/logback-test.groovy rename to maven-plugin/src/test/projects/bootSimple/src/test/resources/logback-test.groovy diff --git a/src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy b/maven-plugin/src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy similarity index 100% rename from src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy rename to maven-plugin/src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy diff --git a/src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy b/maven-plugin/src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy similarity index 100% rename from src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy rename to maven-plugin/src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy diff --git a/src/test/projects/withStubs/pom.xml b/maven-plugin/src/test/projects/withStubs/pom.xml similarity index 100% rename from src/test/projects/withStubs/pom.xml rename to maven-plugin/src/test/projects/withStubs/pom.xml diff --git a/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy b/maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy similarity index 100% rename from src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy rename to maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy diff --git a/pom.xml b/pom.xml index 72faff14f2..8edbc6c529 100644 --- a/pom.xml +++ b/pom.xml @@ -5,10 +5,16 @@ 4.0.0 io.codearte.accurest - accurest-maven-plugin + accurest-maven-project 1.0-SNAPSHOT - takari-maven-plugin + + stubs-assembly-descriptor + test-deps + maven-plugin + + + pom 3.2.5 @@ -50,114 +56,78 @@ - - - io.codearte.accurest - accurest-core - 1.0.1 - - - io.codearte.accurest - accurest-converters - 1.0.1 - - - ch.qos.logback - logback-classic - 1.1.6 - test - + + + + io.codearte.accurest + accurest-core + 1.0.1 + + + io.codearte.accurest + accurest-converters + 1.0.1 + + + ch.qos.logback + logback-classic + 1.1.6 + test + - - org.codehaus.groovy - groovy-all - 2.4.6 - + + org.codehaus.groovy + groovy-all + 2.4.6 + - - org.apache.maven - maven-core - ${mavenVersion} - test - - - org.apache.maven - maven-compat - ${mavenVersion} - test - + + org.apache.maven + maven-core + ${mavenVersion} + test + + + org.apache.maven + maven-compat + ${mavenVersion} + test + - - org.apache.maven - maven-plugin-api - ${mavenVersion} - provided - - - org.apache.maven.plugin-tools - maven-plugin-annotations - ${mavenPluginPluginVersion} - provided - + + org.apache.maven + maven-plugin-api + ${mavenVersion} + provided + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${mavenPluginPluginVersion} + provided + - - io.takari.maven.plugins - takari-plugin-testing - 2.8.0 - test - - - io.takari.maven.plugins - takari-plugin-integration-testing - 2.8.0 - pom - test - - - junit - junit - 4.12 - test - - - - - + io.takari.maven.plugins - takari-lifecycle-plugin - 1.11.12 - true - - none - - - - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - prepare-agent - - prepare-agent - - - - report - - report - - - - - - - org.eluder.coveralls - coveralls-maven-plugin - 4.1.0 - - - + takari-plugin-testing + 2.8.0 + test + + + io.takari.maven.plugins + takari-plugin-integration-testing + 2.8.0 + pom + test + + + junit + junit + 4.12 + test + + + diff --git a/stubs-assembly-descriptor/pom.xml b/stubs-assembly-descriptor/pom.xml new file mode 100644 index 0000000000..96d9ad628f --- /dev/null +++ b/stubs-assembly-descriptor/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + + + io.codearte.accurest + accurest-maven-project + 1.0-SNAPSHOT + + + stubs-assembly-descriptor + + \ No newline at end of file diff --git a/stubs-assembly-descriptor/src/main/resources/assemblies/stubs.xml b/stubs-assembly-descriptor/src/main/resources/assemblies/stubs.xml new file mode 100644 index 0000000000..74c49b880b --- /dev/null +++ b/stubs-assembly-descriptor/src/main/resources/assemblies/stubs.xml @@ -0,0 +1,19 @@ + + stubs + + jar + + false + + + ${project.build.directory} + + mappings/** + + / + true + + + diff --git a/test-deps/pom.xml b/test-deps/pom.xml new file mode 100644 index 0000000000..0b6af3d4da --- /dev/null +++ b/test-deps/pom.xml @@ -0,0 +1,48 @@ + + + 4.0.0 + + + accurest-maven-project + io.codearte.accurest + 1.0-SNAPSHOT + + + accurest-test-deps + pom + + + + org.spockframework + spock-core + 1.0-groovy-2.4 + + + com.jayway.restassured + rest-assured + 2.9.0 + + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + + + com.github.tomakehurst + wiremock + 2.0.4-beta + + + com.toomuchcoding.jsonassert + jsonassert + 0.2.2 + + + org.assertj + assertj-core + 2.3.0 + + + \ No newline at end of file From 538b946c5a3bde1c90c5e8b0aaf104f5e69738b6 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 28 Mar 2016 22:28:28 +0200 Subject: [PATCH 352/719] Added a possibility to build fat-jars of stub-runner --- build.gradle | 2 ++ stub-runner/stub-runner/README.md | 16 +++++++++++++++- stub-runner/stub-runner/build.gradle | 23 +++++++++++++++++++++++ 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 313e58fb19..ba9586b76a 100644 --- a/build.gradle +++ b/build.gradle @@ -2,11 +2,13 @@ buildscript { repositories { mavenCentral() mavenLocal() + if (project.hasProperty('fatJar')) jcenter() } dependencies { classpath "pl.allegro.tech.build:axion-release-plugin:1.3.4" 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' } } diff --git a/stub-runner/stub-runner/README.md b/stub-runner/stub-runner/README.md index bd148045da..2a749ebb39 100644 --- a/stub-runner/stub-runner/README.md +++ b/stub-runner/stub-runner/README.md @@ -11,7 +11,6 @@ Runs stubs for service collaborators. Treating stubs as contracts of services al You can set the following options to the main class: ``` -java -jar stub-runner.jar [options...] -maxp (--maxPort) N : Maximum port value to be assigned to the Wiremock instance. Defaults to 15000 (default: 15000) @@ -33,6 +32,21 @@ java -jar stub-runner.jar [options...] ``` + +#### Building a Fat Jar + +Just call the following command: + +``` +./gradlew stub-runner-root:stub-runner:shadowJar -PfatJar +``` + +and inside the `build/lib` there will be a Fat Jar with classifier `fatJar` waiting for you to execute. E.g. + +``` +java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h +``` + ### Stub runner configuration You can configure the stub runner by either passing the full arguments list with the `-Pargs` like this: diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index 63c8faa6ff..3fa0ed3b75 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -11,6 +11,8 @@ dependencies { compile 'args4j:args4j:2.32' compile 'com.nurkiewicz.asyncretry:asyncretry-jdk7:0.0.6' + if (rootProject.hasProperty("fatJar")) runtime 'ch.qos.logback:logback-classic:1.1.3' + testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { exclude(group: 'org.codehaus.groovy') } @@ -71,3 +73,24 @@ Object appendToListIfNotNull(String argument, String prefix, List list) { } } } + +if (rootProject.hasProperty("fatJar")) { + + apply plugin: 'com.github.johnrengelman.shadow' + apply plugin: 'maven-publish' + + publishing { + publications { + shadow(MavenPublication) { + from components.java + artifact shadowJar + } + } + } + + shadowJar { + classifier = 'fatJar' + dependsOn build + } + +} \ No newline at end of file From 033a7b7df6d40a37dee4167e13a8c41e2f02c601 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 23:41:27 +0200 Subject: [PATCH 353/719] license --- LICENSE | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- 2 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..269e9b6ea0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2016 Codearte + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. \ No newline at end of file diff --git a/README.md b/README.md index 31ea088395..d746cb3866 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ _generatedTestSourcesDir_ - Generated accurest specifications: /target/generated-test-sources/accurest -Publishing wiremock stubs (projectF-stubs.jar) +Publishing wiremock stubs jar --- Project configuration From a77852e3477d32a3ba1503517c33655350f33240 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 28 Mar 2016 23:45:51 +0200 Subject: [PATCH 354/719] Markdown license --- LICENSE | 201 ----------------------------------------------------- LICENSE.md | 194 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 194 insertions(+), 201 deletions(-) delete mode 100644 LICENSE create mode 100644 LICENSE.md diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 269e9b6ea0..0000000000 --- a/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright 2016 Codearte - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000000..74640422d1 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,194 @@ +Apache License +============== + +_Version 2.0, January 2004_ +_<>_ + +### Terms and Conditions for use, reproduction, and distribution + +#### 1. Definitions + +“License” shall mean the terms and conditions for use, reproduction, and +distribution as defined by Sections 1 through 9 of this document. + +“Licensor” shall mean the copyright owner or entity authorized by the copyright +owner that is granting the License. + +“Legal Entity” shall mean the union of the acting entity and all other entities +that control, are controlled by, or are under common control with that entity. +For the purposes of this definition, “control” means **(i)** the power, direct or +indirect, to cause the direction or management of such entity, whether by +contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the +outstanding shares, or **(iii)** beneficial ownership of such entity. + +“You” (or “Your”) shall mean an individual or Legal Entity exercising +permissions granted by this License. + +“Source” form shall mean the preferred form for making modifications, including +but not limited to software source code, documentation source, and configuration +files. + +“Object” form shall mean any form resulting from mechanical transformation or +translation of a Source form, including but not limited to compiled object code, +generated documentation, and conversions to other media types. + +“Work” shall mean the work of authorship, whether in Source or Object form, made +available under the License, as indicated by a copyright notice that is included +in or attached to the work (an example is provided in the Appendix below). + +“Derivative Works” shall mean any work, whether in Source or Object form, that +is based on (or derived from) the Work and for which the editorial revisions, +annotations, elaborations, or other modifications represent, as a whole, an +original work of authorship. For the purposes of this License, Derivative Works +shall not include works that remain separable from, or merely link (or bind by +name) to the interfaces of, the Work and Derivative Works thereof. + +“Contribution” shall mean any work of authorship, including the original version +of the Work and any modifications or additions to that Work or Derivative Works +thereof, that is intentionally submitted to Licensor for inclusion in the Work +by the copyright owner or by an individual or Legal Entity authorized to submit +on behalf of the copyright owner. For the purposes of this definition, +“submitted” means any form of electronic, verbal, or written communication sent +to the Licensor or its representatives, including but not limited to +communication on electronic mailing lists, source code control systems, and +issue tracking systems that are managed by, or on behalf of, the Licensor for +the purpose of discussing and improving the Work, but excluding communication +that is conspicuously marked or otherwise designated in writing by the copyright +owner as “Not a Contribution.” + +“Contributor” shall mean Licensor and any individual or Legal Entity on behalf +of whom a Contribution has been received by Licensor and subsequently +incorporated within the Work. + +#### 2. Grant of Copyright License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable copyright license to reproduce, prepare Derivative Works of, +publicly display, publicly perform, sublicense, and distribute the Work and such +Derivative Works in Source or Object form. + +#### 3. Grant of Patent License + +Subject to the terms and conditions of this License, each Contributor hereby +grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, +irrevocable (except as stated in this section) patent license to make, have +made, use, offer to sell, sell, import, and otherwise transfer the Work, where +such license applies only to those patent claims licensable by such Contributor +that are necessarily infringed by their Contribution(s) alone or by combination +of their Contribution(s) with the Work to which such Contribution(s) was +submitted. If You institute patent litigation against any entity (including a +cross-claim or counterclaim in a lawsuit) alleging that the Work or a +Contribution incorporated within the Work constitutes direct or contributory +patent infringement, then any patent licenses granted to You under this License +for that Work shall terminate as of the date such litigation is filed. + +#### 4. Redistribution + +You may reproduce and distribute copies of the Work or Derivative Works thereof +in any medium, with or without modifications, and in Source or Object form, +provided that You meet the following conditions: + +* **(a)** You must give any other recipients of the Work or Derivative Works a copy of +this License; and +* **(b)** You must cause any modified files to carry prominent notices stating that You +changed the files; and +* **(c)** You must retain, in the Source form of any Derivative Works that You distribute, +all copyright, patent, trademark, and attribution notices from the Source form +of the Work, excluding those notices that do not pertain to any part of the +Derivative Works; and +* **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any +Derivative Works that You distribute must include a readable copy of the +attribution notices contained within such NOTICE file, excluding those notices +that do not pertain to any part of the Derivative Works, in at least one of the +following places: within a NOTICE text file distributed as part of the +Derivative Works; within the Source form or documentation, if provided along +with the Derivative Works; or, within a display generated by the Derivative +Works, if and wherever such third-party notices normally appear. The contents of +the NOTICE file are for informational purposes only and do not modify the +License. You may add Your own attribution notices within Derivative Works that +You distribute, alongside or as an addendum to the NOTICE text from the Work, +provided that such additional attribution notices cannot be construed as +modifying the License. + +You may add Your own copyright statement to Your modifications and may provide +additional or different license terms and conditions for use, reproduction, or +distribution of Your modifications, or for any such Derivative Works as a whole, +provided Your use, reproduction, and distribution of the Work otherwise complies +with the conditions stated in this License. + +#### 5. Submission of Contributions + +Unless You explicitly state otherwise, any Contribution intentionally submitted +for inclusion in the Work by You to the Licensor shall be under the terms and +conditions of this License, without any additional terms or conditions. +Notwithstanding the above, nothing herein shall supersede or modify the terms of +any separate license agreement you may have executed with Licensor regarding +such Contributions. + +#### 6. Trademarks + +This License does not grant permission to use the trade names, trademarks, +service marks, or product names of the Licensor, except as required for +reasonable and customary use in describing the origin of the Work and +reproducing the content of the NOTICE file. + +#### 7. Disclaimer of Warranty + +Unless required by applicable law or agreed to in writing, Licensor provides the +Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, +including, without limitation, any warranties or conditions of TITLE, +NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are +solely responsible for determining the appropriateness of using or +redistributing the Work and assume any risks associated with Your exercise of +permissions under this License. + +#### 8. Limitation of Liability + +In no event and under no legal theory, whether in tort (including negligence), +contract, or otherwise, unless required by applicable law (such as deliberate +and grossly negligent acts) or agreed to in writing, shall any Contributor be +liable to You for damages, including any direct, indirect, special, incidental, +or consequential damages of any character arising as a result of this License or +out of the use or inability to use the Work (including but not limited to +damages for loss of goodwill, work stoppage, computer failure or malfunction, or +any and all other commercial damages or losses), even if such Contributor has +been advised of the possibility of such damages. + +#### 9. Accepting Warranty or Additional Liability + +While redistributing the Work or Derivative Works thereof, You may choose to +offer, and charge a fee for, acceptance of support, warranty, indemnity, or +other liability obligations and/or rights consistent with this License. However, +in accepting such obligations, You may act only on Your own behalf and on Your +sole responsibility, not on behalf of any other Contributor, and only if You +agree to indemnify, defend, and hold each Contributor harmless for any liability +incurred by, or claims asserted against, such Contributor by reason of your +accepting any such warranty or additional liability. + +_END OF TERMS AND CONDITIONS_ + +### APPENDIX: How to apply the Apache License to your work + +To apply the Apache License to your work, attach the following boilerplate +notice, with the fields enclosed by brackets `[]` replaced with your own +identifying information. (Don't include the brackets!) The text should be +enclosed in the appropriate comment syntax for the file format. We also +recommend that a file or class name and description of purpose be included on +the same “printed page” as the copyright notice for easier identification within +third-party archives. + + Copyright 2016 Codearte + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From b783a09519b5ba473b0e01faedc68514286d407e Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 29 Mar 2016 22:24:45 +0200 Subject: [PATCH 355/719] refactoring, oss data --- README.md | 2 +- maven-plugin/pom.xml | 15 ++- .../src/test/projects/bootSimple/pom.xml | 2 +- pom.xml | 91 ++++++------------- stubs-assembly-descriptor/pom.xml | 15 --- .../src/main/resources/assemblies/stubs.xml | 19 ---- 6 files changed, 38 insertions(+), 106 deletions(-) delete mode 100644 stubs-assembly-descriptor/pom.xml delete mode 100644 stubs-assembly-descriptor/src/main/resources/assemblies/stubs.xml diff --git a/README.md b/README.md index d746cb3866..e802a129ba 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Project configuration io.codearte.accurest stubs-assembly-descriptor - ${accurest.version} + 1.0 diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 19ccaca94b..ca967ac381 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -17,20 +17,11 @@ io.codearte.accurest accurest-core - 1.0.1 io.codearte.accurest accurest-converters - 1.0.1 - - ch.qos.logback - logback-classic - 1.1.6 - test - - org.codehaus.groovy groovy-all @@ -82,6 +73,12 @@ 4.12 test + + ch.qos.logback + logback-core + 1.1.6 + test + diff --git a/maven-plugin/src/test/projects/bootSimple/pom.xml b/maven-plugin/src/test/projects/bootSimple/pom.xml index 7dadbb7344..325a46dd11 100644 --- a/maven-plugin/src/test/projects/bootSimple/pom.xml +++ b/maven-plugin/src/test/projects/bootSimple/pom.xml @@ -117,7 +117,7 @@ io.codearte.accurest stubs-assembly-descriptor - ${accurest.version} + 1.0 diff --git a/pom.xml b/pom.xml index 8edbc6c529..c5551963c6 100644 --- a/pom.xml +++ b/pom.xml @@ -8,8 +8,11 @@ accurest-maven-project 1.0-SNAPSHOT + Accurate Maven Plugin + Accurate REST Maven Plugin + https://github.com/Codearte/accurest-maven-plugin + - stubs-assembly-descriptor test-deps maven-plugin @@ -20,11 +23,20 @@ 3.2.5 + + + mariuszs + Mariusz Smykula + mariuszs@gmail.com + + + 3.2.5 3.4 UTF-8 + 1.0.1 @@ -56,75 +68,32 @@ + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + false + true + true + + + + + io.codearte.accurest accurest-core - 1.0.1 + ${accurest.version} io.codearte.accurest accurest-converters - 1.0.1 - - - ch.qos.logback - logback-classic - 1.1.6 - test - - - - org.codehaus.groovy - groovy-all - 2.4.6 - - - - org.apache.maven - maven-core - ${mavenVersion} - test - - - org.apache.maven - maven-compat - ${mavenVersion} - test - - - - org.apache.maven - maven-plugin-api - ${mavenVersion} - provided - - - org.apache.maven.plugin-tools - maven-plugin-annotations - ${mavenPluginPluginVersion} - provided - - - - io.takari.maven.plugins - takari-plugin-testing - 2.8.0 - test - - - io.takari.maven.plugins - takari-plugin-integration-testing - 2.8.0 - pom - test - - - junit - junit - 4.12 - test + ${accurest.version} diff --git a/stubs-assembly-descriptor/pom.xml b/stubs-assembly-descriptor/pom.xml deleted file mode 100644 index 96d9ad628f..0000000000 --- a/stubs-assembly-descriptor/pom.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - 4.0.0 - - - io.codearte.accurest - accurest-maven-project - 1.0-SNAPSHOT - - - stubs-assembly-descriptor - - \ No newline at end of file diff --git a/stubs-assembly-descriptor/src/main/resources/assemblies/stubs.xml b/stubs-assembly-descriptor/src/main/resources/assemblies/stubs.xml deleted file mode 100644 index 74c49b880b..0000000000 --- a/stubs-assembly-descriptor/src/main/resources/assemblies/stubs.xml +++ /dev/null @@ -1,19 +0,0 @@ - - stubs - - jar - - false - - - ${project.build.directory} - - mappings/** - - / - true - - - From 37cee4ccda9e1f8ac94c547f2f6bec15d2ae3350 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 29 Mar 2016 22:40:20 +0200 Subject: [PATCH 356/719] Spring Cloud integration --- .../dsl/WireMockRequestStubStrategy.groovy | 2 +- build.gradle | 12 +++ settings.gradle | 1 + .../stubrunner/junit/AccurestRule.java | 2 +- .../stub-runner-spring-cloud/README.md | 13 +++ .../stub-runner-spring-cloud/build.gradle | 25 +++++ .../spring/cloud/StubMapperProperties.java | 55 ++++++++++ .../cloud/StubRunnerDiscoveryClient.java | 72 ++++++++++++++ .../cloud/StubRunnerServiceInstance.java | 57 +++++++++++ ...tubRunnerSpringCloudAutoConfiguration.java | 39 ++++++++ .../StubRunnerRibbonAutoConfiguration.java | 17 ++++ .../ribbon/StubRunnerRibbonConfiguration.java | 94 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 4 + ...nerSpringCloudAutoConfigurationSpec.groovy | 58 +++++++++++ .../src/test/resources/application.yml | 6 ++ .../src/test/resources/logback.xml | 14 +++ ...udDetectionServer-stubs-0.0.1-SNAPSHOT.jar | Bin 0 -> 1733 bytes ...udDetectionServer-stubs-0.0.1-SNAPSHOT.pom | 8 ++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 +++ .../maven-metadata-local.xml | 11 ++ .../loanIssuance-stubs-0.0.1-SNAPSHOT.jar | Bin 0 -> 587 bytes .../loanIssuance-stubs-0.0.1-SNAPSHOT.pom | 8 ++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 +++ .../maven-metadata-local.xml | 11 ++ stub-runner/stub-runner-spring/README.md | 2 +- stub-runner/stub-runner-spring/build.gradle | 4 +- .../spring/StubRunnerConfiguration.java | 2 +- .../src/test/resources/application.yml | 2 +- stub-runner/stub-runner/build.gradle | 1 - .../accurest/stubrunner/RunningStubs.groovy | 34 +++---- 30 files changed, 553 insertions(+), 25 deletions(-) create mode 100644 stub-runner/stub-runner-spring-cloud/README.md create mode 100644 stub-runner/stub-runner-spring-cloud/build.gradle create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index 194a405237..1c3bbb6016 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -68,7 +68,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT, equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ] } else { - requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath().replace("\\\\", "\\")) } ?: null + requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath().replace("\\\\", "\\")) } ?: null as List } } else if (contentType == ContentType.XML) { requestPattern.bodyPatterns = [new ValuePattern(equalToXml: getMatchingStrategy(request.body.clientValue).clientValue.toString())] diff --git a/build.gradle b/build.gradle index ba9586b76a..96908af878 100644 --- a/build.gradle +++ b/build.gradle @@ -61,6 +61,18 @@ subprojects { exclude(group: 'org.codehaus.groovy') } } + + // fixing the groovydoc issue http://stackoverflow.com/questions/20618857/gradle-task-groovydoc-failing-with-noclassdeffounderror + configurations { + jansi.extendsFrom(runtime) + } + groovydoc { + def title = "IPDS ${version}" + groovyClasspath = project.configurations.jansi + } + dependencies { + jansi 'org.fusesource.jansi:jansi:1.11' + } } project(':accurest-core') { diff --git a/settings.gradle b/settings.gradle index 762abc0c49..cbe81d5e33 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ include "accurest-core", "accurest-gradle-plugin", 'accurest-converters', 'accurest-testing-utils' include ':stub-runner:stub-runner' include ':stub-runner:stub-runner-spring' +include ':stub-runner:stub-runner-spring-cloud' include ':stub-runner:stub-runner-junit' rootProject.name = "accurest" diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index 6236e5d710..a47e4e9e8d 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -58,7 +58,7 @@ public class AccurestRule implements TestRule, StubFinder { String repoRoot = System.getProperty("stubrunner.stubs.repository.root", ""); String stubSuffix = System.getProperty("stubrunner.stubs.classifier", "stubs"); Boolean workOffline = Boolean.parseBoolean(System.getProperty("stubrunner.work-offline", "false")); - String stubsToDownload = System.getProperty("stubrunner.stubs", ""); + String stubsToDownload = System.getProperty("stubrunner.stubs.ids", ""); if (StringUtils.hasText(stubsToDownload)) { Collections.addAll(stubs, stubsToDownload.split(",")); } diff --git a/stub-runner/stub-runner-spring-cloud/README.md b/stub-runner/stub-runner-spring-cloud/README.md new file mode 100644 index 0000000000..06399b13a0 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/README.md @@ -0,0 +1,13 @@ +stub-runner-spring-cloud +======================== + +Registers the stubs in the provided Service Discovery. It's enough to add the jar + +``` +io.codearte.accurest:stub-runner-spring-cloud +``` + +and the Stub Runner autoconfiguration should be picked up. + +In order to find the registered server via service discovery, you have to use the +`artifactId` as the name of the application \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/build.gradle b/stub-runner/stub-runner-spring-cloud/build.gradle new file mode 100644 index 0000000000..96d86c8ac1 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/build.gradle @@ -0,0 +1,25 @@ +description = 'Spring configuration for stub-runner' + +dependencies { + compile project(':stub-runner-root:stub-runner-spring') + + compile localGroovy() + compile 'org.springframework.cloud:spring-cloud-starter:[1.1.0.RC2,)' + // TODO: should be compile only + compile 'org.springframework.cloud:spring-cloud-starter-ribbon:[1.1.0.RC1,)' + + testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + testCompile 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery:1.0.0.RC1' + testCompile 'org.apache.curator:curator-test:2.9.1' + testCompile 'io.reactivex:rxjava:1.1.1' + testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework:spring-web:4.2.5.RELEASE" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'ch.qos.logback:logback-classic:1.1.3' +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java new file mode 100644 index 0000000000..c69ca674dc --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java @@ -0,0 +1,55 @@ +package io.codearte.accurest.stubrunner.spring.cloud; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * Maps Ivy based ids to service Ids. You might want to name the service you're calling + * in another way than artifact id. If that's the case then this class should be used + * to change do the proper mapping. + * + * Just provide in your properties file for example: + * + * stubrunner.stubs.idsToServiceIds: + * ivyNotation: someValueInsideYourCode + * fraudDetectionServer: someNameThatShouldMapFraudDetectionServer + * + * @author Marcin Grzejszczak + */ +@ConfigurationProperties("stubrunner.stubs") +public class StubMapperProperties { + + /** + * Mapping of Ivy notation based ids to serviceIds + * inside your application + * + * Example + * + * "a:b" -> "myService" + * "artifactId" -> "myOtherService" + */ + private Map idsToServiceIds = new HashMap<>(); + + public Map getIdsToServiceIds() { + return this.idsToServiceIds; + } + + public void setIdsToServiceIds(Map idsToServiceIds) { + this.idsToServiceIds = idsToServiceIds; + } + + public String fromIvyNotationToId(String ivyNotation) { + return idsToServiceIds.get(ivyNotation); + } + + public String fromServiceIdToIvyNotation(String serviceId) { + for (Map.Entry entry : idsToServiceIds.entrySet()) { + if (entry.getValue().equals(serviceId)) { + return entry.getKey(); + } + } + return null; + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java new file mode 100644 index 0000000000..66b7deb07e --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java @@ -0,0 +1,72 @@ +package io.codearte.accurest.stubrunner.spring.cloud; + +import java.net.URI; +import java.net.URL; +import java.util.Collections; +import java.util.List; + +import org.springframework.cloud.client.ServiceInstance; +import org.springframework.cloud.client.discovery.DiscoveryClient; + +import io.codearte.accurest.stubrunner.RunningStubs; +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.util.StringUtils; + +/** + * Custom version of {@link DiscoveryClient} that tries to find an instance + * in one of the started WireMock servers + * + * @author Marcin Grzejszczak + */ +public class StubRunnerDiscoveryClient implements DiscoveryClient { + + private final DiscoveryClient delegate; + private final StubFinder stubFinder; + private final StubMapperProperties stubMapperProperties; + + public StubRunnerDiscoveryClient(DiscoveryClient delegate, StubFinder stubFinder, + StubMapperProperties stubMapperProperties) { + this.delegate = delegate; + this.stubFinder = stubFinder; + this.stubMapperProperties = stubMapperProperties; + } + + @Override + public String description() { + return delegate.description(); + } + + @Override + public ServiceInstance getLocalServiceInstance() { + return delegate.getLocalServiceInstance(); + } + + @Override + public List getInstances(String serviceId) { + String ivyNotation = stubMapperProperties.fromServiceIdToIvyNotation(serviceId); + String serviceToFind = StringUtils.hasText(ivyNotation) ? ivyNotation : serviceId; + URL stubUrl = stubFinder.findStubUrl(serviceToFind); + if (stubUrl == null) { + return delegate.getInstances(serviceId); + } + return Collections.singletonList( + new StubRunnerServiceInstance(serviceId, stubUrl.getHost(), stubUrl.getPort(), toUri(stubUrl)) + ); + } + + private URI toUri(URL url) { + try { + return url.toURI(); + } catch (Exception e) { + return null; + } + } + + @Override + public List getServices() { + List services = delegate.getServices(); + RunningStubs runningStubs = stubFinder.findAllRunningStubs(); + services.addAll(runningStubs.getAllServicesNames()); + return services; + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java new file mode 100644 index 0000000000..ba5ee8249f --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java @@ -0,0 +1,57 @@ +package io.codearte.accurest.stubrunner.spring.cloud; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; + +import org.springframework.cloud.client.ServiceInstance; + +/** + * {@link ServiceInstance} with a helpful constructor + * + * @author Marcin Grzejszczak + */ +public class StubRunnerServiceInstance implements ServiceInstance { + + private final String serviceId; + private final String host; + private final int port; + private final URI uri; + + public StubRunnerServiceInstance(String serviceId, String host, int port, URI uri) { + this.serviceId = serviceId; + this.host = host; + this.port = port; + this.uri = uri; + } + + @Override + public String getServiceId() { + return serviceId; + } + + @Override + public String getHost() { + return host; + } + + @Override + public int getPort() { + return port; + } + + @Override + public boolean isSecure() { + return false; + } + + @Override + public URI getUri() { + return uri; + } + + @Override + public Map getMetadata() { + return new HashMap<>(); + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java new file mode 100644 index 0000000000..b759304230 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java @@ -0,0 +1,39 @@ +package io.codearte.accurest.stubrunner.spring.cloud; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; + +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration; + +/** + * Wraps {@link DiscoveryClient} in a Stub Runner implementation that tries to find + * a corresponding WireMock server for a searched dependency + */ +@Configuration +@EnableConfigurationProperties +@ConditionalOnClass(DiscoveryClient.class) +@Import(StubRunnerConfiguration.class) +public class StubRunnerSpringCloudAutoConfiguration { + + @Bean + @ConditionalOnMissingBean + public StubMapperProperties stubMapperProperties() { + return new StubMapperProperties(); + } + + @Bean + @Primary + public DiscoveryClient stubRunnerDiscoveryClient(DiscoveryClient discoveryClient, + StubFinder stubFinder, + StubMapperProperties stubMapperProperties) { + return new StubRunnerDiscoveryClient(discoveryClient, stubFinder, stubMapperProperties); + } + +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java new file mode 100644 index 0000000000..523f499076 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java @@ -0,0 +1,17 @@ +package io.codearte.accurest.stubrunner.spring.cloud.ribbon; + +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; +import org.springframework.cloud.netflix.ribbon.RibbonClients; +import org.springframework.context.annotation.Configuration; + +import com.netflix.loadbalancer.ServerList; + +@Configuration +@ConditionalOnClass(ServerList.class) +@AutoConfigureAfter(RibbonAutoConfiguration.class) +@RibbonClients(defaultConfiguration = StubRunnerRibbonConfiguration.class) +public class StubRunnerRibbonAutoConfiguration { + +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java new file mode 100644 index 0000000000..c598caeaab --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java @@ -0,0 +1,94 @@ +package io.codearte.accurest.stubrunner.spring.cloud.ribbon; + +import java.net.URI; +import java.net.URL; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; + +import io.codearte.accurest.stubrunner.RunningStubs; +import io.codearte.accurest.stubrunner.StubConfiguration; +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; +import io.codearte.accurest.stubrunner.util.StringUtils; + +/** + * Ribbon AutoConfiguration that manipulates the service id to make the service + * be picked from the list of available WireMock instance if one is available. + * + * @author Marcin Grzejszczak + */ +@Configuration +public class StubRunnerRibbonConfiguration { + + @Bean + @Primary + @SuppressWarnings("unchecked") + public ServerList stubRunnerRibbonServerList(final ServerList serverList, + StubFinder stubFinder, + final StubMapperProperties stubMapperProperties, + IClientConfig clientConfig) { + String serviceName = clientConfig.getClientName(); + String mappedServiceName = StringUtils + .hasText(stubMapperProperties.fromServiceIdToIvyNotation(serviceName)) ? + stubMapperProperties.fromServiceIdToIvyNotation(serviceName) : serviceName; + RunningStubs runningStubs = stubFinder.findAllRunningStubs(); + final Map.Entry entry = runningStubs.getEntry(mappedServiceName); + final Collection servers = new ArrayList(); + if (entry != null) { + servers.add(new Server("localhost", entry.getValue()) { + @Override + public MetaInfo getMetaInfo() { + return new MetaInfo() { + @Override + public String getAppName() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().toColonSeparatedDependencyNotation()); + } + + @Override + public String getServerGroup() { + return null; + } + + @Override + public String getServiceIdForDiscovery() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().getArtifactId()); + } + + @Override + public String getInstanceId() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().getArtifactId()); + } + }; + } + }); + } + return new ServerList() { + @Override + public List getInitialListOfServers() { + List combinedList = new ArrayList<>(); + combinedList.addAll(servers); + combinedList.addAll(serverList.getInitialListOfServers()); + return combinedList; + } + + @Override + public List getUpdatedListOfServers() { + List combinedList = new ArrayList<>(); + combinedList.addAll(servers); + combinedList.addAll(serverList.getUpdatedListOfServers()); + return combinedList; + } + }; + } + +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..60fb0401e6 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.stubrunner.spring.cloud.StubRunnerSpringCloudAutoConfiguration,\ +io.codearte.accurest.stubrunner.spring.cloud.ribbon.StubRunnerRibbonAutoConfiguration diff --git a/stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy b/stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy new file mode 100644 index 0000000000..741d7ccbe0 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy @@ -0,0 +1,58 @@ +package io.codearte.accurest.stubrunner.spring.cloud + +import io.codearte.accurest.stubrunner.StubFinder +import org.apache.curator.test.TestingServer +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.boot.test.WebIntegrationTest +import org.springframework.cloud.client.discovery.EnableDiscoveryClient +import org.springframework.cloud.client.loadbalancer.LoadBalanced +import org.springframework.cloud.zookeeper.discovery.ZookeeperServiceDiscovery +import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.test.context.ContextConfiguration +import org.springframework.web.client.RestTemplate +import spock.lang.AutoCleanup +import spock.lang.Shared +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) +@WebIntegrationTest(randomPort = true) +class StubRunnerSpringCloudAutoConfigurationSpec extends Specification { + + @Autowired StubFinder stubFinder + @Autowired @LoadBalanced RestTemplate restTemplate + @Autowired ZookeeperServiceDiscovery zookeeperServiceDiscovery + @Autowired ConfigurableApplicationContext applicationContext + @Shared @AutoCleanup TestingServer testingServer = new TestingServer(2181) + + def 'should make service discovery work'() { + expect: 'WireMocks are running' + "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + and: 'Stubs can be reached via load service discovery' + restTemplate.getForObject('http://loanIssuance/name', String) == 'loanIssuance' + restTemplate.getForObject('http://someNameThatShouldMapFraudDetectionServer/name', String) == 'fraudDetectionServer' + } + + def cleanup() { + zookeeperServiceDiscovery.serviceDiscovery.close() + applicationContext.close() + } + + @Configuration + @EnableAutoConfiguration + @EnableDiscoveryClient + static class Config { + @Bean + @LoadBalanced + RestTemplate restTemplate() { + return new RestTemplate() + } + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml b/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml new file mode 100644 index 0000000000..686861b073 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml @@ -0,0 +1,6 @@ +stubrunner.stubs.repository.root: classpath:m2repo +stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer + +stubrunner.stubs.idsToServiceIds: + ivyNotation: someValueInsideYourCode + fraudDetectionServer: someNameThatShouldMapFraudDetectionServer \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml new file mode 100644 index 0000000000..0cfb35f4cd --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml @@ -0,0 +1,14 @@ + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..a29a63180218c9e81bc924a09c14be4b4619b519 GIT binary patch literal 1733 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^BlM4AaJ9Yi?peL1tch zF@~)`i{Q?a1G3=?(~1&HQ(RI@Qj<$E^YemJi^@`qFm#)($XO`C$iN^4^r0<5-NhOC zr8z0SiACAYIhm<>C62{@`6X^3d-Sr3^Yf-oIO})VK%nJ)EmwAHh=8K+>H4Ky0r>?A zO$Aw11}7IS*-_T<)+=;M`TJYGipPsKsJ^e*KX-200f{R=k^`j^g0Eeet+h?;9qZ!t zvu@jH8~kod&|iB|MC*IjpNTT7=4;(Qc1L2((z08Nly|b_aV(g>b<&r`ALgoew_iSP zAgt;oyx8qvnz5OTzux+F`FZc(Eq-`YsHR?8hFPfV^zyBnE?Mv;I$7=K*!IRp>_qXJ zulMJL%+}64am01g+70>>TvirL)Ua<4pQ>S;=cVc{J+s|zdV#TB{6y&&Rksd4%xkV) zw<{><`;G;?=GUxexCH83+b{7vSo~b?effXm)=aMT`kE}755s0yvge=3)bhN zHtRJ0_w^Uvp~dWh_1B^lfI+SW400|{&L}2ObW6#xm4R{M5 zg!I1K@Ejd<- zKQ^=2ShZI*X6bIB-Az;1sQWBA<)56Y+0`@C>Eyq#XA{d+Z}I6}FH_H`p7r2|`NM;u zv05vwV=lDKyp?az^SH0L?!>&N=jZ0!&fhob(2PT;Yj#yE6A1E-Nq#nMhVtg-y|;d) zPf^ej!3mD%0Kx{~4xCbXzdZgy$SsX# z0a{+VI=;Gkfk7LBR*~db; zfeD6@NrV}95d?HS5C|~5bp+Ay0tsCkdVvH|3<66UHGw2t8&dIvYy!4Y2&^4w@n6R> zAQN8HAZtS}GC^e$1c0>72QuN>u$EBhW}%l*Fw?d)-X&-jf$|F3Dv)o{b0)&70AOCl p?`%w~5cw3{9`uxmu;&CbarU63%K&dyHjokQK&S_FXd?@V2LP^BMu-3a literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..2a8b40b197 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + io.codearte.accurest.stubs + fraudDetectionServer-stubs + 0.0.1-SNAPSHOT + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..5e2fc1d528 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer-stubs + 0.0.1-SNAPSHOT + + + true + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml new file mode 100644 index 0000000000..46fa17218f --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml @@ -0,0 +1,11 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer-stubs + + + 0.0.1-SNAPSHOT + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar new file mode 100644 index 0000000000000000000000000000000000000000..12d6b10f29e2a1b6c25afea27910ef6af0c4f3ce GIT binary patch literal 587 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^Bm13@$;1F;Mc!xa{1tz+^=dFGg6cC{0rK{tss}~rw zA!r5Lr$(ivu9gb(Ce_6y<*k~;=VD;KRYlpJRp;G1sYNUzYpynC=c`K+U-=X=K6k9GE;P;Q_n7@0(vaR(mIfj}U@@YWGT z!-EoC8+uTJ6obH$Mol0I*M=0Z=q7+vBgYzu53=~LV;PW!2NJqA^w0$B0uoyq=Ob&w V61D-}tZX3FEI{}RNLw?4cmNRMhR*;1 literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..a296158345 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom @@ -0,0 +1,8 @@ + + + 4.0.0 + io.codearte.accurest.stubs + loanIssuance-stubs + 0.0.1-SNAPSHOT + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..f33521f12d --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + loanIssuance-stubs + 0.0.1-SNAPSHOT + + + true + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml new file mode 100644 index 0000000000..e990fad0bc --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml @@ -0,0 +1,11 @@ + + + io.codearte.accurest.stubs + loanIssuance-stubs + + + 0.0.1-SNAPSHOT + + 20160326150924 + + diff --git a/stub-runner/stub-runner-spring/README.md b/stub-runner/stub-runner-spring/README.md index c6d26a1386..5fbe827657 100644 --- a/stub-runner/stub-runner-spring/README.md +++ b/stub-runner/stub-runner-spring/README.md @@ -32,5 +32,5 @@ for the following configuration file: ``` stubrunner.stubs.repository.root: classpath:m2repo -stubrunner.stubs: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer +stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer ``` \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/build.gradle b/stub-runner/stub-runner-spring/build.gradle index 3df19ddb06..cf735ddc98 100644 --- a/stub-runner/stub-runner-spring/build.gradle +++ b/stub-runner/stub-runner-spring/build.gradle @@ -13,6 +13,8 @@ dependencies { testCompile 'org.objenesis:objenesis:2.1' testCompile 'org.springframework.boot:spring-boot-starter:1.3.3.RELEASE' testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' - testCompile 'org.spockframework:spock-spring:1.0-groovy-2.3' + testCompile('org.spockframework:spock-spring:1.0-groovy-2.3') { + exclude(group: 'org.codehaus.groovy') + } testCompile 'ch.qos.logback:logback-classic:1.1.3' } diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java index ebc373b762..0e803b4284 100644 --- a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java +++ b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java @@ -41,7 +41,7 @@ public class StubRunnerConfiguration { @Value("${stubrunner.stubs.repository.root:}") Resource stubRepositoryRoot, @Value("${stubrunner.stubs.classifier:stubs}") String stubsSuffix, @Value("${stubrunner.work-offline:false}") boolean workOffline, - @Value("${stubrunner.stubs:}") String stubs) throws IOException { + @Value("${stubrunner.stubs.ids:}") String stubs) throws IOException { StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue, maxPortValue, uriStringOrEmpty(stubRepositoryRoot), stubRepositoryRoot == null || workOffline, stubsSuffix); Set dependencies = StubsParser.fromString(stubs, stubsSuffix); diff --git a/stub-runner/stub-runner-spring/src/test/resources/application.yml b/stub-runner/stub-runner-spring/src/test/resources/application.yml index 4b48d59b25..0cb44fd948 100644 --- a/stub-runner/stub-runner-spring/src/test/resources/application.yml +++ b/stub-runner/stub-runner-spring/src/test/resources/application.yml @@ -1,2 +1,2 @@ stubrunner.stubs.repository.root: classpath:m2repo -stubrunner.stubs: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer \ No newline at end of file +stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer \ No newline at end of file diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index 3fa0ed3b75..3ee78c7685 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -9,7 +9,6 @@ dependencies { compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile 'javax.servlet:javax.servlet-api:3.1.0' compile 'args4j:args4j:2.32' - compile 'com.nurkiewicz.asyncretry:asyncretry-jdk7:0.0.6' if (rootProject.hasProperty("fatJar")) runtime 'ch.qos.logback:logback-classic:1.1.3' diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy index c856dd9dd2..6c1d683fba 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy @@ -23,21 +23,25 @@ class RunningStubs { } Integer getPort(String artifactId) { + return getEntry(artifactId)?.value + } + + Map.Entry getEntry(String artifactId) { def strings = artifactId.split(':') if (strings.length == 1) { return namesAndPorts.entrySet().find { it.key.artifactId == artifactId - }?.value + } } else if(strings.length == 2) { return namesAndPorts.entrySet().find { it.key.groupId == strings[0] && it.key.artifactId == strings[1] - }?.value + } } return namesAndPorts.entrySet().find { it.key.groupId == strings[0] && it.key.artifactId == strings[1] && it.key.classifier == strings[2] - }?.value + } } Integer getPort(String groupId, String artifactId) { @@ -47,21 +51,7 @@ class RunningStubs { } boolean isPresent(String artifactId) { - def strings = artifactId.split(':') - if (strings.length == 1) { - return namesAndPorts.entrySet().find { - it.key.artifactId == artifactId - } - } else if(strings.length == 2) { - return namesAndPorts.entrySet().find { - it.key.groupId == strings[0] && it.key.artifactId == strings[1] - } - } - return namesAndPorts.entrySet().find { - it.key.groupId == strings[0] && - it.key.artifactId == strings[1] && - it.key.classifier == strings[2] - } + return getEntry(artifactId) } boolean isPresent(String groupId, String artifactId) { @@ -70,6 +60,14 @@ class RunningStubs { } } + Set getAllServices() { + return namesAndPorts.keySet() + } + + Set getAllServicesNames() { + return namesAndPorts.keySet().collect { it.artifactId } as Set + } + @Override String toString() { return namesAndPorts.collect { From f343a191d3198f422d03c34d63d6c468d0296e36 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 29 Mar 2016 22:58:10 +0200 Subject: [PATCH 357/719] Changed cloud versions --- stub-runner/stub-runner-spring-cloud/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stub-runner/stub-runner-spring-cloud/build.gradle b/stub-runner/stub-runner-spring-cloud/build.gradle index 96d86c8ac1..3b25cf3895 100644 --- a/stub-runner/stub-runner-spring-cloud/build.gradle +++ b/stub-runner/stub-runner-spring-cloud/build.gradle @@ -4,9 +4,9 @@ dependencies { compile project(':stub-runner-root:stub-runner-spring') compile localGroovy() - compile 'org.springframework.cloud:spring-cloud-starter:[1.1.0.RC2,)' + compile 'org.springframework.cloud:spring-cloud-starter:[1.0.6.RELEASE,)' // TODO: should be compile only - compile 'org.springframework.cloud:spring-cloud-starter-ribbon:[1.1.0.RC1,)' + compile 'org.springframework.cloud:spring-cloud-starter-ribbon:[1.0.6.RELEASE,)' testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { exclude(group: 'org.codehaus.groovy') From 71ddf9442bd4ebeac9f95661ac067ec171f928a8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 30 Mar 2016 08:38:52 +0200 Subject: [PATCH 358/719] Trying to fix Travis --- build.gradle | 1 + stub-runner/stub-runner-spring-cloud/build.gradle | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index 96908af878..0cd3295587 100644 --- a/build.gradle +++ b/build.gradle @@ -9,6 +9,7 @@ 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" } } diff --git a/stub-runner/stub-runner-spring-cloud/build.gradle b/stub-runner/stub-runner-spring-cloud/build.gradle index 3b25cf3895..a69b8dc7fc 100644 --- a/stub-runner/stub-runner-spring-cloud/build.gradle +++ b/stub-runner/stub-runner-spring-cloud/build.gradle @@ -1,12 +1,10 @@ -description = 'Spring configuration for stub-runner' - dependencies { compile project(':stub-runner-root:stub-runner-spring') compile localGroovy() - compile 'org.springframework.cloud:spring-cloud-starter:[1.0.6.RELEASE,)' // TODO: should be compile only - compile 'org.springframework.cloud:spring-cloud-starter-ribbon:[1.0.6.RELEASE,)' + compile 'org.springframework.cloud:spring-cloud-starter:1.1.0.RC2' + compile 'org.springframework.cloud:spring-cloud-starter-ribbon:1.1.0.RC1' testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { exclude(group: 'org.codehaus.groovy') @@ -22,4 +20,4 @@ dependencies { exclude(group: 'org.codehaus.groovy') } testCompile 'ch.qos.logback:logback-classic:1.1.3' -} +} \ No newline at end of file From 42736c5108ba8d5d5f3a957272d263d9a6b52b1e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 30 Mar 2016 08:44:14 +0200 Subject: [PATCH 359/719] Trying to fix Travis - adding missing repo --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 0cd3295587..365bea9dd1 100644 --- a/build.gradle +++ b/build.gradle @@ -50,6 +50,9 @@ subprojects { mavenLocal() mavenCentral() jcenter() + maven { + url "http://repo.spring.io/milestone" + } } //Dependencies in all subprojects - http://solidsoft.wordpress.com/2014/11/13/gradle-tricks-display-dependencies-for-all-subprojects-in-multi-project-build/ From f9e083833e3f40af7c7a924646e0767fbbb85049 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 30 Mar 2016 08:53:36 +0200 Subject: [PATCH 360/719] limited number of logs --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 8f075cb917..feb2c653e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,4 +14,4 @@ jdk: - oraclejdk8 install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --info --continue +script: ./gradlew clean check funcTest --stacktrace --continue From 8725ab8dc521a32188e7221587b27f900aab9c39 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 30 Mar 2016 09:20:42 +0200 Subject: [PATCH 361/719] Added more explicit logging --- build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/build.gradle b/build.gradle index 365bea9dd1..5a4894a4f2 100644 --- a/build.gradle +++ b/build.gradle @@ -66,6 +66,12 @@ subprojects { } } + test { + testLogging { + exceptionFormat = 'full' + } + } + // fixing the groovydoc issue http://stackoverflow.com/questions/20618857/gradle-task-groovydoc-failing-with-noclassdeffounderror configurations { jansi.extendsFrom(runtime) From b01145a203bf2052a219a37e0bdd25ccb60411fa Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 30 Mar 2016 09:54:36 +0200 Subject: [PATCH 362/719] Trying to fix Travis --- .travis.yml | 1 - .../ribbon/StubRunnerRibbonConfiguration.java | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index feb2c653e4..b51e928166 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,6 @@ before_install: jdk: - oraclejdk7 - - openjdk7 - oraclejdk8 install: ./gradlew assemble diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java index c598caeaab..dc2735c0cd 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java @@ -7,6 +7,7 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @@ -30,6 +31,22 @@ import io.codearte.accurest.stubrunner.util.StringUtils; @Configuration public class StubRunnerRibbonConfiguration { + @Bean + @ConditionalOnMissingBean + public ServerList noOpServerList() { + return new ServerList() { + @Override + public List getInitialListOfServers() { + return new ArrayList<>(); + } + + @Override + public List getUpdatedListOfServers() { + return new ArrayList<>(); + } + }; + } + @Bean @Primary @SuppressWarnings("unchecked") From a9d1fe048826585c28872a587a4f81f4e6dc1103 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 30 Mar 2016 09:57:58 +0200 Subject: [PATCH 363/719] Polish --- stub-runner/stub-runner-spring-cloud/README.md | 6 ++++-- .../cloud/StubRunnerSpringCloudAutoConfiguration.java | 2 ++ .../cloud/ribbon/StubRunnerRibbonAutoConfiguration.java | 6 ++++++ .../spring/cloud/ribbon/StubRunnerRibbonConfiguration.java | 2 -- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/stub-runner/stub-runner-spring-cloud/README.md b/stub-runner/stub-runner-spring-cloud/README.md index 06399b13a0..0d7b496245 100644 --- a/stub-runner/stub-runner-spring-cloud/README.md +++ b/stub-runner/stub-runner-spring-cloud/README.md @@ -9,5 +9,7 @@ io.codearte.accurest:stub-runner-spring-cloud and the Stub Runner autoconfiguration should be picked up. -In order to find the registered server via service discovery, you have to use the -`artifactId` as the name of the application \ No newline at end of file +You can match the artifactId of the stub with the name of your app by using the `stubrunner.stubs.idsToServiceIds:` map. + +You can disable Stub Runner Ribbon support by providing: `stubrunner.cloud.ribbon.enabled` equal to `false` +You can disable Stub Runner support by providing: `stubrunner.cloud.enabled` equal to `false` \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java index b759304230..cf4c9d0928 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java @@ -2,6 +2,7 @@ package io.codearte.accurest.stubrunner.spring.cloud; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.context.annotation.Bean; @@ -20,6 +21,7 @@ import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration; @EnableConfigurationProperties @ConditionalOnClass(DiscoveryClient.class) @Import(StubRunnerConfiguration.class) +@ConditionalOnProperty(value = "stubrunner.cloud.enabled", matchIfMissing = true) public class StubRunnerSpringCloudAutoConfiguration { @Bean diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java index 523f499076..e54b825ec7 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java @@ -1,17 +1,23 @@ package io.codearte.accurest.stubrunner.spring.cloud.ribbon; import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClients; import org.springframework.context.annotation.Configuration; import com.netflix.loadbalancer.ServerList; +import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; + @Configuration @ConditionalOnClass(ServerList.class) +@ConditionalOnBean(StubMapperProperties.class) @AutoConfigureAfter(RibbonAutoConfiguration.class) @RibbonClients(defaultConfiguration = StubRunnerRibbonConfiguration.class) +@ConditionalOnProperty(value = "stubrunner.cloud.ribbon.enabled", matchIfMissing = true) public class StubRunnerRibbonAutoConfiguration { } diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java index dc2735c0cd..b55e1960a8 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java @@ -1,7 +1,5 @@ package io.codearte.accurest.stubrunner.spring.cloud.ribbon; -import java.net.URI; -import java.net.URL; import java.util.ArrayList; import java.util.Collection; import java.util.List; From 5d3d42e2b567429bb5ee93545ae23bb252c21e53 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 29 Mar 2016 22:39:13 +0200 Subject: [PATCH 364/719] missing groovy dependency --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 5a4894a4f2..aa84447761 100644 --- a/build.gradle +++ b/build.gradle @@ -98,6 +98,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.3.10' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') From 15f4b7a7473443c2423e35c3e199d63cb33b7ca1 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 29 Mar 2016 22:34:50 +0200 Subject: [PATCH 365/719] Use standard directory for generated test source code --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 2 +- .../io/codearte/accurest/plugin/BasicFunctionalSpec.groovy | 2 +- .../resources/functionalTest/sampleJerseyProject/build.gradle | 2 +- .../test/resources/functionalTest/sampleProject/build.gradle | 2 +- .../test/resources/functionalTest/scenarioProject/build.gradle | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) 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 cd38e879bc..f13dca4039 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 @@ -46,7 +46,7 @@ class AccurestGradlePlugin implements Plugin { void setConfigurationDefaults(AccurestConfigProperties extension) { extension.with { - generatedTestSourcesDir = project.file("${project.buildDir}/generated-sources/accurest") + generatedTestSourcesDir = project.file("${project.buildDir}/generated-test-sources/accurest") contractsDslDir = project.file("${project.rootDir}/src/test/resources/stubs") //TODO: Use sourceset basePackageForTests = 'io.codearte.accurest.tests' } 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 7457760cf9..a8fd7cc7ef 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 @@ -7,7 +7,7 @@ import spock.lang.Stepwise @Stepwise class BasicFunctionalSpec extends IntegrationSpec { - private static final String GENERATED_TEST = "build//generated-sources//accurest//accurest//twitter_places_analyzer//PairIdSpec.groovy" + private static final String GENERATED_TEST = "build//generated-test-sources//accurest//accurest//twitter_places_analyzer//PairIdSpec.groovy" private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.json" private static final String GROOVY_DSL_CONTRACT = "repository//mappings//com//ofg//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.groovy" private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.twitter_places_analyzer.PairIdSpec.xml" diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index f33b17b5a6..c4013e84a4 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -46,7 +46,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') testMode = 'JaxRsClient' baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") - generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") + generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") stubsOutputDir = wireMockStubsOutputDir } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 25ca064fc4..418de70103 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -46,7 +46,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') testMode = 'MockMvc' baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") - generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") + generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") stubsOutputDir = wireMockStubsOutputDir } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index 25ca064fc4..418de70103 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -46,7 +46,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') testMode = 'MockMvc' baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") - generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") + generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") stubsOutputDir = wireMockStubsOutputDir } From 2c020f09573ef8bf324083e9a7000ada4f5e8902 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 30 Mar 2016 20:51:58 +0200 Subject: [PATCH 366/719] deps cleanup --- maven-plugin/pom.xml | 7 +++++++ maven-plugin/src/test/projects/bootSimple/pom.xml | 5 +++++ test-deps/pom.xml | 5 +++-- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index ca967ac381..f199479e0c 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -79,6 +79,13 @@ 1.1.6 test + + io.codearte.accurest + accurest-test-deps + ${project.version} + pom + test + diff --git a/maven-plugin/src/test/projects/bootSimple/pom.xml b/maven-plugin/src/test/projects/bootSimple/pom.xml index 325a46dd11..977bee9b98 100644 --- a/maven-plugin/src/test/projects/bootSimple/pom.xml +++ b/maven-plugin/src/test/projects/bootSimple/pom.xml @@ -46,6 +46,11 @@ ${accurest.version} pom + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + diff --git a/test-deps/pom.xml b/test-deps/pom.xml index 0b6af3d4da..b3c4325703 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -28,16 +28,17 @@ com.jayway.restassured spring-mock-mvc 2.9.0 + true com.github.tomakehurst wiremock - 2.0.4-beta + 2.0.10-beta com.toomuchcoding.jsonassert jsonassert - 0.2.2 + 0.3.0 org.assertj From effd085e79314b111d5f73cc9bf21da6daf2aec0 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 30 Mar 2016 20:54:18 +0200 Subject: [PATCH 367/719] [maven-release-plugin] prepare release accurest-maven-project-0.1-alpha --- maven-plugin/pom.xml | 6 ++---- pom.xml | 8 +++----- test-deps/pom.xml | 6 ++---- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index f199479e0c..4d6e2176a5 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -1,13 +1,11 @@ - + 4.0.0 io.codearte.accurest accurest-maven-project - 1.0-SNAPSHOT + 0.1-alpha accurest-maven-plugin diff --git a/pom.xml b/pom.xml index c5551963c6..5328465b90 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,10 @@ - + 4.0.0 io.codearte.accurest accurest-maven-project - 1.0-SNAPSHOT + 0.1-alpha Accurate Maven Plugin Accurate REST Maven Plugin @@ -52,7 +50,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - HEAD + accurest-maven-project-0.1-alpha diff --git a/test-deps/pom.xml b/test-deps/pom.xml index b3c4325703..719993cda3 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -1,13 +1,11 @@ - + 4.0.0 accurest-maven-project io.codearte.accurest - 1.0-SNAPSHOT + 0.1-alpha accurest-test-deps From 543a314e97cbce1dd6aeae7e5b55565d1d299cb1 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 30 Mar 2016 20:54:18 +0200 Subject: [PATCH 368/719] [maven-release-plugin] prepare for next development iteration --- maven-plugin/pom.xml | 2 +- pom.xml | 4 ++-- test-deps/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 4d6e2176a5..5511e3f990 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -5,7 +5,7 @@ io.codearte.accurest accurest-maven-project - 0.1-alpha + 0.2-SNAPSHOT accurest-maven-plugin diff --git a/pom.xml b/pom.xml index 5328465b90..f3a95d97ed 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.codearte.accurest accurest-maven-project - 0.1-alpha + 0.2-SNAPSHOT Accurate Maven Plugin Accurate REST Maven Plugin @@ -50,7 +50,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - accurest-maven-project-0.1-alpha + HEAD diff --git a/test-deps/pom.xml b/test-deps/pom.xml index 719993cda3..87b60df18e 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -5,7 +5,7 @@ accurest-maven-project io.codearte.accurest - 0.1-alpha + 0.2-SNAPSHOT accurest-test-deps From 530d76b2b15589034d429a8a8051414c2f1d34a3 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 1 Apr 2016 21:20:53 +0200 Subject: [PATCH 369/719] attach simple logging library to runtime --- maven-plugin/pom.xml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 5511e3f990..37b2d56028 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -25,6 +26,11 @@ groovy-all 2.4.6 + + org.slf4j + slf4j-simple + 1.7.20 + org.apache.maven @@ -71,12 +77,7 @@ 4.12 test - - ch.qos.logback - logback-core - 1.1.6 - test - + io.codearte.accurest accurest-test-deps From d001e1200be9cd53f6ea9f34a021855efc6814fc Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 1 Apr 2016 21:21:25 +0200 Subject: [PATCH 370/719] depenency management import for test-deps --- .../src/test/projects/bootSimple/pom.xml | 18 ++++++-- pom.xml | 2 +- test-deps/pom.xml | 42 +++++++++++++++---- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/maven-plugin/src/test/projects/bootSimple/pom.xml b/maven-plugin/src/test/projects/bootSimple/pom.xml index 977bee9b98..a51dd6f7cd 100644 --- a/maven-plugin/src/test/projects/bootSimple/pom.xml +++ b/maven-plugin/src/test/projects/bootSimple/pom.xml @@ -15,7 +15,7 @@ org.springframework.boot spring-boot-starter-parent 1.3.3.RELEASE - + @@ -49,10 +49,22 @@ com.jayway.restassured spring-mock-mvc - 2.9.0 + test + + + + io.codearte.accurest + accurest-test-deps + ${accurest.version} + pom + import + + + + @@ -122,7 +134,7 @@ io.codearte.accurest stubs-assembly-descriptor - 1.0 + 1.1 diff --git a/pom.xml b/pom.xml index f3a95d97ed..5c34c9c25e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ accurest-maven-project 0.2-SNAPSHOT - Accurate Maven Plugin + Accurate Maven Plugin Project Accurate REST Maven Plugin https://github.com/Codearte/accurest-maven-plugin diff --git a/test-deps/pom.xml b/test-deps/pom.xml index 87b60df18e..6bc6297d62 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -15,33 +15,61 @@ org.spockframework spock-core - 1.0-groovy-2.4 com.jayway.restassured rest-assured - 2.9.0 com.jayway.restassured spring-mock-mvc - 2.9.0 - true com.github.tomakehurst wiremock - 2.0.10-beta com.toomuchcoding.jsonassert jsonassert - 0.3.0 org.assertj assertj-core - 2.3.0 + + + + org.spockframework + spock-core + 1.0-groovy-2.4 + + + com.jayway.restassured + rest-assured + 2.9.0 + + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + true + + + com.github.tomakehurst + wiremock + 2.0.10-beta + + + com.toomuchcoding.jsonassert + jsonassert + 0.3.0 + + + org.assertj + assertj-core + 2.3.0 + + + \ No newline at end of file From 177ef1ddbbbccbb4b391220eeda2a2a2a97b54c5 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 1 Apr 2016 21:36:52 +0200 Subject: [PATCH 371/719] target framework and mode support --- .../accurest/maven/GenerateSpecsMojo.java | 18 ++++++++++++++---- .../accurest/maven/GenerateStubsMojo.java | 8 +++++--- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 0634c94508..2e5ed587c5 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -14,6 +14,8 @@ import org.apache.maven.plugins.annotations.Parameter; import io.codearte.accurest.AccurestException; import io.codearte.accurest.TestGenerator; import io.codearte.accurest.config.AccurestConfigProperties; +import io.codearte.accurest.config.TestFramework; +import io.codearte.accurest.config.TestMode; @Mojo(name = "generateSpecs", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) public class GenerateSpecsMojo extends AbstractMojo { @@ -24,18 +26,24 @@ public class GenerateSpecsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}", readonly = true) private File projectBuildDirectory; - @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/contracts") + @Parameter(defaultValue = "/src/test/resources/contracts") private String contractsDir; - @Parameter(property = "generatedTestSourcesDir", defaultValue = "/generated-test-sources/accurest") + @Parameter(defaultValue = "/generated-test-sources/accurest") private String generatedTestSourcesDir; - @Parameter(property = "basePackageForTests", defaultValue = "io.codearte.accurest.tests") + @Parameter(defaultValue = "io.codearte.accurest.tests") private String basePackageForTests; - @Parameter(property = "baseClassForTests") + @Parameter private String baseClassForTests; + @Parameter(defaultValue = "SPOCK") + private TestFramework targetFramework; + + @Parameter(defaultValue = "MOCKMVC") + private TestMode testMode; + public GenerateSpecsMojo() { } @@ -46,6 +54,8 @@ public class GenerateSpecsMojo extends AbstractMojo { config.setBasePackageForTests(basePackageForTests); config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); config.setBaseClassForTests(baseClassForTests); + config.setTargetFramework(targetFramework); + config.setTestMode(testMode); getLog().info("Accurest Plugin: Invoking test sources generation"); getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index 608cb18d3b..603f23120f 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -1,5 +1,7 @@ package io.codearte.accurest.maven; +import static java.lang.String.format; + import java.io.File; import org.apache.maven.plugin.AbstractMojo; @@ -22,10 +24,10 @@ public class GenerateStubsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}", readonly = true) private File projectBuildDirectory; - @Parameter(property = "contractsDir", defaultValue = "/src/test/resources/contracts") + @Parameter(defaultValue = "/src/test/resources/contracts") private String contractsDir; - @Parameter(property = "mappingsDir", defaultValue = "mappings") + @Parameter(defaultValue = "mappings") private String mappingsDir; public void execute() throws MojoExecutionException, MojoFailureException { @@ -34,7 +36,7 @@ public class GenerateStubsMojo extends AbstractMojo { config.setStubsOutputDir(new File(projectBuildDirectory, mappingsDir)); getLog().info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion"); - getLog().info(String.format("From '%s' to '%s'", config.getContractsDslDir(), config.getStubsOutputDir())); + getLog().info(format("From '%s' to '%s'", config.getContractsDslDir(), config.getStubsOutputDir())); RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); converter.processFiles(); From faa6205c99e2f0f57035f7ffb2a47a3437041e32 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 00:26:55 +0200 Subject: [PATCH 372/719] revert to logback, but with compile scope --- maven-plugin/pom.xml | 7 ++++--- pom.xml | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 37b2d56028..41dfe799a5 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -26,10 +26,11 @@ groovy-all 2.4.6 + - org.slf4j - slf4j-simple - 1.7.20 + ch.qos.logback + logback-core + 1.1.3 diff --git a/pom.xml b/pom.xml index 5c34c9c25e..d2de26ae48 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,7 @@ pom - 3.2.5 + [3.2.1,) From a986975e1c0472f6c9e55ae51dd0d31082af8124 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 00:27:44 +0200 Subject: [PATCH 373/719] added convert mojo --- .../codearte/accurest/maven/ConvertMojo.java | 40 +++++++++++++++++++ .../accurest/maven/GenerateSpecsMojo.java | 4 +- .../accurest/maven/GenerateStubsMojo.java | 4 +- 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 maven-plugin/src/main/java/io/codearte/accurest/maven/ConvertMojo.java diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/ConvertMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/ConvertMojo.java new file mode 100644 index 0000000000..a15b5a642b --- /dev/null +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/ConvertMojo.java @@ -0,0 +1,40 @@ +package io.codearte.accurest.maven; + +import static java.lang.String.format; + +import java.io.File; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import io.codearte.accurest.config.AccurestConfigProperties; +import io.codearte.accurest.wiremock.DslToWireMockClientConverter; +import io.codearte.accurest.wiremock.RecursiveFilesConverter; + +@Mojo(name = "convert", requiresProject = false) +public class ConvertMojo extends AbstractMojo { + + @Parameter(property = "contractsDir", defaultValue = "${basedir}") + private File contractsDir; + + @Parameter(property = "mappingsDir", defaultValue = "${basedir}") + private File mappingsDir; + + public void execute() throws MojoExecutionException, MojoFailureException { + + AccurestConfigProperties config = new AccurestConfigProperties(); + config.setContractsDslDir(contractsDir); + config.setStubsOutputDir(mappingsDir); + + getLog().info("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings"); + getLog().info(format(" Accurest contracts directory: %s", config.getContractsDslDir().getAbsolutePath())); + getLog().info(format("WireMock stubs mappings directory: %s", config.getStubsOutputDir().getAbsolutePath())); + + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); + converter.processFiles(); + } + +} diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 2e5ed587c5..cb38afc60c 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -20,10 +20,10 @@ import io.codearte.accurest.config.TestMode; @Mojo(name = "generateSpecs", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) public class GenerateSpecsMojo extends AbstractMojo { - @Parameter(defaultValue = "${basedir}", readonly = true) + @Parameter(defaultValue = "${basedir}", readonly = true, required = true) private File baseDir; - @Parameter(defaultValue = "${project.build.directory}", readonly = true) + @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) private File projectBuildDirectory; @Parameter(defaultValue = "/src/test/resources/contracts") diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index 603f23120f..8a91f976d5 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -18,10 +18,10 @@ import io.codearte.accurest.wiremock.RecursiveFilesConverter; @Mojo(name = "generateStubs", defaultPhase = LifecyclePhase.PROCESS_RESOURCES) public class GenerateStubsMojo extends AbstractMojo { - @Parameter(defaultValue = "${basedir}", readonly = true) + @Parameter(defaultValue = "${basedir}", readonly = true, required = true) private File baseDir; - @Parameter(defaultValue = "${project.build.directory}", readonly = true) + @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) private File projectBuildDirectory; @Parameter(defaultValue = "/src/test/resources/contracts") From 80ee8afef7206f74a4fd99a889f79ccd766613cb Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 01:01:32 +0200 Subject: [PATCH 374/719] tests for convert goal --- .../accurest/maven/PluginIntegrationTest.java | 39 +++---- .../accurest/maven/PluginUnitTest.java | 1 + .../projects/basic-with-execution/pom.xml | 103 ------------------ .../contracts => pomless}/Sample.groovy | 0 4 files changed, 21 insertions(+), 122 deletions(-) delete mode 100644 maven-plugin/src/test/projects/basic-with-execution/pom.xml rename maven-plugin/src/test/projects/{basic-with-execution/src/test/resources/contracts => pomless}/Sample.groovy (100%) diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java index 9cb929fd10..40bd3f697d 100644 --- a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java +++ b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java @@ -6,6 +6,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; +import io.takari.maven.testing.TestProperties; import io.takari.maven.testing.TestResources; import io.takari.maven.testing.executor.MavenRuntime; import io.takari.maven.testing.executor.MavenVersions; @@ -18,6 +19,8 @@ public class PluginIntegrationTest { @Rule public final TestResources resources = new TestResources(); + private final TestProperties properties = new TestProperties(); + private final MavenRuntime maven; public PluginIntegrationTest(MavenRuntime.MavenRuntimeBuilder mavenBuilder) throws Exception { @@ -25,29 +28,27 @@ public class PluginIntegrationTest { } @Test - public void shouldCreateStubs() throws Exception { - File basedir = resources.getBasedir("basic-with-execution"); - maven.forProject(basedir) - .withCliOption("-X") - .execute("package") - .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion"); - } - - @Test - public void shouldCreateSpecs() throws Exception { - File basedir = resources.getBasedir("basic-with-execution"); - maven.forProject(basedir) - .execute("package") - .assertLogText("Accurest Plugin: Invoking test sources generation"); - } - - @Test - public void shouldBuildAndTestSimpleBootProject() throws Exception { + public void shouldBuildSimpleBootWIthAccurtesProject() throws Exception { File basedir = resources.getBasedir("bootSimple"); maven.forProject(basedir) .execute("package") .assertErrorFreeLog() .assertLogText("Accurest Plugin: Invoking test sources generation") - .assertLogText("Generated 1 test classes."); + .assertLogText("Generated 1 test classes.") + .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") + .assertLogText("Creating new json") + .assertErrorFreeLog(); + } + + @Test + public void shouldConvertAccurestToWireMockStubs() throws Exception { + File basedir = resources.getBasedir("pomless"); + properties.getPluginVersion(); + maven.forProject(basedir) + .withCliOption("-X") + .execute(String.format("io.codearte.accurest:accurest-maven-plugin:%s:convert", properties.getPluginVersion())) + .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") + .assertLogText("Creating new json") + .assertErrorFreeLog(); } } \ No newline at end of file diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 71ed604edf..864b844cd8 100644 --- a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -46,4 +46,5 @@ public class PluginUnitTest { assertFilesPresent(basedir, "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestSpec.groovy"); } + } diff --git a/maven-plugin/src/test/projects/basic-with-execution/pom.xml b/maven-plugin/src/test/projects/basic-with-execution/pom.xml deleted file mode 100644 index 40d5b17c72..0000000000 --- a/maven-plugin/src/test/projects/basic-with-execution/pom.xml +++ /dev/null @@ -1,103 +0,0 @@ - - - 4.0.0 - - io.codearte.accurest.sample - sample-project - 0.1 - - - - - org.spockframework - spock-core - 1.0-groovy-2.4 - test - - - com.jayway.restassured - rest-assured - 2.9.0 - test - - - com.jayway.restassured - spring-mock-mvc - 2.9.0 - test - - - com.github.tomakehurst - wiremock - 2.0.4-beta - test - - - com.toomuchcoding.jsonassert - jsonassert - 0.2.2 - test - - - org.assertj - assertj-core - 2.3.0 - - - - - - - io.codearte.accurest - accurest-maven-plugin - ${it-plugin.version} - - - - generateStubs - generateSpecs - - - - - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.5 - - - - testCompile - - - - - - - ${project.basedir}/src/test/groovy - - **/*.groovy - - - - ${project.build.directory}/generated-test-sources/accurest - - **/*.groovy - - - - - - - maven-surefire-plugin - 2.19 - - - **/*Spec.java - - - - - - \ No newline at end of file diff --git a/maven-plugin/src/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy b/maven-plugin/src/test/projects/pomless/Sample.groovy similarity index 100% rename from maven-plugin/src/test/projects/basic-with-execution/src/test/resources/contracts/Sample.groovy rename to maven-plugin/src/test/projects/pomless/Sample.groovy From 7ad032ba95c8a89897fd453e2951af3710c15e54 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 01:04:51 +0200 Subject: [PATCH 375/719] update documentation --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e802a129ba..bf008a1c4e 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,7 @@ Project configuration io.codearte.accurest stubs-assembly-descriptor - 1.0 + 1.1 From 759ac4ef9836e62b0bc957bcc40d799f59e83761 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 01:06:04 +0200 Subject: [PATCH 376/719] [maven-release-plugin] prepare release accurest-maven-project-0.1-beta --- maven-plugin/pom.xml | 5 ++--- pom.xml | 4 ++-- test-deps/pom.xml | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 41dfe799a5..b81a0c5e0b 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.codearte.accurest accurest-maven-project - 0.2-SNAPSHOT + 0.1-beta accurest-maven-plugin diff --git a/pom.xml b/pom.xml index d2de26ae48..9a24a73e40 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.codearte.accurest accurest-maven-project - 0.2-SNAPSHOT + 0.1-beta Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -50,7 +50,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - HEAD + accurest-maven-project-0.1-beta diff --git a/test-deps/pom.xml b/test-deps/pom.xml index 6bc6297d62..604dc23fe2 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -5,7 +5,7 @@ accurest-maven-project io.codearte.accurest - 0.2-SNAPSHOT + 0.1-beta accurest-test-deps From 91f5b9954e9e49892c0705061246ed4d6506fe86 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 01:06:04 +0200 Subject: [PATCH 377/719] [maven-release-plugin] prepare for next development iteration --- maven-plugin/pom.xml | 2 +- pom.xml | 4 ++-- test-deps/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index b81a0c5e0b..5222f6de08 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -5,7 +5,7 @@ io.codearte.accurest accurest-maven-project - 0.1-beta + 0.1-SNAPSHOT accurest-maven-plugin diff --git a/pom.xml b/pom.xml index 9a24a73e40..44208c18be 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.codearte.accurest accurest-maven-project - 0.1-beta + 0.1-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -50,7 +50,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - accurest-maven-project-0.1-beta + HEAD diff --git a/test-deps/pom.xml b/test-deps/pom.xml index 604dc23fe2..c8e9fb9c38 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -5,7 +5,7 @@ accurest-maven-project io.codearte.accurest - 0.1-beta + 0.1-SNAPSHOT accurest-test-deps From ac4e647afdeb286c10e8acc061a6f90a0d317262 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 01:11:36 +0200 Subject: [PATCH 378/719] standalone convertsion to stubs --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index bf008a1c4e..d03954aee4 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,11 @@ Accurate REST Maven Plugin ==== + +Converting Accurest GroovyDSL into WireMock stub mappings: + + mvn io.codearte.accurest:accurest-maven-plugin:0.1-beta:convert + Sample usage ---- From c1e5876e5f3494c78842fbf987cfc9933ddaccb7 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 10:59:57 +0200 Subject: [PATCH 379/719] simplified conversion usage --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d03954aee4..06e8342ed1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Accurate REST Maven Plugin Converting Accurest GroovyDSL into WireMock stub mappings: - mvn io.codearte.accurest:accurest-maven-plugin:0.1-beta:convert + mvn io.codearte.accurest:accurest-maven-plugin:convert Sample usage ---- From b662c5218a7bc1219f65eb674a806d4910727fac Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 11:20:54 +0200 Subject: [PATCH 380/719] /src/test/accurest as standard directory for contracts --- README.md | 2 +- .../main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java | 2 +- .../main/java/io/codearte/accurest/maven/GenerateStubsMojo.java | 2 +- .../src/test/{resources/contracts => accurest}/Sample.groovy | 0 4 files changed, 3 insertions(+), 3 deletions(-) rename maven-plugin/src/test/projects/basic/src/test/{resources/contracts => accurest}/Sample.groovy (100%) diff --git a/README.md b/README.md index 06e8342ed1..a853b5a6b0 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Project default directories _contractsDir_ - contract definitions: - /src/test/resources/contracts + /src/test/accurest _generatedTestSourcesDir_ - Generated accurest specifications: diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index cb38afc60c..2a6e35f081 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -26,7 +26,7 @@ public class GenerateSpecsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) private File projectBuildDirectory; - @Parameter(defaultValue = "/src/test/resources/contracts") + @Parameter(defaultValue = "/src/test/accurest") private String contractsDir; @Parameter(defaultValue = "/generated-test-sources/accurest") diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java index 8a91f976d5..ed907e577d 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java @@ -24,7 +24,7 @@ public class GenerateStubsMojo extends AbstractMojo { @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) private File projectBuildDirectory; - @Parameter(defaultValue = "/src/test/resources/contracts") + @Parameter(defaultValue = "/src/test/accurest") private String contractsDir; @Parameter(defaultValue = "mappings") diff --git a/maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy b/maven-plugin/src/test/projects/basic/src/test/accurest/Sample.groovy similarity index 100% rename from maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy rename to maven-plugin/src/test/projects/basic/src/test/accurest/Sample.groovy From 82076e59e3df32d6f017dfd3c8774626dbd94c17 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 2 Apr 2016 12:03:34 +0200 Subject: [PATCH 381/719] Fix so as not to have SO on delegates --- .../spring/cloud/StubRunnerDiscoveryClient.java | 11 +++++++++-- .../cloud/StubRunnerSpringCloudAutoConfiguration.java | 6 ++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java index 66b7deb07e..a6615fd5b0 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java @@ -5,8 +5,10 @@ import java.net.URL; import java.util.Collections; import java.util.List; +import org.springframework.cloud.client.DefaultServiceInstance; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; +import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClient; import io.codearte.accurest.stubrunner.RunningStubs; import io.codearte.accurest.stubrunner.StubFinder; @@ -25,12 +27,17 @@ public class StubRunnerDiscoveryClient implements DiscoveryClient { private final StubMapperProperties stubMapperProperties; public StubRunnerDiscoveryClient(DiscoveryClient delegate, StubFinder stubFinder, - StubMapperProperties stubMapperProperties) { - this.delegate = delegate; + StubMapperProperties stubMapperProperties, String springAppName) { + this.delegate = delegate instanceof StubRunnerDiscoveryClient ? + noOpDiscoveryClient(springAppName) : delegate; this.stubFinder = stubFinder; this.stubMapperProperties = stubMapperProperties; } + private NoopDiscoveryClient noOpDiscoveryClient(String springAppName) { + return new NoopDiscoveryClient(new DefaultServiceInstance(springAppName, "localhost", 0, false)); + } + @Override public String description() { return delegate.description(); diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java index cf4c9d0928..b5d78bfe78 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java @@ -1,5 +1,6 @@ package io.codearte.accurest.stubrunner.spring.cloud; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -34,8 +35,9 @@ public class StubRunnerSpringCloudAutoConfiguration { @Primary public DiscoveryClient stubRunnerDiscoveryClient(DiscoveryClient discoveryClient, StubFinder stubFinder, - StubMapperProperties stubMapperProperties) { - return new StubRunnerDiscoveryClient(discoveryClient, stubFinder, stubMapperProperties); + StubMapperProperties stubMapperProperties, + @Value("${spring.application.name:unknown}") String springAppName) { + return new StubRunnerDiscoveryClient(discoveryClient, stubFinder, stubMapperProperties, springAppName); } } From 936dfb98880f171ce8522fdf6fdaa0c2bf2a5b14 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 2 Apr 2016 12:42:54 +0200 Subject: [PATCH 382/719] Updated readme --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a29b3523e7..a6c27f899b 100644 --- a/README.md +++ b/README.md @@ -32,4 +32,9 @@ Stub Runner with JUnit rules ### Stub Runner Spring -Spring Configuration that automatically starts stubs upon Spring Context build up \ No newline at end of file +Spring Configuration that automatically starts stubs upon Spring Context build up + +### Stub Runner Spring Cloud + +Spring Cloud AutoConfiguration that automatically starts stubs upon Spring Context build up and allows you to call the stubs +as if they were registered in your service discovery \ No newline at end of file From 033eb6fbf6d30c30c8af49b12d90c134b650693b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 13:50:04 +0200 Subject: [PATCH 383/719] separate generateTests for junit verification code --- maven-plugin/pom.xml | 7 +- .../AbstractGenerateVerificationCodeMojo.java | 70 +++++++++ .../accurest/maven/GenerateSpecsMojo.java | 62 +------- .../accurest/maven/GenerateTestsMojo.java | 18 +++ .../accurest/maven/PluginIntegrationTest.java | 20 ++- .../accurest/maven/PluginUnitTest.java | 19 ++- .../pom.xml | 0 .../ofg/twitter/place/PairIdController.groovy | 0 .../groovy/com/ofg/twitter/place/Tweet.java | 0 .../sample/SampleSimpleBootApplication.java | 0 .../src/main/resources/application.properties | 0 .../ofg/twitter/place/AcceptanceSpec.groovy | 0 .../ofg/twitter/place/BaseMockMvcSpec.groovy | 0 .../SampleSimpleBootApplicationTests.java | 0 .../src/test/resources/logback-test.groovy | 0 .../stubs/collerate_PlacesFrom_Tweet.groovy | 0 .../resources/stubs/moreComplexVersion.groovy | 0 .../test/projects/spring-boot-java/pom.xml | 139 ++++++++++++++++++ .../src/main/java/hello/Application.java | 12 ++ .../src/main/java/hello/Greeting.java | 20 +++ .../main/java/hello/GreetingController.java | 19 +++ .../src/test/accurest/greetings_ok.groovy | 21 +++ .../greetings_with_default_value.groovy | 17 +++ .../src/test/java/hello/BaseAccurest.java | 13 ++ 24 files changed, 368 insertions(+), 69 deletions(-) create mode 100644 maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java create mode 100644 maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/pom.xml (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/main/groovy/com/ofg/twitter/place/Tweet.java (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/main/resources/application.properties (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/test/resources/logback-test.groovy (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy (100%) rename maven-plugin/src/test/projects/{bootSimple => spring-boot-groovy}/src/test/resources/stubs/moreComplexVersion.groovy (100%) create mode 100644 maven-plugin/src/test/projects/spring-boot-java/pom.xml create mode 100644 maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java create mode 100644 maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java create mode 100644 maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java create mode 100644 maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy create mode 100644 maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy create mode 100644 maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 5222f6de08..9059d2bf0f 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -31,7 +31,12 @@ logback-core 1.1.3 - + + org.slf4j + slf4j-simple + 1.7.12 + test + org.apache.maven maven-core diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java new file mode 100644 index 0000000000..c7691c3662 --- /dev/null +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java @@ -0,0 +1,70 @@ +package io.codearte.accurest.maven; + +import static java.lang.String.format; + +import java.io.File; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugins.annotations.Parameter; +import org.assertj.core.util.Strings; + +import io.codearte.accurest.AccurestException; +import io.codearte.accurest.TestGenerator; +import io.codearte.accurest.config.AccurestConfigProperties; +import io.codearte.accurest.config.TestFramework; +import io.codearte.accurest.config.TestMode; + +public abstract class AbstractGenerateVerificationCodeMojo extends AbstractMojo { + + @Parameter(defaultValue = "${basedir}", readonly = true, required = true) + protected File baseDir; + + @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) + protected File projectBuildDirectory; + + @Parameter(defaultValue = "/src/test/accurest") + protected String contractsDir; + + @Parameter(defaultValue = "/generated-test-sources/accurest") + protected String generatedTestSourcesDir; + + @Parameter(defaultValue = "io.codearte.accurest.tests") + protected String basePackageForTests; + + @Parameter + protected String baseClassForTests; + + @Parameter(defaultValue = "MOCKMVC") + protected TestMode testMode; + + protected void generateVerificationCode(TestFramework testFramework) throws MojoExecutionException { + + AccurestConfigProperties config = new AccurestConfigProperties(); + config.setContractsDslDir(new File(baseDir, contractsDir)); + config.setBasePackageForTests(basePackageForTests); + config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); + if (Strings.isNullOrEmpty(baseClassForTests)) { + if (!Strings.isNullOrEmpty(basePackageForTests)) { + baseClassForTests = basePackageForTests + '.' + "BaseAccurest"; + } else { + baseClassForTests = "io.codearte.accurest.tests.BaseAccurest"; + } + } + config.setBaseClassForTests(baseClassForTests); + config.setTargetFramework(testFramework); + config.setTestMode(testMode); + + getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); + getLog().info(format("Using %s as base class for verification classes", config.getBaseClassForTests())); + + try { + TestGenerator generator = new TestGenerator(config); + int generatedClasses = generator.generate(); + getLog().info(format("Generated %s test classes.", generatedClasses)); + } catch (AccurestException e) { + throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e); + } + } + +} diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java index 2a6e35f081..4f1844b49d 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java @@ -1,74 +1,18 @@ package io.codearte.accurest.maven; -import static java.lang.String.format; - -import java.io.File; - -import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; -import io.codearte.accurest.AccurestException; -import io.codearte.accurest.TestGenerator; -import io.codearte.accurest.config.AccurestConfigProperties; import io.codearte.accurest.config.TestFramework; -import io.codearte.accurest.config.TestMode; @Mojo(name = "generateSpecs", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) -public class GenerateSpecsMojo extends AbstractMojo { - - @Parameter(defaultValue = "${basedir}", readonly = true, required = true) - private File baseDir; - - @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) - private File projectBuildDirectory; - - @Parameter(defaultValue = "/src/test/accurest") - private String contractsDir; - - @Parameter(defaultValue = "/generated-test-sources/accurest") - private String generatedTestSourcesDir; - - @Parameter(defaultValue = "io.codearte.accurest.tests") - private String basePackageForTests; - - @Parameter - private String baseClassForTests; - - @Parameter(defaultValue = "SPOCK") - private TestFramework targetFramework; - - @Parameter(defaultValue = "MOCKMVC") - private TestMode testMode; - - public GenerateSpecsMojo() { - } +public class GenerateSpecsMojo extends AbstractGenerateVerificationCodeMojo { public void execute() throws MojoExecutionException, MojoFailureException { - AccurestConfigProperties config = new AccurestConfigProperties(); - - config.setContractsDslDir(new File(baseDir, contractsDir)); - config.setBasePackageForTests(basePackageForTests); - config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); - config.setBaseClassForTests(baseClassForTests); - config.setTargetFramework(targetFramework); - config.setTestMode(testMode); - - getLog().info("Accurest Plugin: Invoking test sources generation"); - getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); - getLog().info(format("Using %s as base class for tests", config.getBaseClassForTests())); - - try { - TestGenerator generator = new TestGenerator(config); - int generatedClasses = generator.generate(); - getLog().info(format("Generated %s test classes.", generatedClasses)); - } catch (AccurestException e) { - throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e); - } - + getLog().info("Generating Spock Specifications source code for Accurest contract verification"); + generateVerificationCode(TestFramework.SPOCK); } } diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java new file mode 100644 index 0000000000..2b82877740 --- /dev/null +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java @@ -0,0 +1,18 @@ +package io.codearte.accurest.maven; + +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; + +import io.codearte.accurest.config.TestFramework; + +@Mojo(name = "generateTests", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) +public class GenerateTestsMojo extends AbstractGenerateVerificationCodeMojo { + + public void execute() throws MojoExecutionException, MojoFailureException { + getLog().info("Generating JUnit Tests source code for Accurest contract verification"); + generateVerificationCode(TestFramework.JUNIT); + } + +} diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java index 40bd3f697d..6d7ed574e2 100644 --- a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java +++ b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java @@ -28,12 +28,24 @@ public class PluginIntegrationTest { } @Test - public void shouldBuildSimpleBootWIthAccurtesProject() throws Exception { - File basedir = resources.getBasedir("bootSimple"); + public void should_build_project_Spring_Boot_Groovy_with_Accurest() throws Exception { + File basedir = resources.getBasedir("spring-boot-groovy"); maven.forProject(basedir) .execute("package") .assertErrorFreeLog() - .assertLogText("Accurest Plugin: Invoking test sources generation") + .assertLogText("Generating Spock Specifications source code for Accurest contract verification") + .assertLogText("Generated 1 test classes.") + .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") + .assertLogText("Creating new json") + .assertErrorFreeLog(); + } + @Test + public void should_build_project_Spring_Boot_Java_with_Accurest() throws Exception { + File basedir = resources.getBasedir("spring-boot-java"); + maven.forProject(basedir) + .execute("package") + .assertErrorFreeLog() + .assertLogText("Generating JUnit Tests source code for Accurest contract verification") .assertLogText("Generated 1 test classes.") .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") .assertLogText("Creating new json") @@ -41,7 +53,7 @@ public class PluginIntegrationTest { } @Test - public void shouldConvertAccurestToWireMockStubs() throws Exception { + public void should_convert_Accurest_Contracts_to_WireMock_Stubs_mappings() throws Exception { File basedir = resources.getBasedir("pomless"); properties.getPluginVersion(); maven.forProject(basedir) diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 864b844cd8..1d04aa339a 100644 --- a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -1,5 +1,6 @@ package io.codearte.accurest.maven; +import static io.takari.maven.testing.TestMavenRuntime.newParameter; import static io.takari.maven.testing.TestResources.assertFilesPresent; import java.io.File; @@ -19,23 +20,23 @@ public class PluginUnitTest { public final TestMavenRuntime maven = new TestMavenRuntime(); @Test - public void shouldGenerateWiremockStubsInDefaultcLocation() throws Exception { + public void shouldGenerateWireMockStubsInDefaultLocation() throws Exception { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "generateStubs"); assertFilesPresent(basedir, "target/mappings/Sample.json"); } @Test - public void shouldGenerateWiremockFromStubsDirectory() throws Exception { + public void shouldGenerateWireMockFromStubsDirectory() throws Exception { File basedir = resources.getBasedir("withStubs"); - maven.executeMojo(basedir, "generateStubs", TestMavenRuntime.newParameter("contractsDir", "/src/test/resources/stubs")); + maven.executeMojo(basedir, "generateStubs", newParameter("contractsDir", "/src/test/resources/stubs")); assertFilesPresent(basedir, "target/mappings/Sample.json"); } @Test - public void shouldGenerateWiremockStubsInSelectedLocation() throws Exception { + public void shouldGenerateWireMockStubsInSelectedLocation() throws Exception { File basedir = resources.getBasedir("basic"); - maven.executeMojo(basedir, "generateStubs", TestMavenRuntime.newParameter("mappingsDir", "foo")); + maven.executeMojo(basedir, "generateStubs", newParameter("mappingsDir", "foo")); assertFilesPresent(basedir, "target/foo/Sample.json"); } @@ -47,4 +48,12 @@ public class PluginUnitTest { "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestSpec.groovy"); } + @Test + public void shouldGenerateContractTestsInDefaultLocation() throws Exception { + File basedir = resources.getBasedir("basic"); + maven.executeMojo(basedir, "generateTests"); + assertFilesPresent(basedir, + "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestTest.java"); + } + } diff --git a/maven-plugin/src/test/projects/bootSimple/pom.xml b/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/pom.xml rename to maven-plugin/src/test/projects/spring-boot-groovy/pom.xml diff --git a/maven-plugin/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/maven-plugin/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy rename to maven-plugin/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy diff --git a/maven-plugin/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java b/maven-plugin/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java rename to maven-plugin/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java diff --git a/maven-plugin/src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java b/maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java rename to maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java diff --git a/maven-plugin/src/test/projects/bootSimple/src/main/resources/application.properties b/maven-plugin/src/test/projects/spring-boot-groovy/src/main/resources/application.properties similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/main/resources/application.properties rename to maven-plugin/src/test/projects/spring-boot-groovy/src/main/resources/application.properties diff --git a/maven-plugin/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy rename to maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy diff --git a/maven-plugin/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy rename to maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy diff --git a/maven-plugin/src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java rename to maven-plugin/src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java diff --git a/maven-plugin/src/test/projects/bootSimple/src/test/resources/logback-test.groovy b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/test/resources/logback-test.groovy rename to maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy diff --git a/maven-plugin/src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy rename to maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy diff --git a/maven-plugin/src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy similarity index 100% rename from maven-plugin/src/test/projects/bootSimple/src/test/resources/stubs/moreComplexVersion.groovy rename to maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-java/pom.xml b/maven-plugin/src/test/projects/spring-boot-java/pom.xml new file mode 100644 index 0000000000..e7be85facd --- /dev/null +++ b/maven-plugin/src/test/projects/spring-boot-java/pom.xml @@ -0,0 +1,139 @@ + + + 4.0.0 + + org.springframework + gs-rest-service + 0.1.0 + + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + + ch.qos.logback + logback-classic + 1.1.3 + + + + io.codearte.accurest + accurest-test-deps + ${it-plugin.version} + pom + test + + + com.jayway.restassured + spring-mock-mvc + test + + + + + + + io.codearte.accurest + accurest-test-deps + ${it-plugin.version} + pom + import + + + + + + 1.8 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + io.codearte.accurest + accurest-maven-plugin + ${it-plugin.version} + + + + generateStubs + generateTests + + + + + hello + + + + maven-assembly-plugin + 2.6 + + + io.codearte.accurest + stubs-assembly-descriptor + 1.1 + + + + + package + + single + + + + + + stubs + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + add-accurest-test-sources + generate-test-sources + + add-test-source + + + + ${project.build.directory}/generated-test-sources/accurest + + + + + + + + + + + spring-releases + https://repo.spring.io/libs-release + + + + + spring-releases + https://repo.spring.io/libs-release + + + diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java b/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java new file mode 100644 index 0000000000..5abd411428 --- /dev/null +++ b/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java @@ -0,0 +1,12 @@ +package hello; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java b/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java new file mode 100644 index 0000000000..5d10b59b77 --- /dev/null +++ b/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java @@ -0,0 +1,20 @@ +package hello; + +public class Greeting { + + private final long id; + private final String content; + + public Greeting(long id, String content) { + this.id = id; + this.content = content; + } + + public long getId() { + return id; + } + + public String getContent() { + return content; + } +} diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java b/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java new file mode 100644 index 0000000000..e356ab2b10 --- /dev/null +++ b/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java @@ -0,0 +1,19 @@ +package hello; + +import java.util.concurrent.atomic.AtomicLong; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GreetingController { + + private static final String template = "Hello, %s!"; + private final AtomicLong counter = new AtomicLong(); + + @RequestMapping("/greeting") + public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { + return new Greeting(counter.incrementAndGet(), + String.format(template, name)); + } +} diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy b/maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy new file mode 100644 index 0000000000..0ffb665f6e --- /dev/null +++ b/maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy @@ -0,0 +1,21 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'GET' + urlPath('/greeting') { + queryParameters { + parameter 'name': 'Something' + } + } + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, Something!" + ) + } +} \ No newline at end of file diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy b/maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy new file mode 100644 index 0000000000..2c5c32f159 --- /dev/null +++ b/maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy @@ -0,0 +1,17 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'GET' + url('/greeting') + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, World!" + ) + } +} \ No newline at end of file diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java b/maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java new file mode 100644 index 0000000000..d3bf7124e2 --- /dev/null +++ b/maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java @@ -0,0 +1,13 @@ +package hello; + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; +import org.junit.Before; + +public class BaseAccurest { + + @Before + public void setup() { + RestAssuredMockMvc.standaloneSetup(new GreetingController()); + } + +} From 10f9f4a58e7363c495cf774a070dbdee97f1338b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 13:53:19 +0200 Subject: [PATCH 384/719] better git ignore for maven --- .gitignore | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.gitignore b/.gitignore index d21bed913b..833eab7406 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ .idea/ *.iml target +pom.xml.tag +pom.xml.releaseBackup +pom.xml.versionsBackup +pom.xml.next +release.properties +dependency-reduced-pom.xml +buildNumber.properties +.mvn/timing.properties + From 4e459a1bfb644cca8e53c3ad0f0fb660becbd3a8 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 17:54:20 +0200 Subject: [PATCH 385/719] [maven-release-plugin] prepare release accurest-maven-project-0.1.1 --- maven-plugin/pom.xml | 2 +- pom.xml | 4 ++-- test-deps/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 9059d2bf0f..d96caa248c 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -5,7 +5,7 @@ io.codearte.accurest accurest-maven-project - 0.1-SNAPSHOT + 0.1.1 accurest-maven-plugin diff --git a/pom.xml b/pom.xml index 44208c18be..1f707026ed 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.codearte.accurest accurest-maven-project - 0.1-SNAPSHOT + 0.1.1 Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -50,7 +50,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - HEAD + accurest-maven-project-0.1.1 diff --git a/test-deps/pom.xml b/test-deps/pom.xml index c8e9fb9c38..4a1fe326ef 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -5,7 +5,7 @@ accurest-maven-project io.codearte.accurest - 0.1-SNAPSHOT + 0.1.1 accurest-test-deps From 4f8c7124b32e893f0ec80622ce15fe851abd325e Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 17:54:20 +0200 Subject: [PATCH 386/719] [maven-release-plugin] prepare for next development iteration --- maven-plugin/pom.xml | 2 +- pom.xml | 4 ++-- test-deps/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index d96caa248c..87a5986111 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -5,7 +5,7 @@ io.codearte.accurest accurest-maven-project - 0.1.1 + 0.1.2-SNAPSHOT accurest-maven-plugin diff --git a/pom.xml b/pom.xml index 1f707026ed..4ab2e9b8bc 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.codearte.accurest accurest-maven-project - 0.1.1 + 0.1.2-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -50,7 +50,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - accurest-maven-project-0.1.1 + HEAD diff --git a/test-deps/pom.xml b/test-deps/pom.xml index 4a1fe326ef..59a7591be9 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -5,7 +5,7 @@ accurest-maven-project io.codearte.accurest - 0.1.1 + 0.1.2-SNAPSHOT accurest-test-deps From d592291ac21141c3b2c58b9b57b90e83ba989b7e Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 18:31:16 +0200 Subject: [PATCH 387/719] remove relese warning --- pom.xml | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4ab2e9b8bc..2874ab45ac 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 io.codearte.accurest @@ -79,6 +80,27 @@ + + + + + maven-deploy-plugin + 2.8.2 + + + maven-install-plugin + 2.5.2 + + + maven-source-plugin + 3.0.0 + + + maven-javadoc-plugin + 2.10.3 + + + From 623ae5bd34e4e3261e55e37358e7ea890abeff6a Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 21:18:58 +0200 Subject: [PATCH 388/719] Revert changes to baseClassForTests --- .../AbstractGenerateVerificationCodeMojo.java | 8 -------- .../src/test/projects/spring-boot-java/pom.xml | 15 +-------------- .../{BaseAccurest.java => BaseMockMvcTest.java} | 2 +- 3 files changed, 2 insertions(+), 23 deletions(-) rename maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/{BaseAccurest.java => BaseMockMvcTest.java} (87%) diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java index c7691c3662..02f59dc8b2 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java @@ -7,7 +7,6 @@ import java.io.File; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Parameter; -import org.assertj.core.util.Strings; import io.codearte.accurest.AccurestException; import io.codearte.accurest.TestGenerator; @@ -44,13 +43,6 @@ public abstract class AbstractGenerateVerificationCodeMojo extends AbstractMojo config.setContractsDslDir(new File(baseDir, contractsDir)); config.setBasePackageForTests(basePackageForTests); config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); - if (Strings.isNullOrEmpty(baseClassForTests)) { - if (!Strings.isNullOrEmpty(basePackageForTests)) { - baseClassForTests = basePackageForTests + '.' + "BaseAccurest"; - } else { - baseClassForTests = "io.codearte.accurest.tests.BaseAccurest"; - } - } config.setBaseClassForTests(baseClassForTests); config.setTargetFramework(testFramework); config.setTestMode(testMode); diff --git a/maven-plugin/src/test/projects/spring-boot-java/pom.xml b/maven-plugin/src/test/projects/spring-boot-java/pom.xml index e7be85facd..1bdf2d1333 100644 --- a/maven-plugin/src/test/projects/spring-boot-java/pom.xml +++ b/maven-plugin/src/test/projects/spring-boot-java/pom.xml @@ -55,7 +55,6 @@ 1.8 - @@ -76,6 +75,7 @@ hello + hello.BaseMockMvcTest @@ -123,17 +123,4 @@ - - - - spring-releases - https://repo.spring.io/libs-release - - - - - spring-releases - https://repo.spring.io/libs-release - - diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java b/maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java similarity index 87% rename from maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java rename to maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java index d3bf7124e2..2fe6a9564a 100644 --- a/maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java +++ b/maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java @@ -3,7 +3,7 @@ package hello; import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; import org.junit.Before; -public class BaseAccurest { +public class BaseMockMvcTest { @Before public void setup() { From 2bc9fea27609ccaa0f659058e3fc21bce3d7ee09 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 21:32:41 +0200 Subject: [PATCH 389/719] revert two goals to generate tests --- README.md | 2 +- .../AbstractGenerateVerificationCodeMojo.java | 62 ------------------- .../accurest/maven/GenerateSpecsMojo.java | 18 ------ .../accurest/maven/GenerateTestsMojo.java | 58 ++++++++++++++++- .../accurest/maven/PluginIntegrationTest.java | 8 ++- .../accurest/maven/PluginUnitTest.java | 2 +- .../test/projects/spring-boot-groovy/pom.xml | 3 +- 7 files changed, 64 insertions(+), 89 deletions(-) delete mode 100644 maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java delete mode 100644 maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java diff --git a/README.md b/README.md index a853b5a6b0..313d75d4ad 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Sample usage generateStubs - generateSpecs + generateTests diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java deleted file mode 100644 index 02f59dc8b2..0000000000 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/AbstractGenerateVerificationCodeMojo.java +++ /dev/null @@ -1,62 +0,0 @@ -package io.codearte.accurest.maven; - -import static java.lang.String.format; - -import java.io.File; - -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugins.annotations.Parameter; - -import io.codearte.accurest.AccurestException; -import io.codearte.accurest.TestGenerator; -import io.codearte.accurest.config.AccurestConfigProperties; -import io.codearte.accurest.config.TestFramework; -import io.codearte.accurest.config.TestMode; - -public abstract class AbstractGenerateVerificationCodeMojo extends AbstractMojo { - - @Parameter(defaultValue = "${basedir}", readonly = true, required = true) - protected File baseDir; - - @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) - protected File projectBuildDirectory; - - @Parameter(defaultValue = "/src/test/accurest") - protected String contractsDir; - - @Parameter(defaultValue = "/generated-test-sources/accurest") - protected String generatedTestSourcesDir; - - @Parameter(defaultValue = "io.codearte.accurest.tests") - protected String basePackageForTests; - - @Parameter - protected String baseClassForTests; - - @Parameter(defaultValue = "MOCKMVC") - protected TestMode testMode; - - protected void generateVerificationCode(TestFramework testFramework) throws MojoExecutionException { - - AccurestConfigProperties config = new AccurestConfigProperties(); - config.setContractsDslDir(new File(baseDir, contractsDir)); - config.setBasePackageForTests(basePackageForTests); - config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); - config.setBaseClassForTests(baseClassForTests); - config.setTargetFramework(testFramework); - config.setTestMode(testMode); - - getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); - getLog().info(format("Using %s as base class for verification classes", config.getBaseClassForTests())); - - try { - TestGenerator generator = new TestGenerator(config); - int generatedClasses = generator.generate(); - getLog().info(format("Generated %s test classes.", generatedClasses)); - } catch (AccurestException e) { - throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e); - } - } - -} diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java deleted file mode 100644 index 4f1844b49d..0000000000 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateSpecsMojo.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.codearte.accurest.maven; - -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; - -import io.codearte.accurest.config.TestFramework; - -@Mojo(name = "generateSpecs", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) -public class GenerateSpecsMojo extends AbstractGenerateVerificationCodeMojo { - - public void execute() throws MojoExecutionException, MojoFailureException { - getLog().info("Generating Spock Specifications source code for Accurest contract verification"); - generateVerificationCode(TestFramework.SPOCK); - } - -} diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java index 2b82877740..b074b06b66 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java @@ -1,18 +1,70 @@ package io.codearte.accurest.maven; +import static java.lang.String.format; + +import java.io.File; + +import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import io.codearte.accurest.AccurestException; +import io.codearte.accurest.TestGenerator; +import io.codearte.accurest.config.AccurestConfigProperties; import io.codearte.accurest.config.TestFramework; +import io.codearte.accurest.config.TestMode; @Mojo(name = "generateTests", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) -public class GenerateTestsMojo extends AbstractGenerateVerificationCodeMojo { +public class GenerateTestsMojo extends AbstractMojo { + + @Parameter(defaultValue = "${basedir}", readonly = true, required = true) + private File baseDir; + + @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) + private File projectBuildDirectory; + + @Parameter(defaultValue = "/src/test/accurest") + private String contractsDir; + + @Parameter(defaultValue = "/generated-test-sources/accurest") + private String generatedTestSourcesDir; + + @Parameter(defaultValue = "io.codearte.accurest.tests") + private String basePackageForTests; + + @Parameter + private String baseClassForTests; + + @Parameter(defaultValue = "MOCKMVC") + private TestMode testMode; + + @Parameter(defaultValue = "JUNIT") + private TestFramework testFramework; public void execute() throws MojoExecutionException, MojoFailureException { - getLog().info("Generating JUnit Tests source code for Accurest contract verification"); - generateVerificationCode(TestFramework.JUNIT); + getLog().info("Generating server tests source code for Accurest contract verification"); + + AccurestConfigProperties config = new AccurestConfigProperties(); + config.setContractsDslDir(new File(baseDir, contractsDir)); + config.setBasePackageForTests(basePackageForTests); + config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); + config.setBaseClassForTests(baseClassForTests); + config.setTargetFramework(testFramework); + config.setTestMode(testMode); + + getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); + getLog().info(format("Using %s as base class for test classes", config.getBaseClassForTests())); + + try { + TestGenerator generator = new TestGenerator(config); + int generatedClasses = generator.generate(); + getLog().info(format("Generated %s test classes.", generatedClasses)); + } catch (AccurestException e) { + throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e); + } } } diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java index 6d7ed574e2..4ed2c79be2 100644 --- a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java +++ b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java @@ -33,19 +33,20 @@ public class PluginIntegrationTest { maven.forProject(basedir) .execute("package") .assertErrorFreeLog() - .assertLogText("Generating Spock Specifications source code for Accurest contract verification") + .assertLogText("Generating server tests source code for Accurest contract verification") .assertLogText("Generated 1 test classes.") .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") .assertLogText("Creating new json") .assertErrorFreeLog(); } + @Test public void should_build_project_Spring_Boot_Java_with_Accurest() throws Exception { File basedir = resources.getBasedir("spring-boot-java"); maven.forProject(basedir) .execute("package") .assertErrorFreeLog() - .assertLogText("Generating JUnit Tests source code for Accurest contract verification") + .assertLogText("Generating server tests source code for Accurest contract verification") .assertLogText("Generated 1 test classes.") .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") .assertLogText("Creating new json") @@ -58,7 +59,8 @@ public class PluginIntegrationTest { properties.getPluginVersion(); maven.forProject(basedir) .withCliOption("-X") - .execute(String.format("io.codearte.accurest:accurest-maven-plugin:%s:convert", properties.getPluginVersion())) + .execute(String.format("io.codearte.accurest:accurest-maven-plugin:%s:convert", + properties.getPluginVersion())) .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") .assertLogText("Creating new json") .assertErrorFreeLog(); diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 1d04aa339a..35ebfc472a 100644 --- a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -43,7 +43,7 @@ public class PluginUnitTest { @Test public void shouldGenerateContractSpecificationInDefaultLocation() throws Exception { File basedir = resources.getBasedir("basic"); - maven.executeMojo(basedir, "generateSpecs"); + maven.executeMojo(basedir, "generateTests", newParameter("testFramework", "SPOCK")); assertFilesPresent(basedir, "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestSpec.groovy"); } diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml b/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml index a51dd6f7cd..2bdf3e7d97 100644 --- a/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml +++ b/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml @@ -79,13 +79,14 @@ generateStubs - generateSpecs + generateTests com.ofg.twitter.place.BaseMockMvcSpec /src/test/resources/stubs + SPOCK From 004582190216f04366dda3c5f7efe8c74428740b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 22:29:51 +0200 Subject: [PATCH 390/719] added rule class param --- .../io/codearte/accurest/maven/GenerateTestsMojo.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java index b074b06b66..0d89bb59c1 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java @@ -44,16 +44,20 @@ public class GenerateTestsMojo extends AbstractMojo { @Parameter(defaultValue = "JUNIT") private TestFramework testFramework; + @Parameter + private String ruleClassForTests; + public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("Generating server tests source code for Accurest contract verification"); AccurestConfigProperties config = new AccurestConfigProperties(); config.setContractsDslDir(new File(baseDir, contractsDir)); - config.setBasePackageForTests(basePackageForTests); config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); - config.setBaseClassForTests(baseClassForTests); config.setTargetFramework(testFramework); config.setTestMode(testMode); + config.setBasePackageForTests(basePackageForTests); + config.setBaseClassForTests(baseClassForTests); + config.setRuleClassForTests(ruleClassForTests); getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); getLog().info(format("Using %s as base class for test classes", config.getBaseClassForTests())); From 9302863ddeb5608cff2c4222cef8c8196f918b4f Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 22:31:48 +0200 Subject: [PATCH 391/719] added nameSuffixForTests --- .../java/io/codearte/accurest/maven/GenerateTestsMojo.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java index 0d89bb59c1..467e60abe0 100644 --- a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java +++ b/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java @@ -47,6 +47,9 @@ public class GenerateTestsMojo extends AbstractMojo { @Parameter private String ruleClassForTests; + @Parameter + private String nameSuffixForTests; + public void execute() throws MojoExecutionException, MojoFailureException { getLog().info("Generating server tests source code for Accurest contract verification"); @@ -58,6 +61,7 @@ public class GenerateTestsMojo extends AbstractMojo { config.setBasePackageForTests(basePackageForTests); config.setBaseClassForTests(baseClassForTests); config.setRuleClassForTests(ruleClassForTests); + config.setNameSuffixForTests(nameSuffixForTests); getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); getLog().info(format("Using %s as base class for test classes", config.getBaseClassForTests())); From 6809ed14442dd69d123dd83626ebc321aec3b0c1 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 22:46:54 +0200 Subject: [PATCH 392/719] added nameSuffixForTests --- maven-plugin/src/test/projects/spring-boot-groovy/pom.xml | 7 ++++--- .../place/{AcceptanceSpec.groovy => AcceptanceTest.groovy} | 2 +- .../{BaseMockMvcSpec.groovy => BaseMockMvcTest.groovy} | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) rename maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/{AcceptanceSpec.groovy => AcceptanceTest.groovy} (94%) rename maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/{BaseMockMvcSpec.groovy => BaseMockMvcTest.groovy} (86%) diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml b/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml index 2bdf3e7d97..217022bd53 100644 --- a/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml +++ b/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml @@ -84,9 +84,10 @@ - com.ofg.twitter.place.BaseMockMvcSpec + com.ofg.twitter.place.BaseMockMvcTest /src/test/resources/stubs SPOCK + Test @@ -119,7 +120,7 @@ - + maven-assembly-plugin 2.6 diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy similarity index 94% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy rename to maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy index 3c244ce6cd..d132261ded 100644 --- a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceSpec.groovy +++ b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy @@ -9,7 +9,7 @@ import spock.lang.Specification import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status -class AcceptanceSpec extends Specification { +class AcceptanceTest extends Specification { def "should have controller up and running"() { given: diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy similarity index 86% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy rename to maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy index b85a44721d..96bf1e60c4 100644 --- a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcSpec.groovy +++ b/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy @@ -4,7 +4,7 @@ import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc import com.ofg.twitter.place.PairIdController import spock.lang.Specification -abstract class BaseMockMvcSpec extends Specification { +abstract class BaseMockMvcTest extends Specification { def setup() { RestAssuredMockMvc.standaloneSetup(new PairIdController()) From 75638eef00d22e8710f8d40601b4e1a205234dcb Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 23:20:20 +0200 Subject: [PATCH 393/719] failsafe --- maven-plugin/pom.xml | 16 +++++++++++++++- ...{PluginIntegrationTest.java => PluginIT.java} | 4 ++-- 2 files changed, 17 insertions(+), 3 deletions(-) rename maven-plugin/src/test/java/io/codearte/accurest/maven/{PluginIntegrationTest.java => PluginIT.java} (94%) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 87a5986111..39520a4827 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 @@ -102,6 +103,19 @@ none + + org.apache.maven.plugins + maven-failsafe-plugin + 2.19.1 + + + + integration-test + verify + + + + org.jacoco jacoco-maven-plugin diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIT.java similarity index 94% rename from maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java rename to maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIT.java index 4ed2c79be2..a13dcc4257 100644 --- a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIntegrationTest.java +++ b/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIT.java @@ -14,7 +14,7 @@ import io.takari.maven.testing.executor.junit.MavenJUnitTestRunner; @RunWith(MavenJUnitTestRunner.class) @MavenVersions({ "3.3.3" }) -public class PluginIntegrationTest { +public class PluginIT { @Rule public final TestResources resources = new TestResources(); @@ -23,7 +23,7 @@ public class PluginIntegrationTest { private final MavenRuntime maven; - public PluginIntegrationTest(MavenRuntime.MavenRuntimeBuilder mavenBuilder) throws Exception { + public PluginIT(MavenRuntime.MavenRuntimeBuilder mavenBuilder) throws Exception { this.maven = mavenBuilder.withCliOptions("-B", "-U").build(); } From a5ba772867937636d3cc5ef0a7b9bcf3add18337 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sun, 3 Apr 2016 20:43:51 +0200 Subject: [PATCH 394/719] Update README.md --- README.md | 77 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 75 deletions(-) diff --git a/README.md b/README.md index 313d75d4ad..0c41985fb0 100644 --- a/README.md +++ b/README.md @@ -4,82 +4,9 @@ Accurate REST Maven Plugin ==== -Converting Accurest GroovyDSL into WireMock stub mappings: +Converting [Accurest](https://github.com/Codearte/accurest/wiki/1.-Introduction) GroovyDSL into WireMock stub mappings: mvn io.codearte.accurest:accurest-maven-plugin:convert -Sample usage ----- -```xml - - io.codearte.accurest - accurest-maven-plugin - - - - generateStubs - generateTests - - - - -``` - - -Project default directories ---- - -_contractsDir_ - contract definitions: - - /src/test/accurest - -_generatedTestSourcesDir_ - Generated accurest specifications: - - /target/generated-test-sources/accurest - -Publishing wiremock stubs jar ---- - -Project configuration - -```xml - - io.codearte.accurest - accurest-maven-plugin - ${accurest.version} - - - - generateStubs - - - - - - maven-assembly-plugin - 2.6 - - - io.codearte.accurest - stubs-assembly-descriptor - 1.1 - - - - - package - - single - - - - - - stubs - - - -``` - -Deploy to artifact repository using `mvn deploy` +For more information please go to the [Wiki](https://github.com/Codearte/accurest/wiki/2.2-Maven-Project) From 845142b942e54c35b354c91b1104e5b338bb500c Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 23:23:00 +0200 Subject: [PATCH 395/719] [maven-release-plugin] prepare release accurest-maven-project-0.2 --- maven-plugin/pom.xml | 5 ++--- pom.xml | 7 +++---- test-deps/pom.xml | 2 +- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 39520a4827..4de32e7a68 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.codearte.accurest accurest-maven-project - 0.1.2-SNAPSHOT + 0.2 accurest-maven-plugin diff --git a/pom.xml b/pom.xml index 2874ab45ac..8defa61d5d 100644 --- a/pom.xml +++ b/pom.xml @@ -1,11 +1,10 @@ - + 4.0.0 io.codearte.accurest accurest-maven-project - 0.1.2-SNAPSHOT + 0.2 Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -51,7 +50,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - HEAD + accurest-maven-project-0.2 diff --git a/test-deps/pom.xml b/test-deps/pom.xml index 59a7591be9..52195e0e24 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -5,7 +5,7 @@ accurest-maven-project io.codearte.accurest - 0.1.2-SNAPSHOT + 0.2 accurest-test-deps From a5683cf874129031942b46087e28dfbe98b07ab2 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 2 Apr 2016 23:23:00 +0200 Subject: [PATCH 396/719] [maven-release-plugin] prepare for next development iteration --- maven-plugin/pom.xml | 2 +- pom.xml | 4 ++-- test-deps/pom.xml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 4de32e7a68..d9c8c74ffc 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -5,7 +5,7 @@ io.codearte.accurest accurest-maven-project - 0.2 + 0.3-SNAPSHOT accurest-maven-plugin diff --git a/pom.xml b/pom.xml index 8defa61d5d..77df52b6f1 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ io.codearte.accurest accurest-maven-project - 0.2 + 0.3-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -50,7 +50,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - accurest-maven-project-0.2 + HEAD diff --git a/test-deps/pom.xml b/test-deps/pom.xml index 52195e0e24..bdf83e2a5b 100644 --- a/test-deps/pom.xml +++ b/test-deps/pom.xml @@ -5,7 +5,7 @@ accurest-maven-project io.codearte.accurest - 0.2 + 0.3-SNAPSHOT accurest-test-deps From 2405baa2e240d23ed1f1c9e9b25dd58f2fe04864 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 3 Apr 2016 21:39:27 +0200 Subject: [PATCH 397/719] Enable Continuous Release --- .mvn/settings.xml | 23 +++++++++++++++ .travis.yml | 36 ++++++++++++++++++++---- pom.xml | 72 +++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 .mvn/settings.xml diff --git a/.mvn/settings.xml b/.mvn/settings.xml new file mode 100644 index 0000000000..3d1ffa5d1b --- /dev/null +++ b/.mvn/settings.xml @@ -0,0 +1,23 @@ + + + + oss + ${env.CI_DEPLOY_USERNAME} + ${env.CI_DEPLOY_PASSWORD} + + + + + + oss + + true + + + ${env.GPG_KEY_NAME} + ${env.GPG_PASSPHRASE} + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index df5da30d05..91263065ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,33 @@ language: java - jdk: - - oraclejdk8 - -script: ./mvnw package - +- oraclejdk8 +before_install: +- openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d +- gpg --fast-import .mvn/codesigning.asc +before_script: +- ./mvnw release-candidate:updateVersion -Drevision=$TRAVIS_BUILD_NUMBER +script: +- ./mvnw deploy --settings .mvn/settings.xml -Prelease after_success: - - ./mvnw clean test jacoco:report coveralls:report \ No newline at end of file +- git config --global user.email "builds@travis-ci.com" +- git config --global user.name "Travis CI" +- export GIT_TAG=build-$(date -u "+%Y-%m-%d")-$TRAVIS_BUILD_NUMBER +- echo -n $GIT_TAG > public/version +- git commit -m "Set build VERSION number" public/version +- git tag $GIT_TAG -a -m "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER" +- git push --quiet https://$GITHUBKEY@github.com/mariuszs/playground.git + $GIT_TAG > /dev/null 2>&1 +- ./mvnw clean test jacoco:report coveralls:report +branches: + except: + - /^build-[0-9a-z\-]*/ +cache: + directories: + - "~/.m2/repository" +env: + global: + - secure: oYAoU+PDuaWLo4MBoQYCF++kEqwWn8xtDAeBxBRIvduJO7758+haeSW43AFjmLfuJ9aUdfS+MrqGnDuj+Nqw1oSU9vdbyX7m+Q3wFDkO1Ln2NCaifrSCVHaAAMSfSKNlYBjD4+sATsrnSF75BSIS2WMNItkGcac7DPD+Ls64Ovw9MbkMB2i4TRYboGFNvOhtFYSOexd6hWltin0s6EHtsqFJKBKiPfvZYPJ34d0bfvMbi/TyfDoaia0QG8EUqyF1FZhBT5j/iXD03kTMdZ59o3pUgkgZjMfiD7rJGWffwZ+kV8PtzYyzjhiH8o+tqhFkLRXfu+s6zcMjBhJDR1rgguEqzlKbGRoFahY5PI+fbLwyNz+kQwtXxF3+lpwM/VZ/1OHPgpTtdDiz5ArRskb/Y/caGbLhjkm4V2x3/7fvRHGcLZf7DraJoShT/5MvG0AN7PCjEhbGX+08YaRucmQLWHUo1pGazwagP+7MqDsimdR+VzIY/HUctFi4DPOLjmZROukcPCFJTwn2T/0TFC5Luptb5ifsT9RvBv89/A71XcYs6rrGcU4UHdy6gZwWIRECKG82X+0jwoM39dFfweF7iVIuimdK2+yy4DtLZQfeqR7pWphs2i42twQUWcwIpRQyi/hn+wteVz7yxIBKfphaIVVP3juS1RPtMD0vOm8BRpo= + - secure: JnHy2f/hedU35C5imIRND+OOaM7xAfuJBa5l5rDKuxFmEQgnbxAYQVNij7QkawrdUsdIr/c8OmcmdSL7grxbblY4dRgwlSw/2LycmdZesSUci752beRZgz8ZnuERP3SLJcCbMYabUezd2GK4dElOt/BaZuGM9JDdV87Yz2yZfihcL8az/JQv8HJKdtkRlAzI3m7FIlA/ArsLnIUcibAkKwQqLBzjZWs+U0XmwCqcyX5YhQPZWl/wLrM12yRPJuPUXb7n+cGo8QIPCuLo7tHR4qBaYM9+1bVLqQ9irvJQ4o22G+NLsZPtzYx4XRTmTwFFmKEmNA05EfgwezaHOwifKOavdeCx1dx4sgznV176dXEcWVYJkr7UWiSy4+RcL/eclP6Ha+wEoC1NG2m8aVTDbDGOIpeR7YOBDA5RrB+bdQvkdp86lNbaC1BeC7pWCxgwstmLy0FiX2qF6HjIut6Yt2K+nUQLFiySE0nzkR7ZaKdRyNj0FO/dYd2glZHSv4Z3koqpXpnwcMlcfG1KaDuX6PryKKr2ocIsvTJDU1XzqkwdKcAqkCYCkYasheSY5JPV6746giATHQPlSMJaWjnFARJHunZ00ua64vc/WbYrTQhb+VKGDLwe2K4EMpTeUXceKhFPEZyHRdS3v9upUSDYsYhIwyOL+LXwPIPLz2J/ku0= + - secure: TcIM58kEMWOCBCyUq8yPA4r2W15xCsUvt3e3EPn7njiSpOMo1P5sTxVduddLSoHvcLpn3nci6TWzwqBb+kBMQoYwKKbCYrdxPb18HrekoRYk31saQpi4zQGzKl/ENoztLVSjcGnRNmoIKvQ5Hux/OZ7PFbDBFtsyf1OfzyCnu0q9vvY2e+uIbpuJMhbcQhx7+cLaS0i5cf+2l4ldzOYUDazCV0CLdUYfme+RrkSriLmgHZ4NN0+bKX6JYJFy5mwfyl+EP8QuirPh+rpVG1CyGz/+7nRY5GeiX1V7ZJzxGBBIOa4Uq73mvMxmlA8ojgYFfcpHl56nzpl0Usou04PiFzi5M4cVGY9uFy5mBcoaBjXS6I791HJhK3AayMigNfnxhf0VELBHUD/o2bn+2VTGtHwbac2vbd+2M7Ia4ZGq9HQLet1Wk/QO3jCLWOG4Vkg9phWCip3tMJP0YuocK3Y4fV/+/aKBs3XR/t7IRAWPpTyn83K3OzXcDpxYUewMvEvk7EgunU90vXcVPzgAPMQ0erkUuZ8U/v7JGsr9ZTbmAUegc51bRmYh2ykkELMv3tr4wQB0FsRtt5O1lqjUV4KcUE3ORGXYOePenisOb00PlmXhEzKgAaXXcK/8aEGD0rvohYRDdINS3WIPLFnGxkI42wWlf8OY8HICFe31EHy7nbY= + - secure: tlZB9DK8Q27upg4L+Nmb57ItvXjQ2Nq6rRJjndPKLEi8PqE6t/JBA5PAkq8JNsYMd6IydF9/NTao97fwq4lYlcAIm7xkymx9O2mVniRR6FE/nz9Z8bze/OoIFTxd8fCSSSotZGW3c3eX2WcMHfY9XOVEwUnvXGLsFPem9fS+ckQ0HNoEaeNItAubMtSXwHCUEK7gskThcULhH+yoNPLsx1RYxKkcR2Ijam+kcrdXBGnNU+2EVcxtPkJVs9j3LQiBIYVDm3I/8cQlOsVsVDIe8+zcp00PuK8cagHi3oFGl84jOOEZnqKBi+gcIzG/8zhNP/z9E9qbt9eA/eCUQXj1Wp5658IJJrCqjmrxdWyiIr69LJWjVWkSyG0sfzszaFfRvuDdCutnnqef2BVJ+GaF3MODsTHyC8N3kiVjJje5u40PT6CzyXlnKHT9CMUt0SnqL3omgJnXyzqZ+MlqwcWJ3qbYRvUN9dp8F6j8rYdkP5WXhhs1UXvtz8Kkya6GuBTTIUFXYQCwhHB1XfXr3lK2fanRtoZBkUos8wxcc2pTax/Z7gkCerS/RATAPxvHSvBuVq+taND/R7x8Rj/DAfjWuAEC6l8rtJm8ve2dARYxeXj1dkznBQuxQqMU9PN0l2f9ZR+rs3KyCl8rym5ESduvqCCXQGQDQlk+jUdayKXeCmM= + - secure: exbai4hxMVO2Wc480kD9L7dEQEuJTTyUINHyfx01Y6KuVf8rw+zKDhVwVF4b5g1frk/R27GuD0g4jWH2yRhXLkOMmc9OOuBfL4OsrxEFhZr85EgQGIz4ME5+NaifU3pxGPVl5/GqjZhumI5XfcQjF/4bdMOTthD0At2z4pE6jmydJHNmwBGD1hw3ox6xAJBASussbvRSHslOSKmkM5ktjtAstzOTpggOdA/eXC/43rZb78THBaDcaR54nF/NdmlexKw+SCZRMIibVI15m+9GZCBRQLM5ndes0vOmi7SUPDPQ2r3r9djx6VKOaaqM4RWpv36lryneervXLj4XV02Ndbv9LqGZApANvrwRN1a5hEPb+X1wg6YHsVCOErG0f9JvnjADxStZrATdVGDMQueMXQUOp8dYD5kO2SfSahKFLDt3f5JRGRXXMmMdW3Jgt8clviRvvuXuBUy13PaXG7fM48mr0x1VvIsvRjOg5NgWHmq/j5MklOEy3LrG2636/3piV2HJZ0GRV/GgPxrVscEDYxPc7Dx5TUyIuhrqH3EjbgCcoddkpb00e9V/IyQ7fF7lyYUnzLBsVoQxgThPBcpKXm41OAvrgHtrK30gvb4HX5mjEBoXdJUgyhSXBzWvx3ApfyTdxd/KL/ga1fe7fHgfQEQLkF8WR5IqolPcGnGlu0E= diff --git a/pom.xml b/pom.xml index 77df52b6f1..a65795f8d2 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 io.codearte.accurest @@ -35,6 +36,8 @@ UTF-8 1.0.1 + + 0000000 @@ -55,12 +58,12 @@ - sonatype-nexus-snapshots + oss Sonatype Nexus Snapshots http://oss.sonatype.org/content/repositories/snapshots - sonatype-nexus-staging + oss Nexus Release Repository http://oss.sonatype.org/service/local/staging/deploy/maven2/ @@ -69,13 +72,38 @@ - org.apache.maven.plugins - maven-release-plugin - 2.5.3 + com.smartcodeltd + release-candidate-maven-plugin + 1.0-201603091838.01dbbbf + + + default-cli + + updateVersion + + + {{ api_version }}.${revision} + + + + + version + + + PROJECT_VERSION={{ version }} + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true - false - true - true + oss + https://oss.sonatype.org/ + false @@ -142,6 +170,32 @@ + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + + From e3cf9d4fc79f615302e99fe69dfd803e43e0f469 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 3 Apr 2016 21:41:33 +0200 Subject: [PATCH 398/719] missing key --- .mvn/codesigning.asc.enc | Bin 0 -> 7280 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .mvn/codesigning.asc.enc diff --git a/.mvn/codesigning.asc.enc b/.mvn/codesigning.asc.enc new file mode 100644 index 0000000000000000000000000000000000000000..da867ac9b11c107076098d6f7c5ab3cc24b1d503 GIT binary patch literal 7280 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 Date: Sun, 3 Apr 2016 21:51:19 +0200 Subject: [PATCH 399/719] wrong repository --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 91263065ed..93736d3037 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ after_success: - echo -n $GIT_TAG > public/version - git commit -m "Set build VERSION number" public/version - git tag $GIT_TAG -a -m "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER" -- git push --quiet https://$GITHUBKEY@github.com/mariuszs/playground.git +- git push --quiet https://$GITHUBKEY@github.com/Codearte/accurest-maven-plugin $GIT_TAG > /dev/null 2>&1 - ./mvnw clean test jacoco:report coveralls:report branches: From 40e044e190c34ed21f4e7dcd5cafb0b73a01b943 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 3 Apr 2016 22:13:17 +0200 Subject: [PATCH 400/719] switch to standard maven plugin package --- maven-plugin/pom.xml | 48 +++++++++++++++++++++++++++++++++++++++----- pom.xml | 4 ---- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index d9c8c74ffc..6d70ca7c4e 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -9,7 +9,7 @@ accurest-maven-plugin - takari-maven-plugin + maven-plugin @@ -93,14 +93,53 @@ + + org.codehaus.plexus + plexus-component-metadata + + + + generate-metadata + generate-test-metadata + + + + + + maven-plugin-plugin + ${mavenPluginPluginVersion} + + true + + + + generated-helpmojo + + helpmojo + + + + generate-descriptor + + descriptor + + + + io.takari.maven.plugins takari-lifecycle-plugin 1.11.12 true - - none - + + + testProperties + process-test-resources + + testProperties + + + org.apache.maven.plugins @@ -134,7 +173,6 @@ - org.eluder.coveralls coveralls-maven-plugin diff --git a/pom.xml b/pom.xml index a65795f8d2..e81d7a7780 100644 --- a/pom.xml +++ b/pom.xml @@ -110,10 +110,6 @@ - - maven-deploy-plugin - 2.8.2 - maven-install-plugin 2.5.2 From 7ada470d11650241c5d5ca2d410dda7000649c2b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 3 Apr 2016 22:18:37 +0200 Subject: [PATCH 401/719] issues badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0c41985fb0..0bdaaa2185 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) +[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)]() Accurate REST Maven Plugin ==== From 643b6b9f00f44e7131d8394759338ba6003722c8 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 3 Apr 2016 22:26:26 +0200 Subject: [PATCH 402/719] auto release! --- README.md | 2 +- pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0bdaaa2185..c4a17f6260 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)]() +[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)]() [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)]() Accurate REST Maven Plugin ==== diff --git a/pom.xml b/pom.xml index e81d7a7780..be73334c92 100644 --- a/pom.xml +++ b/pom.xml @@ -103,7 +103,7 @@ oss https://oss.sonatype.org/ - false + true From cb18c788080b941158a2cfaa69f493649b0e6dce Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 3 Apr 2016 22:29:33 +0200 Subject: [PATCH 403/719] added issues url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c4a17f6260..afd9ef5b5b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)]() [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)]() +[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/issues) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)]() Accurate REST Maven Plugin ==== From 3b461e07850ab6949d0f07ff872708b2db0561d5 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 3 Apr 2016 22:31:52 +0200 Subject: [PATCH 404/719] better issue link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index afd9ef5b5b..c977e3ca67 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/issues) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)]() +[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)]() Accurate REST Maven Plugin ==== From ce67a2fb061633cec6a576fc1722c27825180229 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 4 Apr 2016 09:31:43 +0200 Subject: [PATCH 405/719] limit deploy to master --- .travis.yml | 8 ++++---- README.md | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 93736d3037..e554463caf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,12 @@ language: java jdk: - oraclejdk8 before_install: -- openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d -- gpg --fast-import .mvn/codesigning.asc +- [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d +- [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && gpg --fast-import .mvn/codesigning.asc before_script: - ./mvnw release-candidate:updateVersion -Drevision=$TRAVIS_BUILD_NUMBER script: -- ./mvnw deploy --settings .mvn/settings.xml -Prelease +- [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && ./mvnw deploy --settings .mvn/settings.xml -Prelease after_success: - git config --global user.email "builds@travis-ci.com" - git config --global user.name "Travis CI" @@ -15,7 +15,7 @@ after_success: - echo -n $GIT_TAG > public/version - git commit -m "Set build VERSION number" public/version - git tag $GIT_TAG -a -m "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER" -- git push --quiet https://$GITHUBKEY@github.com/Codearte/accurest-maven-plugin +- [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && git push --quiet https://$GITHUBKEY@github.com/Codearte/accurest-maven-plugin $GIT_TAG > /dev/null 2>&1 - ./mvnw clean test jacoco:report coveralls:report branches: diff --git a/README.md b/README.md index c977e3ca67..46e1b4612c 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,21 @@ Accurate REST Maven Plugin Converting [Accurest](https://github.com/Codearte/accurest/wiki/1.-Introduction) GroovyDSL into WireMock stub mappings: mvn io.codearte.accurest:accurest-maven-plugin:convert + +or shortly + + mvn accurest:convert + +but this requires additional configuration inside `~/.m2/settings.xml` + +```xml + + + io.codearte.accurest + + + +``` For more information please go to the [Wiki](https://github.com/Codearte/accurest/wiki/2.2-Maven-Project) From 28cb38e69a27310ea356014c8994adb56b30b35d Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 4 Apr 2016 09:56:29 +0200 Subject: [PATCH 406/719] travis fix --- .travis.yml | 8 ++++---- README.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index e554463caf..f5ddf41830 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,12 @@ language: java jdk: - oraclejdk8 before_install: -- [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d -- [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && gpg --fast-import .mvn/codesigning.asc +- \[ "$TRAVIS_BRANCH" = 'master' \] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d +- \[ "$TRAVIS_BRANCH" = 'master' \] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && gpg --fast-import .mvn/codesigning.asc before_script: - ./mvnw release-candidate:updateVersion -Drevision=$TRAVIS_BUILD_NUMBER script: -- [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && ./mvnw deploy --settings .mvn/settings.xml -Prelease +- \[ "$TRAVIS_BRANCH" = 'master' \] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && ./mvnw deploy --settings .mvn/settings.xml -Prelease after_success: - git config --global user.email "builds@travis-ci.com" - git config --global user.name "Travis CI" @@ -15,7 +15,7 @@ after_success: - echo -n $GIT_TAG > public/version - git commit -m "Set build VERSION number" public/version - git tag $GIT_TAG -a -m "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER" -- [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && git push --quiet https://$GITHUBKEY@github.com/Codearte/accurest-maven-plugin +- \[ "$TRAVIS_BRANCH" = 'master' \] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && git push --quiet https://$GITHUBKEY@github.com/Codearte/accurest-maven-plugin $GIT_TAG > /dev/null 2>&1 - ./mvnw clean test jacoco:report coveralls:report branches: diff --git a/README.md b/README.md index 46e1b4612c..542d7616b3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)]() +[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) Accurate REST Maven Plugin ==== From 9601dafbe1693fefeb139f3a3d86b0186e33f72b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 4 Apr 2016 10:21:02 +0200 Subject: [PATCH 407/719] another fix --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index f5ddf41830..93011840cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,12 +2,12 @@ language: java jdk: - oraclejdk8 before_install: -- \[ "$TRAVIS_BRANCH" = 'master' \] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d -- \[ "$TRAVIS_BRANCH" = 'master' \] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && gpg --fast-import .mvn/codesigning.asc +- true && [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d +- true && [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && gpg --fast-import .mvn/codesigning.asc before_script: - ./mvnw release-candidate:updateVersion -Drevision=$TRAVIS_BUILD_NUMBER script: -- \[ "$TRAVIS_BRANCH" = 'master' \] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && ./mvnw deploy --settings .mvn/settings.xml -Prelease +- true && [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && ./mvnw deploy --settings .mvn/settings.xml -Prelease after_success: - git config --global user.email "builds@travis-ci.com" - git config --global user.name "Travis CI" @@ -15,7 +15,7 @@ after_success: - echo -n $GIT_TAG > public/version - git commit -m "Set build VERSION number" public/version - git tag $GIT_TAG -a -m "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER" -- \[ "$TRAVIS_BRANCH" = 'master' \] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && git push --quiet https://$GITHUBKEY@github.com/Codearte/accurest-maven-plugin +- true && [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && git push --quiet https://$GITHUBKEY@github.com/Codearte/accurest-maven-plugin $GIT_TAG > /dev/null 2>&1 - ./mvnw clean test jacoco:report coveralls:report branches: From 6b8e379283e9072b83365b1cbdb2ed2bde33be19 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 4 Apr 2016 23:17:59 +0200 Subject: [PATCH 408/719] fixed travis issues --- .mvn/settings.xml | 4 ++++ .travis.yml | 22 ++++++++-------------- pom.xml | 18 +++++++++++++++++- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/.mvn/settings.xml b/.mvn/settings.xml index 3d1ffa5d1b..f94b247a34 100644 --- a/.mvn/settings.xml +++ b/.mvn/settings.xml @@ -6,6 +6,10 @@ ${env.CI_DEPLOY_USERNAME} ${env.CI_DEPLOY_PASSWORD} + + github.com + ${env.GITHUBKEY} + diff --git a/.travis.yml b/.travis.yml index 93011840cf..4e5fee2854 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,25 +2,19 @@ language: java jdk: - oraclejdk8 before_install: -- true && [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d -- true && [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && gpg --fast-import .mvn/codesigning.asc -before_script: -- ./mvnw release-candidate:updateVersion -Drevision=$TRAVIS_BUILD_NUMBER -script: -- true && [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && ./mvnw deploy --settings .mvn/settings.xml -Prelease -after_success: +- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d; fi +- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then gpg --fast-import .mvn/codesigning.asc; fi - git config --global user.email "builds@travis-ci.com" - git config --global user.name "Travis CI" -- export GIT_TAG=build-$(date -u "+%Y-%m-%d")-$TRAVIS_BUILD_NUMBER -- echo -n $GIT_TAG > public/version -- git commit -m "Set build VERSION number" public/version -- git tag $GIT_TAG -a -m "Generated tag from TravisCI build $TRAVIS_BUILD_NUMBER" -- true && [ "$TRAVIS_BRANCH" = 'master' ] && [ "$TRAVIS_PULL_REQUEST" == 'false' ] && git push --quiet https://$GITHUBKEY@github.com/Codearte/accurest-maven-plugin - $GIT_TAG > /dev/null 2>&1 +before_script: +- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw release-candidate:updateVersion -Drevision=$TRAVIS_BUILD_NUMBER; fi +script: +- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw deploy --settings .mvn/settings.xml -Prelease; else ./mvnw install; fi +after_success: - ./mvnw clean test jacoco:report coveralls:report branches: except: - - /^build-[0-9a-z\-]*/ + - /^v\d/ cache: directories: - "~/.m2/repository" diff --git a/pom.xml b/pom.xml index be73334c92..77dcc274f2 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ updateVersion - {{ api_version }}.${revision} + {{ api_version }}-${revision} @@ -192,6 +192,22 @@ + + org.apache.maven.plugins + maven-scm-plugin + 1.9.4 + + + deploy + + tag + + + + + v${project.version} + + From a18921132ed4054eeb08aa2899f03d1e97f45a8b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 08:48:27 +0200 Subject: [PATCH 409/719] fix tagging --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 77dcc274f2..31ffe43043 100644 --- a/pom.xml +++ b/pom.xml @@ -196,6 +196,7 @@ org.apache.maven.plugins maven-scm-plugin 1.9.4 + false deploy From 95a8c620d5f9adf2f8ae9be03b34d6a746607064 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 09:20:56 +0200 Subject: [PATCH 410/719] Release version: 1.0.2 [ci skip] From 5e54f56c0e954e8cc333f6f6773369a3f2d30654 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 09:20:56 +0200 Subject: [PATCH 411/719] Release version: 1.0.2 [ci skip] From 4df12a2cbabf820a26f9ccf608c3ba066b8defa8 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 09:20:56 +0200 Subject: [PATCH 412/719] Release version: 1.0.2 [ci skip] From 1a035b1b1998aa0d18b9479950a6fce40e80efad Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 10:01:23 +0200 Subject: [PATCH 413/719] release cleanup --- .travis.yml | 3 ++- pom.xml | 44 ++++++++++++++++++++++---------------------- 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4e5fee2854..76a5bf5b4b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,14 @@ before_script: script: - if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw deploy --settings .mvn/settings.xml -Prelease; else ./mvnw install; fi after_success: +- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw scm:tag --settings .mvn/settings.xml; fi - ./mvnw clean test jacoco:report coveralls:report branches: except: - /^v\d/ cache: directories: - - "~/.m2/repository" + - ~/.m2/repository env: global: - secure: oYAoU+PDuaWLo4MBoQYCF++kEqwWn8xtDAeBxBRIvduJO7758+haeSW43AFjmLfuJ9aUdfS+MrqGnDuj+Nqw1oSU9vdbyX7m+Q3wFDkO1Ln2NCaifrSCVHaAAMSfSKNlYBjD4+sATsrnSF75BSIS2WMNItkGcac7DPD+Ls64Ovw9MbkMB2i4TRYboGFNvOhtFYSOexd6hWltin0s6EHtsqFJKBKiPfvZYPJ34d0bfvMbi/TyfDoaia0QG8EUqyF1FZhBT5j/iXD03kTMdZ59o3pUgkgZjMfiD7rJGWffwZ+kV8PtzYyzjhiH8o+tqhFkLRXfu+s6zcMjBhJDR1rgguEqzlKbGRoFahY5PI+fbLwyNz+kQwtXxF3+lpwM/VZ/1OHPgpTtdDiz5ArRskb/Y/caGbLhjkm4V2x3/7fvRHGcLZf7DraJoShT/5MvG0AN7PCjEhbGX+08YaRucmQLWHUo1pGazwagP+7MqDsimdR+VzIY/HUctFi4DPOLjmZROukcPCFJTwn2T/0TFC5Luptb5ifsT9RvBv89/A71XcYs6rrGcU4UHdy6gZwWIRECKG82X+0jwoM39dFfweF7iVIuimdK2+yy4DtLZQfeqR7pWphs2i42twQUWcwIpRQyi/hn+wteVz7yxIBKfphaIVVP3juS1RPtMD0vOm8BRpo= diff --git a/pom.xml b/pom.xml index 31ffe43043..1fb2f13681 100644 --- a/pom.xml +++ b/pom.xml @@ -96,15 +96,21 @@ - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - oss - https://oss.sonatype.org/ - true - + org.apache.maven.plugins + maven-scm-plugin + 1.9.4 + false + + + default-cli + + tag + + + v${project.version} + + + @@ -193,20 +199,14 @@ - org.apache.maven.plugins - maven-scm-plugin - 1.9.4 - false - - - deploy - - tag - - - + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true - v${project.version} + oss + https://oss.sonatype.org/ + true From 775a30379793c7561b88d5f3cf61de624d3607f6 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 5 Apr 2016 11:07:53 +0200 Subject: [PATCH 414/719] Fixed path to m2repo --- .gitignore | 1 + .travis.yml | 3 --- .../accurest/stubrunner/junit/AccurestRuleJUnitTest.java | 8 ++++---- .../src/test/resources/application.yml | 2 +- .../stub-runner-spring/src/test/resources/application.yml | 2 +- 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index 5fd4a2d374..bd4b5b192b 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ target/ build/ hs_err_pid* +.DS_Store \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index b51e928166..427eae8489 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,6 @@ dist: trusty before_install: - "export JAVA_OPTS='-Xmx1024m -XX:MaxPermSize=256m'" - - "rm -rf $HOME/.m2/repository/io/codearte/accurest/stubs" - - "mkdir $HOME/.m2/repository/io/codearte/accurest/ --parents" - - "cp -r stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs $HOME/.m2/repository/io/codearte/accurest/" jdk: - oraclejdk7 diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java index b22f1f60fe..3660014705 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java @@ -1,12 +1,12 @@ package io.codearte.accurest.stubrunner.junit; -import java.io.InputStream; -import java.net.URI; - import org.apache.commons.io.IOUtils; import org.junit.ClassRule; import org.junit.Test; +import java.io.InputStream; +import java.net.URI; + import static org.assertj.core.api.BDDAssertions.then; /** @@ -37,7 +37,7 @@ public class AccurestRuleJUnitTest { private static String repoRoot() { try { - return AccurestRuleJUnitTest.class.getResource("/m2repo").toURI().toString(); + return AccurestRuleJUnitTest.class.getResource("/m2repo/repository/").toURI().toString(); } catch (Exception e) { return ""; } diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml b/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml index 686861b073..051a8a328e 100644 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml @@ -1,4 +1,4 @@ -stubrunner.stubs.repository.root: classpath:m2repo +stubrunner.stubs.repository.root: classpath:m2repo/repository/ stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer stubrunner.stubs.idsToServiceIds: diff --git a/stub-runner/stub-runner-spring/src/test/resources/application.yml b/stub-runner/stub-runner-spring/src/test/resources/application.yml index 0cb44fd948..25ca710cb7 100644 --- a/stub-runner/stub-runner-spring/src/test/resources/application.yml +++ b/stub-runner/stub-runner-spring/src/test/resources/application.yml @@ -1,2 +1,2 @@ -stubrunner.stubs.repository.root: classpath:m2repo +stubrunner.stubs.repository.root: classpath:m2repo/repository/ stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer \ No newline at end of file From 85797ce103a9e55d0b4be9a187040c9e73359597 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 11:14:21 +0200 Subject: [PATCH 415/719] simplified --- .travis.yml | 1 - .../test/projects/spring-boot-groovy/pom.xml | 42 ++++++----- .../test/projects/spring-boot-java/pom.xml | 43 ++++++----- pom.xml | 35 +++++---- test-deps/pom.xml | 75 ------------------- 5 files changed, 67 insertions(+), 129 deletions(-) delete mode 100644 test-deps/pom.xml diff --git a/.travis.yml b/.travis.yml index 76a5bf5b4b..a76fc178c4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,6 @@ before_script: script: - if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw deploy --settings .mvn/settings.xml -Prelease; else ./mvnw install; fi after_success: -- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw scm:tag --settings .mvn/settings.xml; fi - ./mvnw clean test jacoco:report coveralls:report branches: except: diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml b/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml index 217022bd53..12ba2e0d33 100644 --- a/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml +++ b/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml @@ -40,31 +40,39 @@ groovy-all + - io.codearte.accurest - accurest-test-deps - ${accurest.version} - pom + org.spockframework + spock-core + 1.0-groovy-2.4 + + + com.jayway.restassured + rest-assured + 2.9.0 com.jayway.restassured spring-mock-mvc - test + 2.9.0 + + + com.github.tomakehurst + wiremock + 2.0.10-beta + + + com.toomuchcoding.jsonassert + jsonassert + 0.3.0 + + + org.assertj + assertj-core + 2.3.0 - - - - io.codearte.accurest - accurest-test-deps - ${accurest.version} - pom - import - - - - diff --git a/maven-plugin/src/test/projects/spring-boot-java/pom.xml b/maven-plugin/src/test/projects/spring-boot-java/pom.xml index 1bdf2d1333..7ca7455ae5 100644 --- a/maven-plugin/src/test/projects/spring-boot-java/pom.xml +++ b/maven-plugin/src/test/projects/spring-boot-java/pom.xml @@ -25,32 +25,39 @@ 1.1.3 + - io.codearte.accurest - accurest-test-deps - ${it-plugin.version} - pom - test + org.spockframework + spock-core + 1.0-groovy-2.4 + + + com.jayway.restassured + rest-assured + 2.9.0 com.jayway.restassured spring-mock-mvc - test + 2.9.0 + + + com.github.tomakehurst + wiremock + 2.0.10-beta + + + com.toomuchcoding.jsonassert + jsonassert + 0.3.0 + + + org.assertj + assertj-core + 2.3.0 - - - - io.codearte.accurest - accurest-test-deps - ${it-plugin.version} - pom - import - - - - 1.8 diff --git a/pom.xml b/pom.xml index 1fb2f13681..263a5f0cac 100644 --- a/pom.xml +++ b/pom.xml @@ -12,7 +12,6 @@ https://github.com/Codearte/accurest-maven-plugin - test-deps maven-plugin @@ -95,23 +94,6 @@ - - org.apache.maven.plugins - maven-scm-plugin - 1.9.4 - false - - - default-cli - - tag - - - v${project.version} - - - - @@ -209,6 +191,23 @@ true + + org.apache.maven.plugins + maven-scm-plugin + 1.9.4 + false + + + deploy + + tag + + + v${project.version} + + + + diff --git a/test-deps/pom.xml b/test-deps/pom.xml deleted file mode 100644 index bdf83e2a5b..0000000000 --- a/test-deps/pom.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - 4.0.0 - - - accurest-maven-project - io.codearte.accurest - 0.3-SNAPSHOT - - - accurest-test-deps - pom - - - - org.spockframework - spock-core - - - com.jayway.restassured - rest-assured - - - com.jayway.restassured - spring-mock-mvc - - - com.github.tomakehurst - wiremock - - - com.toomuchcoding.jsonassert - jsonassert - - - org.assertj - assertj-core - - - - - - org.spockframework - spock-core - 1.0-groovy-2.4 - - - com.jayway.restassured - rest-assured - 2.9.0 - - - com.jayway.restassured - spring-mock-mvc - 2.9.0 - true - - - com.github.tomakehurst - wiremock - 2.0.10-beta - - - com.toomuchcoding.jsonassert - jsonassert - 0.3.0 - - - org.assertj - assertj-core - 2.3.0 - - - - \ No newline at end of file From ab5686b69c9e63f191282c62e764b6588b9f0ee6 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 11:35:53 +0200 Subject: [PATCH 416/719] unused dep --- maven-plugin/pom.xml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml index 6d70ca7c4e..ce1606ed6e 100644 --- a/maven-plugin/pom.xml +++ b/maven-plugin/pom.xml @@ -83,13 +83,6 @@ test - - io.codearte.accurest - accurest-test-deps - ${project.version} - pom - test - From dad6c559983d398ea97ca5bc1ec37842c78f3539 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 5 Apr 2016 11:51:09 +0200 Subject: [PATCH 417/719] I hate Travis --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 427eae8489..b51e928166 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,9 @@ dist: trusty before_install: - "export JAVA_OPTS='-Xmx1024m -XX:MaxPermSize=256m'" + - "rm -rf $HOME/.m2/repository/io/codearte/accurest/stubs" + - "mkdir $HOME/.m2/repository/io/codearte/accurest/ --parents" + - "cp -r stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs $HOME/.m2/repository/io/codearte/accurest/" jdk: - oraclejdk7 From 8eb0b5956aec8818dc2a1d0c8cd3b6a1f28f80d1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 5 Apr 2016 14:08:34 +0200 Subject: [PATCH 418/719] Fixed(?) stub runner tests (?) --- .../stubrunner/junit/AccurestRuleJUnitTest.java | 9 +++++++++ .../stubrunner/junit/AccurestRuleSpec.groovy | 10 +++++++--- .../junit/AccurestRuleSysPropsSpec.groovy | 13 ++++++++++--- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java index 3660014705..8b6b237925 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java @@ -1,6 +1,8 @@ package io.codearte.accurest.stubrunner.junit; import org.apache.commons.io.IOUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; @@ -14,6 +16,13 @@ import static org.assertj.core.api.BDDAssertions.then; */ public class AccurestRuleJUnitTest { + @BeforeClass + @AfterClass + public static void setupProps() { + System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); + System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); + } + @ClassRule public static AccurestRule rule = new AccurestRule() .repoRoot(repoRoot()) .downloadStub("io.codearte.accurest.stubs", "loanIssuance") diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy index a5dbf056e1..91f693c113 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy @@ -1,5 +1,7 @@ package io.codearte.accurest.stubrunner.junit +import org.junit.AfterClass +import org.junit.BeforeClass import org.junit.ClassRule import spock.lang.Shared import spock.lang.Specification @@ -9,9 +11,11 @@ import spock.lang.Specification */ class AccurestRuleSpec extends Specification { - static { - System.properties.setProperty("stubrunner.stubs.repository.root", "") - System.properties.setProperty("stubrunner.stubs.classifier", 'stubs') + @BeforeClass + @AfterClass + void setupProps() { + System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); + System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); } @ClassRule @Shared AccurestRule rule = new AccurestRule() diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy index 2dc4fe0939..00e4065198 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy @@ -1,21 +1,28 @@ package io.codearte.accurest.stubrunner.junit +import org.junit.AfterClass +import org.junit.BeforeClass import org.junit.ClassRule import spock.lang.Shared import spock.lang.Specification -import spock.util.environment.RestoreSystemProperties /** * @author Marcin Grzejszczak */ -@RestoreSystemProperties class AccurestRuleSysPropsSpec extends Specification { - static { + @BeforeClass + void setProps() { System.properties.setProperty("stubrunner.stubs.repository.root", AccurestRuleSysPropsSpec.getResource("/m2repo").toURI().toString()) System.properties.setProperty("stubrunner.stubs.classifier", 'classifier that will be overridden') } + @AfterClass + void cleanupProps() { + System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); + System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); + } + @ClassRule @Shared AccurestRule rule = new AccurestRule() .downloadStub("io.codearte.accurest.stubs", "loanIssuance", "stubs") .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:stubs") From bd0a531bbcafcd259fe50c6cf1d556a663e3fea5 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 14:23:25 +0200 Subject: [PATCH 419/719] Raised gradle wrapper version. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index aa84447761..e5243d8c6b 100644 --- a/build.gradle +++ b/build.gradle @@ -151,5 +151,5 @@ project(':accurest-gradle-plugin') { } task wrapper(type: Wrapper) { - gradleVersion = '2.4' + gradleVersion = '2.12' } From ad88b2b0207e80db603de455e2d0765e27395dfb Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 14:24:15 +0200 Subject: [PATCH 420/719] Release version: 1.0.3 [ci skip] From 306d5fb779084af145d12983e82784b7fb99e98b Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 14:24:15 +0200 Subject: [PATCH 421/719] Release version: 1.0.3 [ci skip] From 37c9b067787a2792053cee767e538aa31e4a3f0b Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 14:24:15 +0200 Subject: [PATCH 422/719] Release version: 1.0.3 [ci skip] From a63a35aac26c9990bef285078cc8d5c8eaee0f75 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 14:44:31 +0200 Subject: [PATCH 423/719] Reverted gradle and wrapper version changes. --- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 51018 -> 53638 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 10 +++------- gradlew.bat | 2 +- 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/build.gradle b/build.gradle index e5243d8c6b..aa84447761 100644 --- a/build.gradle +++ b/build.gradle @@ -151,5 +151,5 @@ project(':accurest-gradle-plugin') { } task wrapper(type: Wrapper) { - gradleVersion = '2.12' + gradleVersion = '2.4' } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index c97a8bdb9088d370da7e88784a7a093b971aa23a..5ccda13e9cb94678ba179b32452cf3d60dc36353 100644 GIT binary patch delta 25651 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 +cd "`dirname \"$PRG\"`/" >/dev/null APP_HOME="`pwd -P`" -cd "$SAVED" >&- +cd "$SAVED" >/dev/null CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar @@ -114,6 +109,7 @@ fi 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` diff --git a/gradlew.bat b/gradlew.bat index 8a0b282aa6..5f192121eb 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -46,7 +46,7 @@ echo location of your Java installation. goto fail :init -@rem Get command-line arguments, handling Windowz variants +@rem Get command-line arguments, handling Windows variants if not "%OS%" == "Windows_NT" goto win9xME_args if "%@eval[2+2]" == "4" goto 4NT_args From 2c1342e9c930d418e7bfe18e3504232da7352b64 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 14:45:03 +0200 Subject: [PATCH 424/719] Release version: 1.0.4 [ci skip] From 24dfc4ecac93e6ea646568898b7e7e619081c737 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 14:45:03 +0200 Subject: [PATCH 425/719] Release version: 1.0.4 [ci skip] From 134fd4648fa05c13e576bd34cae8499519f5c71c Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Tue, 5 Apr 2016 14:45:03 +0200 Subject: [PATCH 426/719] Release version: 1.0.4 [ci skip] From 628fdd270ea44d997fe5f59caccb54954c76c946 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 15:08:44 +0200 Subject: [PATCH 427/719] goal order --- pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pom.xml b/pom.xml index 263a5f0cac..3bf3818d41 100644 --- a/pom.xml +++ b/pom.xml @@ -185,6 +185,15 @@ nexus-staging-maven-plugin 1.6.7 true + + + default-deploy + deploy + + deploy + + + oss https://oss.sonatype.org/ @@ -198,6 +207,7 @@ false + tag-release deploy tag From 344389d4771f08737685e28d8d67593dcd2befc5 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 15:17:21 +0200 Subject: [PATCH 428/719] disable install [ci skip] --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a76fc178c4..c8279dabc3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,7 @@ script: - if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw deploy --settings .mvn/settings.xml -Prelease; else ./mvnw install; fi after_success: - ./mvnw clean test jacoco:report coveralls:report +install: true branches: except: - /^v\d/ From 3e4413e05217afb991c3069542993969e738f7db Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 15:41:48 +0200 Subject: [PATCH 429/719] skipLocalStaging --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3bf3818d41..7224431c36 100644 --- a/pom.xml +++ b/pom.xml @@ -187,7 +187,7 @@ true - default-deploy + deploy-to-oss deploy deploy @@ -198,6 +198,7 @@ oss https://oss.sonatype.org/ true + true From 0dbfc437521d1d7e30785460b8caae0e41f0142b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 16:24:29 +0200 Subject: [PATCH 430/719] tag after deploy [ci skip] --- pom.xml | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/pom.xml b/pom.xml index 7224431c36..5376fdfb3b 100644 --- a/pom.xml +++ b/pom.xml @@ -94,6 +94,18 @@ + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + oss + https://oss.sonatype.org/ + true + true + + @@ -180,27 +192,6 @@ - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - - deploy-to-oss - deploy - - deploy - - - - - oss - https://oss.sonatype.org/ - true - true - - org.apache.maven.plugins maven-scm-plugin From 6a07f2ddc466369868cd4113437a0a088b72e138 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 5 Apr 2016 18:36:54 +0200 Subject: [PATCH 431/719] Feature/one module project * project refactor * switch to beta classifier for auto builds --- maven-plugin/pom.xml | 178 ---------------- pom.xml | 192 +++++++++++++++--- .../codearte/accurest/maven/ConvertMojo.java | 0 .../accurest/maven/GenerateStubsMojo.java | 0 .../accurest/maven/GenerateTestsMojo.java | 0 .../io/codearte/accurest/maven/PluginIT.java | 0 .../accurest/maven/PluginUnitTest.java | 0 .../src => src}/test/projects/basic/pom.xml | 0 .../basic/src/test/accurest/Sample.groovy | 0 .../test/projects/pomless/Sample.groovy | 0 .../test/projects/spring-boot-groovy/pom.xml | 0 .../ofg/twitter/place/PairIdController.groovy | 0 .../groovy/com/ofg/twitter/place/Tweet.java | 0 .../sample/SampleSimpleBootApplication.java | 0 .../src/main/resources/application.properties | 0 .../ofg/twitter/place/AcceptanceTest.groovy | 0 .../ofg/twitter/place/BaseMockMvcTest.groovy | 0 .../SampleSimpleBootApplicationTests.java | 0 .../src/test/resources/logback-test.groovy | 0 .../stubs/collerate_PlacesFrom_Tweet.groovy | 0 .../resources/stubs/moreComplexVersion.groovy | 0 .../test/projects/spring-boot-java/pom.xml | 0 .../src/main/java/hello/Application.java | 0 .../src/main/java/hello/Greeting.java | 0 .../main/java/hello/GreetingController.java | 0 .../src/test/accurest/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../src/test/java/hello/BaseMockMvcTest.java | 0 .../test/projects/withStubs/pom.xml | 0 .../src/test/resources/stubs/Sample.groovy | 0 30 files changed, 167 insertions(+), 203 deletions(-) delete mode 100644 maven-plugin/pom.xml rename {maven-plugin/src => src}/main/java/io/codearte/accurest/maven/ConvertMojo.java (100%) rename {maven-plugin/src => src}/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java (100%) rename {maven-plugin/src => src}/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java (100%) rename {maven-plugin/src => src}/test/java/io/codearte/accurest/maven/PluginIT.java (100%) rename {maven-plugin/src => src}/test/java/io/codearte/accurest/maven/PluginUnitTest.java (100%) rename {maven-plugin/src => src}/test/projects/basic/pom.xml (100%) rename {maven-plugin/src => src}/test/projects/basic/src/test/accurest/Sample.groovy (100%) rename {maven-plugin/src => src}/test/projects/pomless/Sample.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/pom.xml (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/main/resources/application.properties (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-java/pom.xml (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-java/src/main/java/hello/Application.java (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-java/src/main/java/hello/Greeting.java (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy (100%) rename {maven-plugin/src => src}/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java (100%) rename {maven-plugin/src => src}/test/projects/withStubs/pom.xml (100%) rename {maven-plugin/src => src}/test/projects/withStubs/src/test/resources/stubs/Sample.groovy (100%) diff --git a/maven-plugin/pom.xml b/maven-plugin/pom.xml deleted file mode 100644 index ce1606ed6e..0000000000 --- a/maven-plugin/pom.xml +++ /dev/null @@ -1,178 +0,0 @@ - - - 4.0.0 - - - io.codearte.accurest - accurest-maven-project - 0.3-SNAPSHOT - - - accurest-maven-plugin - maven-plugin - - - - io.codearte.accurest - accurest-core - - - io.codearte.accurest - accurest-converters - - - org.codehaus.groovy - groovy-all - 2.4.6 - - - - ch.qos.logback - logback-core - 1.1.3 - - - org.slf4j - slf4j-simple - 1.7.12 - test - - - org.apache.maven - maven-core - ${mavenVersion} - test - - - org.apache.maven - maven-compat - ${mavenVersion} - test - - - - org.apache.maven - maven-plugin-api - ${mavenVersion} - provided - - - org.apache.maven.plugin-tools - maven-plugin-annotations - ${mavenPluginPluginVersion} - provided - - - - io.takari.maven.plugins - takari-plugin-testing - 2.8.0 - test - - - io.takari.maven.plugins - takari-plugin-integration-testing - 2.8.0 - pom - test - - - junit - junit - 4.12 - test - - - - - - - org.codehaus.plexus - plexus-component-metadata - - - - generate-metadata - generate-test-metadata - - - - - - maven-plugin-plugin - ${mavenPluginPluginVersion} - - true - - - - generated-helpmojo - - helpmojo - - - - generate-descriptor - - descriptor - - - - - - io.takari.maven.plugins - takari-lifecycle-plugin - 1.11.12 - true - - - testProperties - process-test-resources - - testProperties - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.19.1 - - - - integration-test - verify - - - - - - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - prepare-agent - - prepare-agent - - - - report - - report - - - - - - org.eluder.coveralls - coveralls-maven-plugin - 4.1.0 - - - - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5376fdfb3b..9a0da34fdf 100644 --- a/pom.xml +++ b/pom.xml @@ -4,19 +4,14 @@ 4.0.0 io.codearte.accurest - accurest-maven-project + accurest-maven-plugin + maven-plugin 0.3-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin https://github.com/Codearte/accurest-maven-plugin - - maven-plugin - - - pom - [3.2.1,) @@ -70,6 +65,86 @@ + + org.codehaus.plexus + plexus-component-metadata + 1.6 + + + + generate-metadata + generate-test-metadata + + + + + + maven-plugin-plugin + ${mavenPluginPluginVersion} + + true + + + + generated-helpmojo + + helpmojo + + + + generate-descriptor + + descriptor + + + + + + io.takari.maven.plugins + takari-lifecycle-plugin + 1.11.12 + true + + + testProperties + process-test-resources + + testProperties + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.19.1 + + + + integration-test + verify + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + prepare-agent + + prepare-agent + + + + + + org.eluder.coveralls + coveralls-maven-plugin + 4.1.0 + com.smartcodeltd release-candidate-maven-plugin @@ -81,7 +156,7 @@ updateVersion - {{ api_version }}-${revision} + {{ api_version }}-beta-${revision} @@ -102,8 +177,16 @@ oss https://oss.sonatype.org/ - true - true + false + + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + false + true @@ -126,20 +209,80 @@ - - - - io.codearte.accurest - accurest-core - ${accurest.version} - - - io.codearte.accurest - accurest-converters - ${accurest.version} - - - + + + io.codearte.accurest + accurest-core + ${accurest.version} + + + io.codearte.accurest + accurest-converters + ${accurest.version} + + + org.codehaus.groovy + groovy-all + 2.4.6 + + + + ch.qos.logback + logback-core + 1.1.3 + + + org.slf4j + slf4j-simple + 1.7.12 + test + + + org.apache.maven + maven-core + ${mavenVersion} + test + + + org.apache.maven + maven-compat + ${mavenVersion} + test + + + + org.apache.maven + maven-plugin-api + ${mavenVersion} + provided + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${mavenPluginPluginVersion} + provided + + + + io.takari.maven.plugins + takari-plugin-testing + 2.8.0 + test + + + io.takari.maven.plugins + takari-plugin-integration-testing + 2.8.0 + pom + test + + + junit + junit + 4.12 + test + + @@ -199,7 +342,6 @@ false - tag-release deploy tag diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/ConvertMojo.java b/src/main/java/io/codearte/accurest/maven/ConvertMojo.java similarity index 100% rename from maven-plugin/src/main/java/io/codearte/accurest/maven/ConvertMojo.java rename to src/main/java/io/codearte/accurest/maven/ConvertMojo.java diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java similarity index 100% rename from maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java rename to src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java diff --git a/maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java similarity index 100% rename from maven-plugin/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java rename to src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/io/codearte/accurest/maven/PluginIT.java similarity index 100% rename from maven-plugin/src/test/java/io/codearte/accurest/maven/PluginIT.java rename to src/test/java/io/codearte/accurest/maven/PluginIT.java diff --git a/maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java similarity index 100% rename from maven-plugin/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java rename to src/test/java/io/codearte/accurest/maven/PluginUnitTest.java diff --git a/maven-plugin/src/test/projects/basic/pom.xml b/src/test/projects/basic/pom.xml similarity index 100% rename from maven-plugin/src/test/projects/basic/pom.xml rename to src/test/projects/basic/pom.xml diff --git a/maven-plugin/src/test/projects/basic/src/test/accurest/Sample.groovy b/src/test/projects/basic/src/test/accurest/Sample.groovy similarity index 100% rename from maven-plugin/src/test/projects/basic/src/test/accurest/Sample.groovy rename to src/test/projects/basic/src/test/accurest/Sample.groovy diff --git a/maven-plugin/src/test/projects/pomless/Sample.groovy b/src/test/projects/pomless/Sample.groovy similarity index 100% rename from maven-plugin/src/test/projects/pomless/Sample.groovy rename to src/test/projects/pomless/Sample.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/pom.xml rename to src/test/projects/spring-boot-groovy/pom.xml diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy rename to src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java b/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java rename to src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java b/src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java rename to src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/main/resources/application.properties b/src/test/projects/spring-boot-groovy/src/main/resources/application.properties similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/main/resources/application.properties rename to src/test/projects/spring-boot-groovy/src/main/resources/application.properties diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy b/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy rename to src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy b/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy rename to src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java b/src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java rename to src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy rename to src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy rename to src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy rename to src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-java/pom.xml rename to src/test/projects/spring-boot-java/pom.xml diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java b/src/test/projects/spring-boot-java/src/main/java/hello/Application.java similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java rename to src/test/projects/spring-boot-java/src/main/java/hello/Application.java diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java b/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java rename to src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java b/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java rename to src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy b/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy rename to src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy b/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy rename to src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy diff --git a/maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java b/src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java similarity index 100% rename from maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java rename to src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java diff --git a/maven-plugin/src/test/projects/withStubs/pom.xml b/src/test/projects/withStubs/pom.xml similarity index 100% rename from maven-plugin/src/test/projects/withStubs/pom.xml rename to src/test/projects/withStubs/pom.xml diff --git a/maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy b/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy similarity index 100% rename from maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy rename to src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy From c596d304872564830933cf29aba8a87b6c6f70dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 5 Apr 2016 18:45:08 +0200 Subject: [PATCH 432/719] Accurest update to 1.0.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9a0da34fdf..acd5312f7f 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 3.4 UTF-8 - 1.0.1 + 1.0.4 0000000 @@ -356,4 +356,4 @@ -
\ No newline at end of file +
From d7a7726de00852e6ca42d55b612fee004c83275e Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 19:31:31 +0200 Subject: [PATCH 433/719] adjust tagNameFormat [ci skip] --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index acd5312f7f..6c256e9a4f 100644 --- a/pom.xml +++ b/pom.xml @@ -187,6 +187,7 @@ false true + v@{project.version} From 59e8d6c096b46125fb709d7e830e8f2e367d3593 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 19:32:58 +0200 Subject: [PATCH 434/719] [maven-release-plugin] prepare release v0.4 --- pom.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 6c256e9a4f..2f5e846434 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,11 @@ - + 4.0.0 io.codearte.accurest accurest-maven-plugin maven-plugin - 0.3-SNAPSHOT + 0.4 Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -47,7 +46,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - HEAD + v0.4 From ea2caf62d9861ac79761f19be05457d0eba88425 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 19:32:58 +0200 Subject: [PATCH 435/719] [maven-release-plugin] prepare for next development iteration [skip ci] --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2f5e846434..737bf70031 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.4 + 0.5-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -46,7 +46,7 @@ scm:git:https://github.com/Codearte/accurest-maven-plugin.git scm:git:git@github.com:Codearte/accurest-maven-plugin.git https://github.com/Codearte/accurest-maven-plugin - v0.4 + HEAD From 13b33f741a34280a5d62601cf16d6aa5a310278d Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 5 Apr 2016 20:13:21 +0200 Subject: [PATCH 436/719] exclude HelpMojo [ci skip] --- pom.xml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 737bf70031..8505212d9f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,6 @@ - + 4.0.0 io.codearte.accurest @@ -130,6 +131,11 @@ org.jacoco jacoco-maven-plugin 0.7.6.201602180812 + + + **/HelpMojo.class + + prepare-agent From 917a74c14b0baf101fcce65f5ba33387f9f96d79 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 6 Apr 2016 17:40:15 +0200 Subject: [PATCH 437/719] accurest:run --- .mvn/settings.xml | 7 +- .travis.yml | 10 +- README.md | 24 ++- pom.xml | 159 +++++++++++++----- .../accurest/maven/AccurestConverter.java | 14 ++ .../codearte/accurest/maven/ConvertMojo.java | 3 +- .../io/codearte/accurest/maven/RunMojo.java | 68 ++++++++ 7 files changed, 226 insertions(+), 59 deletions(-) create mode 100644 src/main/java/io/codearte/accurest/maven/AccurestConverter.java create mode 100644 src/main/java/io/codearte/accurest/maven/RunMojo.java diff --git a/.mvn/settings.xml b/.mvn/settings.xml index f94b247a34..5c84da1f0c 100644 --- a/.mvn/settings.xml +++ b/.mvn/settings.xml @@ -12,12 +12,13 @@ + + release + + oss - - true - ${env.GPG_KEY_NAME} ${env.GPG_PASSPHRASE} diff --git a/.travis.yml b/.travis.yml index c8279dabc3..f6465c8c88 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,15 @@ language: java jdk: - oraclejdk8 before_install: -- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d; fi -- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then gpg --fast-import .mvn/codesigning.asc; fi +- openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d +- gpg --fast-import .mvn/codesigning.asc - git config --global user.email "builds@travis-ci.com" - git config --global user.name "Travis CI" +- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then git checkout master; fi before_script: -- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw release-candidate:updateVersion -Drevision=$TRAVIS_BUILD_NUMBER; fi +- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw initialize -Pversion; fi script: -- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw deploy --settings .mvn/settings.xml -Prelease; else ./mvnw install; fi +- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw deploy --settings .mvn/settings.xml; else ./mvnw install; fi after_success: - ./mvnw clean test jacoco:report coveralls:report install: true @@ -19,6 +20,7 @@ branches: cache: directories: - ~/.m2/repository + - ~/.m2/wrapper env: global: - secure: oYAoU+PDuaWLo4MBoQYCF++kEqwWn8xtDAeBxBRIvduJO7758+haeSW43AFjmLfuJ9aUdfS+MrqGnDuj+Nqw1oSU9vdbyX7m+Q3wFDkO1Ln2NCaifrSCVHaAAMSfSKNlYBjD4+sATsrnSF75BSIS2WMNItkGcac7DPD+Ls64Ovw9MbkMB2i4TRYboGFNvOhtFYSOexd6hWltin0s6EHtsqFJKBKiPfvZYPJ34d0bfvMbi/TyfDoaia0QG8EUqyF1FZhBT5j/iXD03kTMdZ59o3pUgkgZjMfiD7rJGWffwZ+kV8PtzYyzjhiH8o+tqhFkLRXfu+s6zcMjBhJDR1rgguEqzlKbGRoFahY5PI+fbLwyNz+kQwtXxF3+lpwM/VZ/1OHPgpTtdDiz5ArRskb/Y/caGbLhjkm4V2x3/7fvRHGcLZf7DraJoShT/5MvG0AN7PCjEhbGX+08YaRucmQLWHUo1pGazwagP+7MqDsimdR+VzIY/HUctFi4DPOLjmZROukcPCFJTwn2T/0TFC5Luptb5ifsT9RvBv89/A71XcYs6rrGcU4UHdy6gZwWIRECKG82X+0jwoM39dFfweF7iVIuimdK2+yy4DtLZQfeqR7pWphs2i42twQUWcwIpRQyi/hn+wteVz7yxIBKfphaIVVP3juS1RPtMD0vOm8BRpo= diff --git a/README.md b/README.md index 542d7616b3..8bf002775b 100644 --- a/README.md +++ b/README.md @@ -3,16 +3,31 @@ Accurate REST Maven Plugin ==== - Converting [Accurest](https://github.com/Codearte/accurest/wiki/1.-Introduction) GroovyDSL into WireMock stub mappings: mvn io.codearte.accurest:accurest-maven-plugin:convert -or shortly +or shortly (*) mvn accurest:convert -but this requires additional configuration inside `~/.m2/settings.xml` + +Accurest Runner +--- + + mvn io.codearte.accurest:accurest-maven-plugin:run + +or shortly (*) + + mvn accurest:run + + +For more information please go to the [Wiki](https://github.com/Codearte/accurest/wiki/2.2-Maven-Project) + + +--- + +(*) Additional configuration inside `~/.m2/settings.xml` ```xml @@ -22,6 +37,3 @@ but this requires additional configuration inside `~/.m2/settings.xml` ``` - - -For more information please go to the [Wiki](https://github.com/Codearte/accurest/wiki/2.2-Maven-Project) diff --git a/pom.xml b/pom.xml index 8505212d9f..6bf7f49877 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5-SNAPSHOT + 0.5.0-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin @@ -30,8 +30,6 @@ UTF-8 1.0.4 - - 0000000 @@ -150,41 +148,6 @@ coveralls-maven-plugin 4.1.0 - - com.smartcodeltd - release-candidate-maven-plugin - 1.0-201603091838.01dbbbf - - - default-cli - - updateVersion - - - {{ api_version }}-beta-${revision} - - - - - version - - - PROJECT_VERSION={{ version }} - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - oss - https://oss.sonatype.org/ - false - - org.apache.maven.plugins maven-release-plugin @@ -293,12 +256,6 @@ release - - - performRelease - true - - @@ -358,6 +315,120 @@ + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + oss + https://oss.sonatype.org/ + true + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + parse-version + deploy + + parse-version + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.2 + + + switch-to-snapshot-version + deploy + + set + + + + ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT + + + + + + org.apache.maven.plugins + maven-scm-plugin + 1.9.4 + false + + + tag-new-release + deploy + + tag + + + v${project.version} + + + + save-changes + deploy + + checkin + + + connection + pom.xml + Setting next development version to ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT. + + [ci skip] + + + + + + + + + + version + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + parse-version + initialize + + parse-version + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.2 + + + set-release-version + initialize + + set + + + ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion} + + + + diff --git a/src/main/java/io/codearte/accurest/maven/AccurestConverter.java b/src/main/java/io/codearte/accurest/maven/AccurestConverter.java new file mode 100644 index 0000000000..e04b814bce --- /dev/null +++ b/src/main/java/io/codearte/accurest/maven/AccurestConverter.java @@ -0,0 +1,14 @@ +package io.codearte.accurest.maven; + +import io.codearte.accurest.config.AccurestConfigProperties; +import io.codearte.accurest.wiremock.DslToWireMockClientConverter; +import io.codearte.accurest.wiremock.RecursiveFilesConverter; + +public class AccurestConverter { + + public void convert(AccurestConfigProperties config){ + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); + converter.processFiles(); + } + +} diff --git a/src/main/java/io/codearte/accurest/maven/ConvertMojo.java b/src/main/java/io/codearte/accurest/maven/ConvertMojo.java index a15b5a642b..16ee3642db 100644 --- a/src/main/java/io/codearte/accurest/maven/ConvertMojo.java +++ b/src/main/java/io/codearte/accurest/maven/ConvertMojo.java @@ -33,8 +33,7 @@ public class ConvertMojo extends AbstractMojo { getLog().info(format(" Accurest contracts directory: %s", config.getContractsDslDir().getAbsolutePath())); getLog().info(format("WireMock stubs mappings directory: %s", config.getStubsOutputDir().getAbsolutePath())); - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); - converter.processFiles(); + new AccurestConverter().convert(config); } } diff --git a/src/main/java/io/codearte/accurest/maven/RunMojo.java b/src/main/java/io/codearte/accurest/maven/RunMojo.java new file mode 100644 index 0000000000..5744ab4170 --- /dev/null +++ b/src/main/java/io/codearte/accurest/maven/RunMojo.java @@ -0,0 +1,68 @@ +package io.codearte.accurest.maven; + +import static java.lang.String.format; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.common.SingleRootFileSource; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.standalone.JsonFileMappingsLoader; +import io.codearte.accurest.config.AccurestConfigProperties; + +@Mojo(name = "run", requiresProject = false) +public class RunMojo extends AbstractMojo { + + @Parameter(property = "contractsDir", defaultValue = "${basedir}") + private File contractsDir; + + @Parameter(property = "port", defaultValue = "8089") + private int port; + + public void execute() throws MojoExecutionException, MojoFailureException { + + try { + Path mappingsPath = Files.createTempDirectory("mappings"); + AccurestConfigProperties config = new AccurestConfigProperties(); + config.setContractsDslDir(contractsDir); + config.setStubsOutputDir(mappingsPath.toFile()); + new AccurestConverter().convert(config); + getLog().info( + format(" Accurest contracts directory: %s", config.getContractsDslDir().getAbsolutePath())); + getLog().info( + format("WireMock stubs mappings directory: %s", config.getStubsOutputDir().getAbsolutePath())); + + WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(port)); + wireMockServer.loadMappingsUsing( + new JsonFileMappingsLoader(new SingleRootFileSource(mappingsPath.toFile()))); + wireMockServer.start(); + + pressAnyKeyToContinue(); + getLog().info("Shutting down ..."); + + wireMockServer.stop(); + + } catch (IOException e) { + e.printStackTrace(); + } + + } + + private void pressAnyKeyToContinue() { + getLog().info("Press any key to continue..."); + try { + System.in.read(); + } catch (Exception ignored) { + } + } + +} From 7c1d87345d72c16f486b05a6f95cf9f1390912ec Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 6 Apr 2016 17:51:32 +0200 Subject: [PATCH 438/719] duplicated scm plugin --- pom.xml | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/pom.xml b/pom.xml index 6bf7f49877..8f32815d3a 100644 --- a/pom.xml +++ b/pom.xml @@ -298,23 +298,6 @@ - - org.apache.maven.plugins - maven-scm-plugin - 1.9.4 - false - - - deploy - - tag - - - v${project.version} - - - - org.sonatype.plugins nexus-staging-maven-plugin From 27e0645e110273db5855e7a282efb6563c5c8faa Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 6 Apr 2016 17:58:06 +0200 Subject: [PATCH 439/719] wrong profile name --- .mvn/settings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.mvn/settings.xml b/.mvn/settings.xml index 5c84da1f0c..564d2466ed 100644 --- a/.mvn/settings.xml +++ b/.mvn/settings.xml @@ -18,7 +18,7 @@ - oss + release ${env.GPG_KEY_NAME} ${env.GPG_PASSPHRASE} From e93019bcead9440470439f368a9705806be58bb4 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Wed, 6 Apr 2016 16:04:16 +0000 Subject: [PATCH 440/719] Setting next development version to 0.5.1-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8f32815d3a..c6e124f418 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.0-SNAPSHOT + 0.5.1-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin From 33e3806b0e0f4bed0f4b94fc8763e4395c0a83ca Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 6 Apr 2016 21:11:45 +0200 Subject: [PATCH 441/719] formatting [ci skip] --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8bf002775b..d862d2b660 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Converting [Accurest](https://github.com/Codearte/accurest/wiki/1.-Introduction) mvn io.codearte.accurest:accurest-maven-plugin:convert -or shortly (*) +or shortly * mvn accurest:convert @@ -17,7 +17,7 @@ Accurest Runner mvn io.codearte.accurest:accurest-maven-plugin:run -or shortly (*) +or shortly * mvn accurest:run @@ -27,7 +27,7 @@ For more information please go to the [Wiki](https://github.com/Codearte/accures --- -(*) Additional configuration inside `~/.m2/settings.xml` +* Additional configuration inside `~/.m2/settings.xml` ```xml @@ -37,3 +37,4 @@ For more information please go to the [Wiki](https://github.com/Codearte/accures ``` + From cdd9ff5921538b74126ab096556b974ffc0db102 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 6 Apr 2016 21:12:38 +0200 Subject: [PATCH 442/719] missing text [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d862d2b660..9a86188604 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ For more information please go to the [Wiki](https://github.com/Codearte/accures --- -* Additional configuration inside `~/.m2/settings.xml` +* Additional configuration inside `~/.m2/settings.xml` is required. ```xml From 30ecba65c7d9134d7682749cd34e3ae340cfe3bb Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 6 Apr 2016 21:50:56 +0200 Subject: [PATCH 443/719] ignore gh-pages [ci skip] --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index f6465c8c88..d1c24045ab 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ install: true branches: except: - /^v\d/ + - gh-pages cache: directories: - ~/.m2/repository From a5dcc896dd6a75803530969f0ef8f00cf9e86690 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 6 Apr 2016 21:56:21 +0200 Subject: [PATCH 444/719] better readme [ci skip] --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 9a86188604..a118f28851 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) -Accurate REST Maven Plugin +[Accurate REST Maven Plugin](http://codearte.github.io/accurest-maven-plugin/plugin-info.html) ==== Converting [Accurest](https://github.com/Codearte/accurest/wiki/1.-Introduction) GroovyDSL into WireMock stub mappings: @@ -11,6 +11,10 @@ or shortly * mvn accurest:convert +For more information please go to the [Accurest Wiki](https://github.com/Codearte/accurest/wiki/2.2-Maven-Project) or [Plugin Documentation Site](http://codearte.github.io/accurest-maven-plugin/plugin-info.html). + + + Accurest Runner --- @@ -21,10 +25,6 @@ or shortly * mvn accurest:run - -For more information please go to the [Wiki](https://github.com/Codearte/accurest/wiki/2.2-Maven-Project) - - --- * Additional configuration inside `~/.m2/settings.xml` is required. From 796cd5e553c5b1eb98dd6b442da7dcbf521dcd4c Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 6 Apr 2016 21:58:02 +0200 Subject: [PATCH 445/719] removed title link [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a118f28851..06f7e4c857 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) -[Accurate REST Maven Plugin](http://codearte.github.io/accurest-maven-plugin/plugin-info.html) +Accurate REST Maven Plugin ==== Converting [Accurest](https://github.com/Codearte/accurest/wiki/1.-Introduction) GroovyDSL into WireMock stub mappings: From 2fc1f918d85e1e6a4b321a3e34b8cc3251265a84 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 7 Apr 2016 00:30:13 +0200 Subject: [PATCH 446/719] Added verification for empty root repo --- .../io/codearte/accurest/stubrunner/StubDownloader.groovy | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy index 94171feb7e..3d306ce9bc 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.stubrunner import groovy.grape.Grape import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.util.StringUtils import io.codearte.accurest.stubrunner.util.ZipCategory import static java.nio.file.Files.createTempDirectory @@ -63,7 +64,11 @@ class StubDownloader { try { System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") - return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) + if (StringUtils.hasText(stubRepositoryRoot)) { + return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) + } + log.warn("No repository passed so will try to resolve dependencies from local Maven Repo") + return buildResolver(true).resolveDependency(stubRepositoryRoot, depToGrab) } finally { restoreOldGrapeConfigIfApplicable(oldGrapeConfig) } From 7f20c77607285c5a2fe0ef5d68b9824b3c01c22b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Fri, 8 Apr 2016 19:10:39 +0200 Subject: [PATCH 447/719] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a6c27f899b..383f196d2a 100644 --- a/README.md +++ b/README.md @@ -37,4 +37,8 @@ Spring Configuration that automatically starts stubs upon Spring Context build u ### Stub Runner Spring Cloud Spring Cloud AutoConfiguration that automatically starts stubs upon Spring Context build up and allows you to call the stubs -as if they were registered in your service discovery \ No newline at end of file +as if they were registered in your service discovery + +### [Accurest Maven Plugin](https://github.com/Codearte/accurest-maven-plugin) + +Maven project support with standalone Accurest Stub Runner and Accurest Contracts to Wiremock mappings converter From 14b5a0c06fa64bdf3c95b1e415ebe12aebd3e69b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 9 Apr 2016 08:53:20 +0200 Subject: [PATCH 448/719] Fixed wrong classifier appending fixes #214 --- ...fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar | Bin 1733 -> 0 bytes ...fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1897 bytes .../fraudDetectionServer-0.0.1-SNAPSHOT.pom} | 3 ++- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 4 ++-- .../maven-metadata-local.xml | 5 +++-- .../loanIssuance-stubs-0.0.1-SNAPSHOT.jar | Bin 587 -> 0 bytes .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 639 bytes .../loanIssuance-0.0.1-SNAPSHOT.pom} | 3 ++- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 4 ++-- .../maven-metadata-local.xml | 5 +++-- ...fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar | Bin 1733 -> 0 bytes .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ------------ ...fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1897 bytes .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 9 +++++++++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++++++++++++ .../maven-metadata-local.xml | 12 ++++++++++++ .../loanIssuance-stubs-0.0.1-SNAPSHOT.jar | Bin 587 -> 0 bytes .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 639 bytes .../loanIssuance-0.0.1-SNAPSHOT.pom} | 3 ++- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 4 ++-- .../maven-metadata-local.xml | 5 +++-- ...fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar | Bin 1733 -> 0 bytes ...fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom | 8 -------- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ------------ .../maven-metadata-local.xml | 11 ----------- ...fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1897 bytes .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 9 +++++++++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++++++++++++ .../maven-metadata-local.xml | 12 ++++++++++++ .../loanIssuance-stubs-0.0.1-SNAPSHOT.jar | Bin 587 -> 0 bytes .../loanIssuance-stubs-0.0.1-SNAPSHOT.pom | 8 -------- .../loanIssuance-stubs/maven-metadata-local.xml | 11 ----------- .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 639 bytes .../loanIssuance-0.0.1-SNAPSHOT.pom} | 3 ++- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 4 ++-- .../stubs/loanIssuance}/maven-metadata-local.xml | 5 +++-- .../accurest/stubrunner/StubDownloader.groovy | 14 ++++++++------ .../accurest/stubrunner/StubRunnerFactory.groovy | 6 +----- .../stubrunner/StubRunnerFactorySpec.groovy | 2 +- 39 files changed, 104 insertions(+), 94 deletions(-) delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar rename stub-runner/{stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom => stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom} (83%) rename stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/{fraudDetectionServer-stubs => fraudDetectionServer}/0.0.1-SNAPSHOT/maven-metadata-local.xml (70%) rename stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/{fraudDetectionServer-stubs => fraudDetectionServer}/maven-metadata-local.xml (61%) delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/{loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom => loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom} (84%) rename stub-runner/{stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs => stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance}/0.0.1-SNAPSHOT/maven-metadata-local.xml (72%) rename stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/{loanIssuance-stubs => loanIssuance}/maven-metadata-local.xml (63%) delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar create mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename stub-runner/{stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom => stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom} (84%) rename stub-runner/{stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs => stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance}/0.0.1-SNAPSHOT/maven-metadata-local.xml (72%) rename stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/{loanIssuance-stubs => loanIssuance}/maven-metadata-local.xml (63%) delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename stub-runner/{stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom => stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom} (84%) rename stub-runner/{stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs => stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance}/0.0.1-SNAPSHOT/maven-metadata-local.xml (72%) rename stub-runner/{stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs => stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance}/maven-metadata-local.xml (63%) diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar deleted file mode 100644 index a29a63180218c9e81bc924a09c14be4b4619b519..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1733 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^BlM4AaJ9Yi?peL1tch zF@~)`i{Q?a1G3=?(~1&HQ(RI@Qj<$E^YemJi^@`qFm#)($XO`C$iN^4^r0<5-NhOC zr8z0SiACAYIhm<>C62{@`6X^3d-Sr3^Yf-oIO})VK%nJ)EmwAHh=8K+>H4Ky0r>?A zO$Aw11}7IS*-_T<)+=;M`TJYGipPsKsJ^e*KX-200f{R=k^`j^g0Eeet+h?;9qZ!t zvu@jH8~kod&|iB|MC*IjpNTT7=4;(Qc1L2((z08Nly|b_aV(g>b<&r`ALgoew_iSP zAgt;oyx8qvnz5OTzux+F`FZc(Eq-`YsHR?8hFPfV^zyBnE?Mv;I$7=K*!IRp>_qXJ zulMJL%+}64am01g+70>>TvirL)Ua<4pQ>S;=cVc{J+s|zdV#TB{6y&&Rksd4%xkV) zw<{><`;G;?=GUxexCH83+b{7vSo~b?effXm)=aMT`kE}755s0yvge=3)bhN zHtRJ0_w^Uvp~dWh_1B^lfI+SW400|{&L}2ObW6#xm4R{M5 zg!I1K@Ejd<- zKQ^=2ShZI*X6bIB-Az;1sQWBA<)56Y+0`@C>Eyq#XA{d+Z}I6}FH_H`p7r2|`NM;u zv05vwV=lDKyp?az^SH0L?!>&N=jZ0!&fhob(2PT;Yj#yE6A1E-Nq#nMhVtg-y|;d) zPf^ej!3mD%0Kx{~4xCbXzdZgy$SsX# z0a{+VI=;Gkfk7LBR*~db; zfeD6@NrV}95d?HS5C|~5bp+Ay0tsCkdVvH|3<66UHGw2t8&dIvYy!4Y2&^4w@n6R> zAQN8HAZtS}GC^e$1c0>72QuN>u$EBhW}%l*Fw?d)-X&-jf$|F3Dv)o{b0)&70AOCl p?`%w~5cw3{9`uxmu;&CbarU63%K&dyHjokQK&S_FXd?@V2LP^BMu-3a diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..fdb70e383f00ec1a31fd06d81aa618347b8aa5b3 GIT binary patch literal 1897 zcmWIWW@h1HVBp|jSmxB}!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9Q}aq3i`_uh=w%h>=Y@uFGBCR?

Ai(h6<{MwahD zlUYEPO`YKDf7pPh?fqZTiLE9AOJ5&*uI6jNTlgTP_uZB^0#VLZo0gcoT$1^!Uj3xi zi^3-YC+prG|F)Z-qmgTW_7%1hGv4Ip7?-NXu>9@sx>|Y6@ORS(h1?4TQ>#rQmmGhy z`&2onF`M?vx!ZC)*ELFVUsxaI8GW$!`OQxs|7Z$zoqXwb_0oisEj@R3M>M|AJ`~I_ zQzKv&iz%1;3*NTt=G)7^^Do}5`^e1o3HeZ_Sr<~2P( zH|KW#zDb8>96DXIt74fzkatY-vuQJwH#hIS^(%df(w-krM5KNk-@82KnLgJnc~DA1 zM2gvpoP`p=ppybdiXAzT;+J1SY`mQHJ8U4(^1hZUyEQ~W(f4%yQm%mf0)?i6tSW<( ziv-!GI;H&mEnmgsMH^J#SL~lVH|>DLl^@B0(h0%WF3i^2CiaeX@%mY}ZL|%3 zweJikKn{gkJOx;e1dsn^|PRW04*WXbl^_R{e!^wjnA)jN6SJhz{&mbWg`>|>$aKwmL3i7?|X+JN2z0s)4% zjvyLd(4lKXFX%vuL10OvCXj?{Ln`*rO#rDzE>l5#h{a_<8eW9q(*`Q*AOPgv`9LOI z8}^b9WSAT?B2rOHJ_)c{z&yv$(0GrqVff2IR!BLBRtBOw05z8*JD?aCHUxZw=>W7m lPn;W2Q#P_2m|2K)16n%AWiKlmD1_O8unOqAn?TbU7yzYKYMcN7 literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom similarity index 83% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom rename to stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom index a296158345..9f04720f7d 100644 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom @@ -3,6 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 4.0.0 io.codearte.accurest.stubs - loanIssuance-stubs + fraudDetectionServer 0.0.1-SNAPSHOT + pom diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 70% rename from stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml index 5e2fc1d528..0bd6282c8e 100644 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -1,12 +1,12 @@ io.codearte.accurest.stubs - fraudDetectionServer-stubs + fraudDetectionServer 0.0.1-SNAPSHOT true - 20160326150924 + 20160409062112 diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml similarity index 61% rename from stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml rename to stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml index 46fa17218f..d4ab9afc83 100644 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml @@ -1,11 +1,12 @@ io.codearte.accurest.stubs - fraudDetectionServer-stubs + fraudDetectionServer + 0.0.1-SNAPSHOT 0.0.1-SNAPSHOT - 20160326150924 + 20160409062112 diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar deleted file mode 100644 index 12d6b10f29e2a1b6c25afea27910ef6af0c4f3ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 587 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^Bm13@$;1F;Mc!xa{1tz+^=dFGg6cC{0rK{tss}~rw zA!r5Lr$(ivu9gb(Ce_6y<*k~;=VD;KRYlpJRp;G1sYNUzYpynC=c`K+U-=X=K6k9GE;P;Q_n7@0(vaR(mIfj}U@@YWGT z!-EoC8+uTJ6obH$Mol0I*M=0Z=q7+vBgYzu53=~LV;PW!2NJqA^w0$B0uoyq=Ob&w V61D-}tZX3FEI{}RNLw?4cmNRMhR*;1 diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..e322590636a2642f1814bfec0720ea78f93fc4ec GIT binary patch literal 639 zcmWIWW@h1HVBp|jSnAa2!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9tz+^=Y@uFGB8Ii z

Ai(h6<{Mwai43=AwF(^fwV3JB2h($(?R)e8*T5VV5rQ=`&SS4)L?lj`D<@>Wga zb1^XAs-kSqs`Kuh)FKv;A 4.0.0 io.codearte.accurest.stubs - loanIssuance-stubs + loanIssuance 0.0.1-SNAPSHOT + pom diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 72% rename from stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml index f33521f12d..5220bd8f0a 100644 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -1,12 +1,12 @@ io.codearte.accurest.stubs - loanIssuance-stubs + loanIssuance 0.0.1-SNAPSHOT true - 20160326150924 + 20160409062111 diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml similarity index 63% rename from stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml rename to stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml index e990fad0bc..bf14a1ad21 100644 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml @@ -1,11 +1,12 @@ io.codearte.accurest.stubs - loanIssuance-stubs + loanIssuance + 0.0.1-SNAPSHOT 0.0.1-SNAPSHOT - 20160326150924 + 20160409062111 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar deleted file mode 100644 index a29a63180218c9e81bc924a09c14be4b4619b519..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1733 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^BlM4AaJ9Yi?peL1tch zF@~)`i{Q?a1G3=?(~1&HQ(RI@Qj<$E^YemJi^@`qFm#)($XO`C$iN^4^r0<5-NhOC zr8z0SiACAYIhm<>C62{@`6X^3d-Sr3^Yf-oIO})VK%nJ)EmwAHh=8K+>H4Ky0r>?A zO$Aw11}7IS*-_T<)+=;M`TJYGipPsKsJ^e*KX-200f{R=k^`j^g0Eeet+h?;9qZ!t zvu@jH8~kod&|iB|MC*IjpNTT7=4;(Qc1L2((z08Nly|b_aV(g>b<&r`ALgoew_iSP zAgt;oyx8qvnz5OTzux+F`FZc(Eq-`YsHR?8hFPfV^zyBnE?Mv;I$7=K*!IRp>_qXJ zulMJL%+}64am01g+70>>TvirL)Ua<4pQ>S;=cVc{J+s|zdV#TB{6y&&Rksd4%xkV) zw<{><`;G;?=GUxexCH83+b{7vSo~b?effXm)=aMT`kE}755s0yvge=3)bhN zHtRJ0_w^Uvp~dWh_1B^lfI+SW400|{&L}2ObW6#xm4R{M5 zg!I1K@Ejd<- zKQ^=2ShZI*X6bIB-Az;1sQWBA<)56Y+0`@C>Eyq#XA{d+Z}I6}FH_H`p7r2|`NM;u zv05vwV=lDKyp?az^SH0L?!>&N=jZ0!&fhob(2PT;Yj#yE6A1E-Nq#nMhVtg-y|;d) zPf^ej!3mD%0Kx{~4xCbXzdZgy$SsX# z0a{+VI=;Gkfk7LBR*~db; zfeD6@NrV}95d?HS5C|~5bp+Ay0tsCkdVvH|3<66UHGw2t8&dIvYy!4Y2&^4w@n6R> zAQN8HAZtS}GC^e$1c0>72QuN>u$EBhW}%l*Fw?d)-X&-jf$|F3Dv)o{b0)&70AOCl p?`%w~5cw3{9`uxmu;&CbarU63%K&dyHjokQK&S_FXd?@V2LP^BMu-3a diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 5e2fc1d528..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer-stubs - 0.0.1-SNAPSHOT - - - true - - 20160326150924 - - diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..fdb70e383f00ec1a31fd06d81aa618347b8aa5b3 GIT binary patch literal 1897 zcmWIWW@h1HVBp|jSmxB}!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9Q}aq3i`_uh=w%h>=Y@uFGBCR?

Ai(h6<{MwahD zlUYEPO`YKDf7pPh?fqZTiLE9AOJ5&*uI6jNTlgTP_uZB^0#VLZo0gcoT$1^!Uj3xi zi^3-YC+prG|F)Z-qmgTW_7%1hGv4Ip7?-NXu>9@sx>|Y6@ORS(h1?4TQ>#rQmmGhy z`&2onF`M?vx!ZC)*ELFVUsxaI8GW$!`OQxs|7Z$zoqXwb_0oisEj@R3M>M|AJ`~I_ zQzKv&iz%1;3*NTt=G)7^^Do}5`^e1o3HeZ_Sr<~2P( zH|KW#zDb8>96DXIt74fzkatY-vuQJwH#hIS^(%df(w-krM5KNk-@82KnLgJnc~DA1 zM2gvpoP`p=ppybdiXAzT;+J1SY`mQHJ8U4(^1hZUyEQ~W(f4%yQm%mf0)?i6tSW<( ziv-!GI;H&mEnmgsMH^J#SL~lVH|>DLl^@B0(h0%WF3i^2CiaeX@%mY}ZL|%3 zweJikKn{gkJOx;e1dsn^|PRW04*WXbl^_R{e!^wjnA)jN6SJhz{&mbWg`>|>$aKwmL3i7?|X+JN2z0s)4% zjvyLd(4lKXFX%vuL10OvCXj?{Ln`*rO#rDzE>l5#h{a_<8eW9q(*`Q*AOPgv`9LOI z8}^b9WSAT?B2rOHJ_)c{z&yv$(0GrqVff2IR!BLBRtBOw05z8*JD?aCHUxZw=>W7m lPn;W2Q#P_2m|2K)16n%AWiKlmD1_O8unOqAn?TbU7yzYKYMcN7 literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..9f04720f7d --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + io.codearte.accurest.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + pom + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..0bd6282c8e --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml new file mode 100644 index 0000000000..d4ab9afc83 --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar deleted file mode 100644 index 12d6b10f29e2a1b6c25afea27910ef6af0c4f3ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 587 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^Bm13@$;1F;Mc!xa{1tz+^=dFGg6cC{0rK{tss}~rw zA!r5Lr$(ivu9gb(Ce_6y<*k~;=VD;KRYlpJRp;G1sYNUzYpynC=c`K+U-=X=K6k9GE;P;Q_n7@0(vaR(mIfj}U@@YWGT z!-EoC8+uTJ6obH$Mol0I*M=0Z=q7+vBgYzu53=~LV;PW!2NJqA^w0$B0uoyq=Ob&w V61D-}tZX3FEI{}RNLw?4cmNRMhR*;1 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..e322590636a2642f1814bfec0720ea78f93fc4ec GIT binary patch literal 639 zcmWIWW@h1HVBp|jSnAa2!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9tz+^=Y@uFGB8Ii z

Ai(h6<{Mwai43=AwF(^fwV3JB2h($(?R)e8*T5VV5rQ=`&SS4)L?lj`D<@>Wga zb1^XAs-kSqs`Kuh)FKv;A 4.0.0 io.codearte.accurest.stubs - fraudDetectionServer-stubs + loanIssuance 0.0.1-SNAPSHOT + pom diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 72% rename from stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml index f33521f12d..5220bd8f0a 100644 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -1,12 +1,12 @@ io.codearte.accurest.stubs - loanIssuance-stubs + loanIssuance 0.0.1-SNAPSHOT true - 20160326150924 + 20160409062111 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml similarity index 63% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml rename to stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml index e990fad0bc..bf14a1ad21 100644 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml +++ b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml @@ -1,11 +1,12 @@ io.codearte.accurest.stubs - loanIssuance-stubs + loanIssuance + 0.0.1-SNAPSHOT 0.0.1-SNAPSHOT - 20160326150924 + 20160409062111 diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.jar deleted file mode 100644 index a29a63180218c9e81bc924a09c14be4b4619b519..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1733 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^BlM4AaJ9Yi?peL1tch zF@~)`i{Q?a1G3=?(~1&HQ(RI@Qj<$E^YemJi^@`qFm#)($XO`C$iN^4^r0<5-NhOC zr8z0SiACAYIhm<>C62{@`6X^3d-Sr3^Yf-oIO})VK%nJ)EmwAHh=8K+>H4Ky0r>?A zO$Aw11}7IS*-_T<)+=;M`TJYGipPsKsJ^e*KX-200f{R=k^`j^g0Eeet+h?;9qZ!t zvu@jH8~kod&|iB|MC*IjpNTT7=4;(Qc1L2((z08Nly|b_aV(g>b<&r`ALgoew_iSP zAgt;oyx8qvnz5OTzux+F`FZc(Eq-`YsHR?8hFPfV^zyBnE?Mv;I$7=K*!IRp>_qXJ zulMJL%+}64am01g+70>>TvirL)Ua<4pQ>S;=cVc{J+s|zdV#TB{6y&&Rksd4%xkV) zw<{><`;G;?=GUxexCH83+b{7vSo~b?effXm)=aMT`kE}755s0yvge=3)bhN zHtRJ0_w^Uvp~dWh_1B^lfI+SW400|{&L}2ObW6#xm4R{M5 zg!I1K@Ejd<- zKQ^=2ShZI*X6bIB-Az;1sQWBA<)56Y+0`@C>Eyq#XA{d+Z}I6}FH_H`p7r2|`NM;u zv05vwV=lDKyp?az^SH0L?!>&N=jZ0!&fhob(2PT;Yj#yE6A1E-Nq#nMhVtg-y|;d) zPf^ej!3mD%0Kx{~4xCbXzdZgy$SsX# z0a{+VI=;Gkfk7LBR*~db; zfeD6@NrV}95d?HS5C|~5bp+Ay0tsCkdVvH|3<66UHGw2t8&dIvYy!4Y2&^4w@n6R> zAQN8HAZtS}GC^e$1c0>72QuN>u$EBhW}%l*Fw?d)-X&-jf$|F3Dv)o{b0)&70AOCl p?`%w~5cw3{9`uxmu;&CbarU63%K&dyHjokQK&S_FXd?@V2LP^BMu-3a diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom deleted file mode 100644 index 2a8b40b197..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/fraudDetectionServer-stubs-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,8 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - fraudDetectionServer-stubs - 0.0.1-SNAPSHOT - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 5e2fc1d528..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer-stubs - 0.0.1-SNAPSHOT - - - true - - 20160326150924 - - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml deleted file mode 100644 index 46fa17218f..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer-stubs - - - 0.0.1-SNAPSHOT - - 20160326150924 - - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..fdb70e383f00ec1a31fd06d81aa618347b8aa5b3 GIT binary patch literal 1897 zcmWIWW@h1HVBp|jSmxB}!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9Q}aq3i`_uh=w%h>=Y@uFGBCR?

Ai(h6<{MwahD zlUYEPO`YKDf7pPh?fqZTiLE9AOJ5&*uI6jNTlgTP_uZB^0#VLZo0gcoT$1^!Uj3xi zi^3-YC+prG|F)Z-qmgTW_7%1hGv4Ip7?-NXu>9@sx>|Y6@ORS(h1?4TQ>#rQmmGhy z`&2onF`M?vx!ZC)*ELFVUsxaI8GW$!`OQxs|7Z$zoqXwb_0oisEj@R3M>M|AJ`~I_ zQzKv&iz%1;3*NTt=G)7^^Do}5`^e1o3HeZ_Sr<~2P( zH|KW#zDb8>96DXIt74fzkatY-vuQJwH#hIS^(%df(w-krM5KNk-@82KnLgJnc~DA1 zM2gvpoP`p=ppybdiXAzT;+J1SY`mQHJ8U4(^1hZUyEQ~W(f4%yQm%mf0)?i6tSW<( ziv-!GI;H&mEnmgsMH^J#SL~lVH|>DLl^@B0(h0%WF3i^2CiaeX@%mY}ZL|%3 zweJikKn{gkJOx;e1dsn^|PRW04*WXbl^_R{e!^wjnA)jN6SJhz{&mbWg`>|>$aKwmL3i7?|X+JN2z0s)4% zjvyLd(4lKXFX%vuL10OvCXj?{Ln`*rO#rDzE>l5#h{a_<8eW9q(*`Q*AOPgv`9LOI z8}^b9WSAT?B2rOHJ_)c{z&yv$(0GrqVff2IR!BLBRtBOw05z8*JD?aCHUxZw=>W7m lPn;W2Q#P_2m|2K)16n%AWiKlmD1_O8unOqAn?TbU7yzYKYMcN7 literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..9f04720f7d --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + io.codearte.accurest.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + pom + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..0bd6282c8e --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml new file mode 100644 index 0000000000..d4ab9afc83 --- /dev/null +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.jar deleted file mode 100644 index 12d6b10f29e2a1b6c25afea27910ef6af0c4f3ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 587 zcmWIWW@h1HVBp|j&}pplU;qLp5CH_7KE;?7qUY=O+4sz8A8%c~i@e^tTIbH3-yCFc#rVO~M^Bm13@$;1F;Mc!xa{1tz+^=dFGg6cC{0rK{tss}~rw zA!r5Lr$(ivu9gb(Ce_6y<*k~;=VD;KRYlpJRp;G1sYNUzYpynC=c`K+U-=X=K6k9GE;P;Q_n7@0(vaR(mIfj}U@@YWGT z!-EoC8+uTJ6obH$Mol0I*M=0Z=q7+vBgYzu53=~LV;PW!2NJqA^w0$B0uoyq=Ob&w V61D-}tZX3FEI{}RNLw?4cmNRMhR*;1 diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom deleted file mode 100644 index a296158345..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/loanIssuance-stubs-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,8 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - loanIssuance-stubs - 0.0.1-SNAPSHOT - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml deleted file mode 100644 index e990fad0bc..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/maven-metadata-local.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - io.codearte.accurest.stubs - loanIssuance-stubs - - - 0.0.1-SNAPSHOT - - 20160326150924 - - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..e322590636a2642f1814bfec0720ea78f93fc4ec GIT binary patch literal 639 zcmWIWW@h1HVBp|jSnAa2!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9tz+^=Y@uFGB8Ii z

Ai(h6<{Mwai43=AwF(^fwV3JB2h($(?R)e8*T5VV5rQ=`&SS4)L?lj`D<@>Wga zb1^XAs-kSqs`Kuh)FKv;A 4.0.0 io.codearte.accurest.stubs - fraudDetectionServer-stubs + loanIssuance 0.0.1-SNAPSHOT + pom diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 72% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml index f33521f12d..5220bd8f0a 100644 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance-stubs/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -1,12 +1,12 @@ io.codearte.accurest.stubs - loanIssuance-stubs + loanIssuance 0.0.1-SNAPSHOT true - 20160326150924 + 20160409062111 diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml similarity index 63% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml rename to stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml index 46fa17218f..bf14a1ad21 100644 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer-stubs/maven-metadata-local.xml +++ b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml @@ -1,11 +1,12 @@ io.codearte.accurest.stubs - fraudDetectionServer-stubs + loanIssuance + 0.0.1-SNAPSHOT 0.0.1-SNAPSHOT - 20160326150924 + 20160409062111 diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy index 3d306ce9bc..8c4525b8bf 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy @@ -31,11 +31,13 @@ class StubDownloader { * @return file where the stubs where unpacked */ File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String - stubsModule) { - log.warn("Downloading stubs for group [$stubsGroup] and module [$stubsModule] from repository [$stubRepositoryRoot]") - URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule) + stubsModule, String classifier) { + log.warn("Downloading stubs for group [$stubsGroup], module [$stubsModule], " + + "classifier [$classifier] from repository [$stubRepositoryRoot]") + URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule, classifier) if (!stubJarUri) { - log.warn("Failed to download stubs for group [$stubsGroup] and module [$stubsModule] from repository [$stubRepositoryRoot]") + log.warn("Failed to download stubs for group [$stubsGroup] artifactId [$stubsModule] and " + + "classifier [$classifier] from repository [$stubRepositoryRoot]") return null } File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) @@ -56,8 +58,8 @@ class StubDownloader { return tmpDirWhereStubsWillBeUnzipped } - private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule) { - Map depToGrab = [group: stubsGroup, module: stubsModule, version: LATEST_MODULE, transitive: false] + private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { + Map depToGrab = [group: stubsGroup, module: stubsModule, classifier: classifier, version: LATEST_MODULE, transitive: false] String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy index d62b876a26..9a12b1c94d 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -31,15 +31,11 @@ class StubRunnerFactory { return collaborators.collect { StubConfiguration stubsConfiguration -> final File unzipedStubDir = stubDownloader.downloadAndUnpackStubJar(stubRunnerOptions.workOffline, stubRunnerOptions.stubRepositoryRoot, - stubsConfiguration.groupId, "$stubsConfiguration.artifactId${getStubDefinitionSuffix(stubsConfiguration)}") + stubsConfiguration.groupId, stubsConfiguration.artifactId, stubsConfiguration.classifier) return createStubRunner(unzipedStubDir, stubsConfiguration) }.findAll { it != null } } - private String getStubDefinitionSuffix(StubConfiguration stubsConfiguration) { - return stubsConfiguration.hasClassifier() ? "-${stubsConfiguration.classifier}" : "" - } - private StubRunner createStubRunner(File unzipedStubDir, StubConfiguration stubsConfiguration) { if (!unzipedStubDir) { return null diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy index d7cf552c8c..2baa98ea68 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy @@ -17,7 +17,7 @@ class StubRunnerFactorySpec extends Specification { def "Should download stub definitions many times"() { given: folder.newFolder("mappings") - 2 * downloader.downloadAndUnpackStubJar(_, _, _, _) >> folder.root + 2 * downloader.downloadAndUnpackStubJar(_, _, _, _, _) >> folder.root stubRunnerOptions.stubRepositoryRoot = folder.root.absolutePath when: Collection stubRunners = collectOnlyPresentValues(factory.createStubsFromServiceConfiguration()) From 1b2af2da18068c100b4ea2661248680ad2f16545 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 11 Apr 2016 19:15:54 +0200 Subject: [PATCH 449/719] allow using custom artifact downloader --- .../stubrunner/GrapeStubDownloader.groovy | 172 ++++++++++++++++++ .../accurest/stubrunner/StubDownloader.groovy | 171 +---------------- .../stubrunner/StubRunnerFactory.groovy | 8 +- 3 files changed, 179 insertions(+), 172 deletions(-) create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy new file mode 100644 index 0000000000..638cadef84 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy @@ -0,0 +1,172 @@ +package io.codearte.accurest.stubrunner + +import groovy.grape.Grape +import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.util.StringUtils +import io.codearte.accurest.stubrunner.util.ZipCategory + +import static java.nio.file.Files.createTempDirectory + +/** + * Downloads stubs from an external repository and unpacks them locally + */ +@Slf4j +class GrapeStubDownloader implements StubDownloader { + + private static final String LATEST_MODULE = '*' + private static final String REPOSITORY_NAME = 'dependency-repository' + private static final String STUB_RUNNER_TEMP_DIR_PREFIX = 'stub-runner' + private static final String GRAPE_CONFIG = 'grape.config' + private static final String STUB_RUNNER_GRAPE_CONFIG = "accurest.stubrunner.grape.config" + + /** + * Downloads stubs from an external repository and unpacks them locally. + * Depending on the switch either uses only local repository to check for + * stub presence. + * + * @param workOffline -flag that defines whether only local cache should be used + * @param stubRepositoryRoot - address of the repo from which deps should be grabbed + * @param stubsGroup - group name of the jar containing stubs + * @param stubsModule - artifact id with a classifier name of the jar containing stubs + * @return file where the stubs where unpacked + */ + File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String + stubsModule, String classifier) { + log.warn("Downloading stubs for group [$stubsGroup], module [$stubsModule], " + + "classifier [$classifier] from repository [$stubRepositoryRoot]") + URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule, classifier) + if (!stubJarUri) { + log.warn("Failed to download stubs for group [$stubsGroup] artifactId [$stubsModule] and " + + "classifier [$classifier] from repository [$stubRepositoryRoot]") + return null + } + File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) + unzippedStubsDir.deleteOnExit() + Thread.addShutdownHook { + unzippedStubsDir.deleteDir() + } + return unzippedStubsDir + } + + private File unpackStubJarToATemporaryFolder(URI stubJarUri) { + File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(STUB_RUNNER_TEMP_DIR_PREFIX).toFile() + tmpDirWhereStubsWillBeUnzipped.deleteOnExit() + log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") + use(ZipCategory) { + new File(stubJarUri).unzipTo(tmpDirWhereStubsWillBeUnzipped) + } + return tmpDirWhereStubsWillBeUnzipped + } + + private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { + Map depToGrab = [group: stubsGroup, module: stubsModule, classifier: classifier, version: LATEST_MODULE, transitive: false] + String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) + initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) + String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) + try { + System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) + log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") + if (StringUtils.hasText(stubRepositoryRoot)) { + return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) + } + log.warn("No repository passed so will try to resolve dependencies from local Maven Repo") + return buildResolver(true).resolveDependency(stubRepositoryRoot, depToGrab) + } finally { + restoreOldGrapeConfigIfApplicable(oldGrapeConfig) + } + } + + private DependencyResolver buildResolver(boolean workOffline) { + return workOffline ? new LocalOnlyDependencyResolver() : new RemoteDependencyResolver() + } + + private void initializeAccurestGrapeIfAbsent(String accurestGrapePath) { + File accurestGrape = new File(accurestGrapePath) + if (!accurestGrape.exists()) { + accurestGrape.parentFile.mkdirs() + accurestGrape.createNewFile() + accurestGrape.text = GrapeStubDownloader.class.getResource('/accurestStubrunnerGrapeConfig.xml').text + } + } + + private void restoreOldGrapeConfigIfApplicable(String oldGrapeConfig) { + if (oldGrapeConfig) { + System.setProperty(GRAPE_CONFIG, oldGrapeConfig) + } + } + + private String getDefaultAccurestGrapeConfigPath() { + return "${System.getProperty('user.home')}/.accurest/accurestStubrunnerGrapeConfig.xml" + } + + /** + * Dependency resolver providing {@link URI} to remote dependencies. + */ + @Slf4j + private class RemoteDependencyResolver extends DependencyResolver { + + URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { + try { + return doResolveRemoteDependency(stubRepositoryRoot, depToGrab) + } catch (UnknownHostException e) { + failureHandler(stubRepositoryRoot, "unknown host error -> ${e.message}", e) + } catch (Exception e) { + failureHandler(stubRepositoryRoot, "connection error -> ${e.message}", e) + } + } + + private URI doResolveRemoteDependency(String stubRepositoryRoot, Map depToGrab) { + Grape.addResolver(name: REPOSITORY_NAME, root: stubRepositoryRoot) + log.info("Resolving dependency ${depToGrab} location in remote repository...") + return resolveDependencyLocation(depToGrab) + } + + private void failureHandler(String stubRepository, String reason, Exception cause) { + log.warn("Unable to resolve dependency in stub repository [$stubRepository]. Reason: [$reason]", cause) + } + + } + + /** + * Dependency resolver that first checks if a dependency is available in the local repository. + * If not, it will try to provide {@link URI} from the remote repository. + * + * @see RemoteDependencyResolver + */ + @Slf4j + private class LocalOnlyDependencyResolver extends DependencyResolver { + + URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { + try { + log.info("Resolving dependency ${depToGrab} location in local repository...") + return resolveDependencyLocation(depToGrab) + } catch (Exception e) { //Grape throws ordinary RuntimeException + log.warn("Unable to find dependency $depToGrab in local repository, trying $stubRepositoryRoot") + log.debug("Unable to find dependency $depToGrab in local repository: ${e.getClass()}: ${e.message}") + return null + } + } + } + + /** + * Base class of dependency resolvers providing {@link URI} to required dependency. + */ + abstract class DependencyResolver { + + /** + * Returns {@link URI} to a dependency. + * + * @param stubRepositoryRoot root of the repository where the dependency should be found + * @param depToGrab parameters describing dependency to search for + * + * @return {@link URI} to dependency + */ + abstract URI resolveDependency(String stubRepositoryRoot, Map depToGrab) + + URI resolveDependencyLocation(Map depToGrab) { + return Grape.resolve([classLoader: new GroovyClassLoader()], depToGrab).first() + } + + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy index 8c4525b8bf..006e639cfd 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy @@ -1,172 +1,7 @@ package io.codearte.accurest.stubrunner -import groovy.grape.Grape -import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.util.StringUtils -import io.codearte.accurest.stubrunner.util.ZipCategory +interface StubDownloader { -import static java.nio.file.Files.createTempDirectory - -/** - * Downloads stubs from an external repository and unpacks them locally - */ -@Slf4j -class StubDownloader { - - private static final String LATEST_MODULE = '*' - private static final String REPOSITORY_NAME = 'dependency-repository' - private static final String STUB_RUNNER_TEMP_DIR_PREFIX = 'stub-runner' - private static final String GRAPE_CONFIG = 'grape.config' - private static final String STUB_RUNNER_GRAPE_CONFIG = "accurest.stubrunner.grape.config" - - /** - * Downloads stubs from an external repository and unpacks them locally. - * Depending on the switch either uses only local repository to check for - * stub presence. - * - * @param workOffline -flag that defines whether only local cache should be used - * @param stubRepositoryRoot - address of the repo from which deps should be grabbed - * @param stubsGroup - group name of the jar containing stubs - * @param stubsModule - artifact id with a classifier name of the jar containing stubs - * @return file where the stubs where unpacked - */ File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String - stubsModule, String classifier) { - log.warn("Downloading stubs for group [$stubsGroup], module [$stubsModule], " + - "classifier [$classifier] from repository [$stubRepositoryRoot]") - URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule, classifier) - if (!stubJarUri) { - log.warn("Failed to download stubs for group [$stubsGroup] artifactId [$stubsModule] and " + - "classifier [$classifier] from repository [$stubRepositoryRoot]") - return null - } - File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) - unzippedStubsDir.deleteOnExit() - Thread.addShutdownHook { - unzippedStubsDir.deleteDir() - } - return unzippedStubsDir - } - - private File unpackStubJarToATemporaryFolder(URI stubJarUri) { - File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(STUB_RUNNER_TEMP_DIR_PREFIX).toFile() - tmpDirWhereStubsWillBeUnzipped.deleteOnExit() - log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") - use(ZipCategory) { - new File(stubJarUri).unzipTo(tmpDirWhereStubsWillBeUnzipped) - } - return tmpDirWhereStubsWillBeUnzipped - } - - private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { - Map depToGrab = [group: stubsGroup, module: stubsModule, classifier: classifier, version: LATEST_MODULE, transitive: false] - String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) - initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) - String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) - try { - System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) - log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") - if (StringUtils.hasText(stubRepositoryRoot)) { - return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) - } - log.warn("No repository passed so will try to resolve dependencies from local Maven Repo") - return buildResolver(true).resolveDependency(stubRepositoryRoot, depToGrab) - } finally { - restoreOldGrapeConfigIfApplicable(oldGrapeConfig) - } - } - - private DependencyResolver buildResolver(boolean workOffline) { - return workOffline ? new LocalOnlyDependencyResolver() : new RemoteDependencyResolver() - } - - private void initializeAccurestGrapeIfAbsent(String accurestGrapePath) { - File accurestGrape = new File(accurestGrapePath) - if (!accurestGrape.exists()) { - accurestGrape.parentFile.mkdirs() - accurestGrape.createNewFile() - accurestGrape.text = StubDownloader.class.getResource('/accurestStubrunnerGrapeConfig.xml').text - } - } - - private void restoreOldGrapeConfigIfApplicable(String oldGrapeConfig) { - if (oldGrapeConfig) { - System.setProperty(GRAPE_CONFIG, oldGrapeConfig) - } - } - - private String getDefaultAccurestGrapeConfigPath() { - return "${System.getProperty('user.home')}/.accurest/accurestStubrunnerGrapeConfig.xml" - } - - /** - * Dependency resolver providing {@link URI} to remote dependencies. - */ - @Slf4j - private class RemoteDependencyResolver extends DependencyResolver { - - URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { - try { - return doResolveRemoteDependency(stubRepositoryRoot, depToGrab) - } catch (UnknownHostException e) { - failureHandler(stubRepositoryRoot, "unknown host error -> ${e.message}", e) - } catch (Exception e) { - failureHandler(stubRepositoryRoot, "connection error -> ${e.message}", e) - } - } - - private URI doResolveRemoteDependency(String stubRepositoryRoot, Map depToGrab) { - Grape.addResolver(name: REPOSITORY_NAME, root: stubRepositoryRoot) - log.info("Resolving dependency ${depToGrab} location in remote repository...") - return resolveDependencyLocation(depToGrab) - } - - private void failureHandler(String stubRepository, String reason, Exception cause) { - log.warn("Unable to resolve dependency in stub repository [$stubRepository]. Reason: [$reason]", cause) - } - - } - - /** - * Dependency resolver that first checks if a dependency is available in the local repository. - * If not, it will try to provide {@link URI} from the remote repository. - * - * @see RemoteDependencyResolver - */ - @Slf4j - private class LocalOnlyDependencyResolver extends DependencyResolver { - - URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { - try { - log.info("Resolving dependency ${depToGrab} location in local repository...") - return resolveDependencyLocation(depToGrab) - } catch (Exception e) { //Grape throws ordinary RuntimeException - log.warn("Unable to find dependency $depToGrab in local repository, trying $stubRepositoryRoot") - log.debug("Unable to find dependency $depToGrab in local repository: ${e.getClass()}: ${e.message}") - return null - } - } - } - - /** - * Base class of dependency resolvers providing {@link URI} to required dependency. - */ - abstract class DependencyResolver { - - /** - * Returns {@link URI} to a dependency. - * - * @param stubRepositoryRoot root of the repository where the dependency should be found - * @param depToGrab parameters describing dependency to search for - * - * @return {@link URI} to dependency - */ - abstract URI resolveDependency(String stubRepositoryRoot, Map depToGrab) - - URI resolveDependencyLocation(Map depToGrab) { - return Grape.resolve([classLoader: new GroovyClassLoader()], depToGrab).first() - } - - } - -} + stubsModule, String classifier) +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy index 9a12b1c94d..501acb20f6 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -3,13 +3,13 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j + /** * Factory of StubRunners. Basing on the options and passed collaborators * downloads the stubs and returns a list of corresponding stub runners. */ @Slf4j @CompileStatic -@PackageScope class StubRunnerFactory { private final StubRunnerOptions stubRunnerOptions @@ -17,11 +17,11 @@ class StubRunnerFactory { private final StubDownloader stubDownloader StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators) { - this(stubRunnerOptions, collaborators, new StubDownloader()) + this(stubRunnerOptions, collaborators, new GrapeStubDownloader()) } - protected StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators, - StubDownloader stubDownloader) { + StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators, + StubDownloader stubDownloader) { this.stubRunnerOptions = stubRunnerOptions this.collaborators = collaborators this.stubDownloader = stubDownloader From c550ba2c4d0e301e1113686b63d63d26fdc88bbc Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 11 Apr 2016 19:15:54 +0200 Subject: [PATCH 450/719] allow using custom artifact downloader --- .../stubrunner/BatchStubRunnerFactory.groovy | 10 +- .../stubrunner/GrapeStubDownloader.groovy | 172 ++++++++++++++++++ .../accurest/stubrunner/StubDownloader.groovy | 171 +---------------- .../stubrunner/StubRunnerFactory.groovy | 11 +- 4 files changed, 188 insertions(+), 176 deletions(-) create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy index 18652eb767..99b01dcfc0 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy @@ -13,14 +13,22 @@ class BatchStubRunnerFactory { private final StubRunnerOptions stubRunnerOptions private final Collection dependencies + private final StubDownloader stubDownloader BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies) { + this(stubRunnerOptions, dependencies, new GrapeStubDownloader()) + } + + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, + Collection dependencies, + StubDownloader stubDownloader) { this.stubRunnerOptions = stubRunnerOptions this.dependencies = dependencies + this.stubDownloader = stubDownloader } BatchStubRunner buildBatchStubRunner() { - StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, dependencies) + StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, dependencies, stubDownloader) return new BatchStubRunner(stubRunnerFactory.createStubsFromServiceConfiguration()) } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy new file mode 100644 index 0000000000..638cadef84 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy @@ -0,0 +1,172 @@ +package io.codearte.accurest.stubrunner + +import groovy.grape.Grape +import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.util.StringUtils +import io.codearte.accurest.stubrunner.util.ZipCategory + +import static java.nio.file.Files.createTempDirectory + +/** + * Downloads stubs from an external repository and unpacks them locally + */ +@Slf4j +class GrapeStubDownloader implements StubDownloader { + + private static final String LATEST_MODULE = '*' + private static final String REPOSITORY_NAME = 'dependency-repository' + private static final String STUB_RUNNER_TEMP_DIR_PREFIX = 'stub-runner' + private static final String GRAPE_CONFIG = 'grape.config' + private static final String STUB_RUNNER_GRAPE_CONFIG = "accurest.stubrunner.grape.config" + + /** + * Downloads stubs from an external repository and unpacks them locally. + * Depending on the switch either uses only local repository to check for + * stub presence. + * + * @param workOffline -flag that defines whether only local cache should be used + * @param stubRepositoryRoot - address of the repo from which deps should be grabbed + * @param stubsGroup - group name of the jar containing stubs + * @param stubsModule - artifact id with a classifier name of the jar containing stubs + * @return file where the stubs where unpacked + */ + File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String + stubsModule, String classifier) { + log.warn("Downloading stubs for group [$stubsGroup], module [$stubsModule], " + + "classifier [$classifier] from repository [$stubRepositoryRoot]") + URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule, classifier) + if (!stubJarUri) { + log.warn("Failed to download stubs for group [$stubsGroup] artifactId [$stubsModule] and " + + "classifier [$classifier] from repository [$stubRepositoryRoot]") + return null + } + File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) + unzippedStubsDir.deleteOnExit() + Thread.addShutdownHook { + unzippedStubsDir.deleteDir() + } + return unzippedStubsDir + } + + private File unpackStubJarToATemporaryFolder(URI stubJarUri) { + File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(STUB_RUNNER_TEMP_DIR_PREFIX).toFile() + tmpDirWhereStubsWillBeUnzipped.deleteOnExit() + log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") + use(ZipCategory) { + new File(stubJarUri).unzipTo(tmpDirWhereStubsWillBeUnzipped) + } + return tmpDirWhereStubsWillBeUnzipped + } + + private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { + Map depToGrab = [group: stubsGroup, module: stubsModule, classifier: classifier, version: LATEST_MODULE, transitive: false] + String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) + initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) + String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) + try { + System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) + log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") + if (StringUtils.hasText(stubRepositoryRoot)) { + return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) + } + log.warn("No repository passed so will try to resolve dependencies from local Maven Repo") + return buildResolver(true).resolveDependency(stubRepositoryRoot, depToGrab) + } finally { + restoreOldGrapeConfigIfApplicable(oldGrapeConfig) + } + } + + private DependencyResolver buildResolver(boolean workOffline) { + return workOffline ? new LocalOnlyDependencyResolver() : new RemoteDependencyResolver() + } + + private void initializeAccurestGrapeIfAbsent(String accurestGrapePath) { + File accurestGrape = new File(accurestGrapePath) + if (!accurestGrape.exists()) { + accurestGrape.parentFile.mkdirs() + accurestGrape.createNewFile() + accurestGrape.text = GrapeStubDownloader.class.getResource('/accurestStubrunnerGrapeConfig.xml').text + } + } + + private void restoreOldGrapeConfigIfApplicable(String oldGrapeConfig) { + if (oldGrapeConfig) { + System.setProperty(GRAPE_CONFIG, oldGrapeConfig) + } + } + + private String getDefaultAccurestGrapeConfigPath() { + return "${System.getProperty('user.home')}/.accurest/accurestStubrunnerGrapeConfig.xml" + } + + /** + * Dependency resolver providing {@link URI} to remote dependencies. + */ + @Slf4j + private class RemoteDependencyResolver extends DependencyResolver { + + URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { + try { + return doResolveRemoteDependency(stubRepositoryRoot, depToGrab) + } catch (UnknownHostException e) { + failureHandler(stubRepositoryRoot, "unknown host error -> ${e.message}", e) + } catch (Exception e) { + failureHandler(stubRepositoryRoot, "connection error -> ${e.message}", e) + } + } + + private URI doResolveRemoteDependency(String stubRepositoryRoot, Map depToGrab) { + Grape.addResolver(name: REPOSITORY_NAME, root: stubRepositoryRoot) + log.info("Resolving dependency ${depToGrab} location in remote repository...") + return resolveDependencyLocation(depToGrab) + } + + private void failureHandler(String stubRepository, String reason, Exception cause) { + log.warn("Unable to resolve dependency in stub repository [$stubRepository]. Reason: [$reason]", cause) + } + + } + + /** + * Dependency resolver that first checks if a dependency is available in the local repository. + * If not, it will try to provide {@link URI} from the remote repository. + * + * @see RemoteDependencyResolver + */ + @Slf4j + private class LocalOnlyDependencyResolver extends DependencyResolver { + + URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { + try { + log.info("Resolving dependency ${depToGrab} location in local repository...") + return resolveDependencyLocation(depToGrab) + } catch (Exception e) { //Grape throws ordinary RuntimeException + log.warn("Unable to find dependency $depToGrab in local repository, trying $stubRepositoryRoot") + log.debug("Unable to find dependency $depToGrab in local repository: ${e.getClass()}: ${e.message}") + return null + } + } + } + + /** + * Base class of dependency resolvers providing {@link URI} to required dependency. + */ + abstract class DependencyResolver { + + /** + * Returns {@link URI} to a dependency. + * + * @param stubRepositoryRoot root of the repository where the dependency should be found + * @param depToGrab parameters describing dependency to search for + * + * @return {@link URI} to dependency + */ + abstract URI resolveDependency(String stubRepositoryRoot, Map depToGrab) + + URI resolveDependencyLocation(Map depToGrab) { + return Grape.resolve([classLoader: new GroovyClassLoader()], depToGrab).first() + } + + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy index 8c4525b8bf..006e639cfd 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy @@ -1,172 +1,7 @@ package io.codearte.accurest.stubrunner -import groovy.grape.Grape -import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.util.StringUtils -import io.codearte.accurest.stubrunner.util.ZipCategory +interface StubDownloader { -import static java.nio.file.Files.createTempDirectory - -/** - * Downloads stubs from an external repository and unpacks them locally - */ -@Slf4j -class StubDownloader { - - private static final String LATEST_MODULE = '*' - private static final String REPOSITORY_NAME = 'dependency-repository' - private static final String STUB_RUNNER_TEMP_DIR_PREFIX = 'stub-runner' - private static final String GRAPE_CONFIG = 'grape.config' - private static final String STUB_RUNNER_GRAPE_CONFIG = "accurest.stubrunner.grape.config" - - /** - * Downloads stubs from an external repository and unpacks them locally. - * Depending on the switch either uses only local repository to check for - * stub presence. - * - * @param workOffline -flag that defines whether only local cache should be used - * @param stubRepositoryRoot - address of the repo from which deps should be grabbed - * @param stubsGroup - group name of the jar containing stubs - * @param stubsModule - artifact id with a classifier name of the jar containing stubs - * @return file where the stubs where unpacked - */ File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String - stubsModule, String classifier) { - log.warn("Downloading stubs for group [$stubsGroup], module [$stubsModule], " + - "classifier [$classifier] from repository [$stubRepositoryRoot]") - URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule, classifier) - if (!stubJarUri) { - log.warn("Failed to download stubs for group [$stubsGroup] artifactId [$stubsModule] and " + - "classifier [$classifier] from repository [$stubRepositoryRoot]") - return null - } - File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) - unzippedStubsDir.deleteOnExit() - Thread.addShutdownHook { - unzippedStubsDir.deleteDir() - } - return unzippedStubsDir - } - - private File unpackStubJarToATemporaryFolder(URI stubJarUri) { - File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(STUB_RUNNER_TEMP_DIR_PREFIX).toFile() - tmpDirWhereStubsWillBeUnzipped.deleteOnExit() - log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") - use(ZipCategory) { - new File(stubJarUri).unzipTo(tmpDirWhereStubsWillBeUnzipped) - } - return tmpDirWhereStubsWillBeUnzipped - } - - private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { - Map depToGrab = [group: stubsGroup, module: stubsModule, classifier: classifier, version: LATEST_MODULE, transitive: false] - String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) - initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) - String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) - try { - System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) - log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") - if (StringUtils.hasText(stubRepositoryRoot)) { - return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) - } - log.warn("No repository passed so will try to resolve dependencies from local Maven Repo") - return buildResolver(true).resolveDependency(stubRepositoryRoot, depToGrab) - } finally { - restoreOldGrapeConfigIfApplicable(oldGrapeConfig) - } - } - - private DependencyResolver buildResolver(boolean workOffline) { - return workOffline ? new LocalOnlyDependencyResolver() : new RemoteDependencyResolver() - } - - private void initializeAccurestGrapeIfAbsent(String accurestGrapePath) { - File accurestGrape = new File(accurestGrapePath) - if (!accurestGrape.exists()) { - accurestGrape.parentFile.mkdirs() - accurestGrape.createNewFile() - accurestGrape.text = StubDownloader.class.getResource('/accurestStubrunnerGrapeConfig.xml').text - } - } - - private void restoreOldGrapeConfigIfApplicable(String oldGrapeConfig) { - if (oldGrapeConfig) { - System.setProperty(GRAPE_CONFIG, oldGrapeConfig) - } - } - - private String getDefaultAccurestGrapeConfigPath() { - return "${System.getProperty('user.home')}/.accurest/accurestStubrunnerGrapeConfig.xml" - } - - /** - * Dependency resolver providing {@link URI} to remote dependencies. - */ - @Slf4j - private class RemoteDependencyResolver extends DependencyResolver { - - URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { - try { - return doResolveRemoteDependency(stubRepositoryRoot, depToGrab) - } catch (UnknownHostException e) { - failureHandler(stubRepositoryRoot, "unknown host error -> ${e.message}", e) - } catch (Exception e) { - failureHandler(stubRepositoryRoot, "connection error -> ${e.message}", e) - } - } - - private URI doResolveRemoteDependency(String stubRepositoryRoot, Map depToGrab) { - Grape.addResolver(name: REPOSITORY_NAME, root: stubRepositoryRoot) - log.info("Resolving dependency ${depToGrab} location in remote repository...") - return resolveDependencyLocation(depToGrab) - } - - private void failureHandler(String stubRepository, String reason, Exception cause) { - log.warn("Unable to resolve dependency in stub repository [$stubRepository]. Reason: [$reason]", cause) - } - - } - - /** - * Dependency resolver that first checks if a dependency is available in the local repository. - * If not, it will try to provide {@link URI} from the remote repository. - * - * @see RemoteDependencyResolver - */ - @Slf4j - private class LocalOnlyDependencyResolver extends DependencyResolver { - - URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { - try { - log.info("Resolving dependency ${depToGrab} location in local repository...") - return resolveDependencyLocation(depToGrab) - } catch (Exception e) { //Grape throws ordinary RuntimeException - log.warn("Unable to find dependency $depToGrab in local repository, trying $stubRepositoryRoot") - log.debug("Unable to find dependency $depToGrab in local repository: ${e.getClass()}: ${e.message}") - return null - } - } - } - - /** - * Base class of dependency resolvers providing {@link URI} to required dependency. - */ - abstract class DependencyResolver { - - /** - * Returns {@link URI} to a dependency. - * - * @param stubRepositoryRoot root of the repository where the dependency should be found - * @param depToGrab parameters describing dependency to search for - * - * @return {@link URI} to dependency - */ - abstract URI resolveDependency(String stubRepositoryRoot, Map depToGrab) - - URI resolveDependencyLocation(Map depToGrab) { - return Grape.resolve([classLoader: new GroovyClassLoader()], depToGrab).first() - } - - } - -} + stubsModule, String classifier) +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy index 9a12b1c94d..d06ae1f190 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -3,25 +3,22 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j + /** * Factory of StubRunners. Basing on the options and passed collaborators * downloads the stubs and returns a list of corresponding stub runners. */ @Slf4j @CompileStatic -@PackageScope class StubRunnerFactory { private final StubRunnerOptions stubRunnerOptions private final Collection collaborators private final StubDownloader stubDownloader - StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators) { - this(stubRunnerOptions, collaborators, new StubDownloader()) - } - - protected StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators, - StubDownloader stubDownloader) { + StubRunnerFactory(StubRunnerOptions stubRunnerOptions, + Collection collaborators, + StubDownloader stubDownloader) { this.stubRunnerOptions = stubRunnerOptions this.collaborators = collaborators this.stubDownloader = stubDownloader From b0ce2060551210ab477c4ad908d72609cf492055 Mon Sep 17 00:00:00 2001 From: Maciej Zielinski Date: Tue, 12 Apr 2016 16:13:42 +0200 Subject: [PATCH 451/719] #221 Support for execute method in headers --- .../builder/JUnitMethodBodyBuilder.groovy | 13 +++++++++ .../JaxRsClientJUnitMethodBodyBuilder.groovy | 20 +++++++++++++- .../JaxRsClientSpockMethodBodyBuilder.groovy | 20 +++++++++++++- .../accurest/builder/MethodBodyBuilder.groovy | 12 +++++++++ .../MockMvcJUnitMethodBodyBuilder.groovy | 23 ++++++++++------ .../MockMvcSpockMethodBodyBuilder.groovy | 27 ++++++++++++------- .../builder/SpockMethodBodyBuilder.groovy | 10 +++++++ .../MockMvcMethodBodyBuilderSpec.groovy | 16 +++++++---- .../pairId/moreComplexVersion.groovy | 4 +++ .../ofg/twitter/places/BaseMockMvcSpec.groovy | 5 ++++ 10 files changed, 126 insertions(+), 24 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index bd84b6ab41..246a9b372a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -9,6 +9,8 @@ import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.NamedProperty import io.codearte.accurest.dsl.internal.Request +import java.util.regex.Pattern + import static groovy.json.StringEscapeUtils.escapeJava import static io.codearte.accurest.config.TestFramework.JUNIT import static io.codearte.accurest.util.ContentUtils.getJavaMultipartFileParameterContent @@ -113,4 +115,15 @@ abstract class JUnitMethodBodyBuilder extends MethodBodyBuilder { protected String getParameterString(Map.Entry parameter) { return """.param("${escapeJava(parameter.key)}", "${escapeJava(parameter.value as String)}")""" } + + protected String createHeaderComparison(Object headerValue) { + String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") + return "isEqualTo(\"$escapedHeader\");" + } + + protected String createHeaderComparison(Pattern headerValue) { + String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") + return "matches(\"$escapedHeader\");" + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy index 27c5d0f51a..ab8506d61f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy @@ -1,10 +1,13 @@ package io.codearte.accurest.builder 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.QueryParameter import io.codearte.accurest.dsl.internal.QueryParameters +import java.util.regex.Pattern + import static io.codearte.accurest.config.TestFramework.JUNIT /** @@ -94,7 +97,7 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { response.headers?.collect { Header header -> - bb.addLine("assertThat(response.getHeaderString(\"$header.name\")).isEqualTo(\"$header.serverValue\");") + processHeaderElement(bb, header.name, header.serverValue) } } @@ -107,4 +110,19 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { return 'responseAsString' } + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) { + blockBuilder.addLine("assertThat(response.getHeaderString(\"$property\")).${createHeaderComparison(value)}") + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) { + blockBuilder.addLine("assertThat(response.getHeaderString(\"$property\")).${createHeaderComparison(pattern)}") + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { + blockBuilder.addLine("${exec.insertValue("response.getHeaderString(\"$property\")")};") + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy index 0a5339f0e0..cc47fc751a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodBodyBuilder.groovy @@ -3,10 +3,13 @@ package io.codearte.accurest.builder 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.QueryParameter import io.codearte.accurest.dsl.internal.QueryParameters +import java.util.regex.Pattern + @PackageScope @TypeChecked class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { @@ -95,7 +98,7 @@ class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { response.headers?.collect { Header header -> - bb.addLine("response.getHeaderString('$header.name') == '$header.serverValue'") + processHeaderElement(bb, header.name, header.serverValue) } } @@ -104,4 +107,19 @@ class JaxRsClientSpockMethodBodyBuilder extends SpockMethodBodyBuilder { return 'responseAsString' } + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { + blockBuilder.addLine("${exec.insertValue("response.getHeaderString(\'$property\')")}") + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) { + blockBuilder.addLine("response.getHeaderString('$property') ${convertHeaderComparison(value)}") + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern value) { + blockBuilder.addLine("response.getHeaderString('$property') ${convertHeaderComparison(value)}") + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index a78488d441..9b93acc5f2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -19,6 +19,8 @@ import io.codearte.accurest.util.JsonPaths import io.codearte.accurest.util.JsonToJsonPathsConverter 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 @@ -55,6 +57,12 @@ abstract class MethodBodyBuilder { protected abstract void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) + protected abstract void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) + + protected abstract void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) + + protected abstract void processHeaderElement(BlockBuilder blockBuilder, String property, String value) + protected abstract String getPropertyInListString(String property, Integer index) protected abstract String convertUnicodeEscapesIfRequired(String json) @@ -198,6 +206,9 @@ abstract class MethodBodyBuilder { return s.substring(1); } + protected void processHeaderElement(BlockBuilder blockBuilder, String property, Object value) { + } + protected void processBodyElement(BlockBuilder blockBuilder, String property, Object value) { } @@ -307,4 +318,5 @@ abstract class MethodBodyBuilder { private boolean hasQueryParams(Url url) { return url.queryParameters } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy index 6bfc8c357f..d3bd3acbe7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.Header import java.util.regex.Pattern @@ -22,18 +23,24 @@ class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { - response.headers?.collect { Header header -> - bb.addLine("assertThat(response.header(\"$header.name\")).${createHeaderComparison(header.serverValue)}") + response.headers?.collect { Header header ->\ + processHeaderElement(bb, header.name, header.serverValue) } } - private String createHeaderComparison(Object headerValue) { - String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") - return "isEqualTo(\"$escapedHeader\");" + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) { + blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(value)}") } - private String createHeaderComparison(Pattern headerValue) { - String escapedHeader = convertUnicodeEscapesIfRequired("$headerValue") - return "matches(\"$escapedHeader\");" + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) { + blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(pattern)}") } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { + blockBuilder.addLine("${exec.insertValue("response.header(\"$property\")")};") + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy index fe18c08a19..80ee1169b2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodBodyBuilder.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.builder 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 java.util.regex.Pattern @@ -23,20 +24,28 @@ class MockMvcSpockMethodBodyBuilder extends SpockMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { response.headers?.collect { Header header -> - bb.addLine("response.header('$header.name') ${convertHeaderComparison(header.serverValue)}") + processHeaderElement(bb, header.name, header.serverValue) } } - private String convertHeaderComparison(Object headerValue) { - return " == '$headerValue'" - } - - private String convertHeaderComparison(Pattern headerValue) { - return "==~ java.util.regex.Pattern.compile('$headerValue')" - } - @Override protected String getResponseAsString() { return 'response.body.asString()' } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { + blockBuilder.addLine("${exec.insertValue("response.header(\'$property\')")}") + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) { + blockBuilder.addLine("response.header('$property') ${convertHeaderComparison(value)}") + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern value) { + blockBuilder.addLine("response.header('$property') ${convertHeaderComparison(value)}") + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy index 55dba94b57..b7a3f22e60 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodBodyBuilder.groovy @@ -9,6 +9,8 @@ import io.codearte.accurest.dsl.internal.Header import io.codearte.accurest.dsl.internal.NamedProperty import io.codearte.accurest.dsl.internal.Request +import java.util.regex.Pattern + import static io.codearte.accurest.util.ContentUtils.getGroovyMultipartFileParameterContent /** @@ -97,4 +99,12 @@ abstract class SpockMethodBodyBuilder extends MethodBodyBuilder { return ".param('$parameter.key', '$parameter.value')" } + protected String convertHeaderComparison(String headerValue) { + return " == '$headerValue'" + } + + protected String convertHeaderComparison(Pattern headerValue) { + return "==~ java.util.regex.Pattern.compile('$headerValue')" + } + } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index ab3a0ae4c3..c38b346d37 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -884,6 +884,10 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub }""") headers { header('Content-Type': 'application/vnd.fraud.v1+json') + header 'Location': value( + stub(null), + test(execute('assertThatLocationIsNull($it)')) + ) } } } @@ -891,13 +895,15 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + String test = blockBuilder.toString() then: - test.contains(assertionString) + assertionStrings.each { String assertionString -> + assert test.contains(assertionString) + } where: - methodBuilderName | methodBuilder | assertionString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } | '''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''' - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''' + 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"))'''] } @Unroll diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy index 943fbc23b9..8348974b89 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy @@ -12,6 +12,10 @@ io.codearte.accurest.dsl.GroovyDsl.make { ''' } response { + headers { + header 'Content-Type': $(client('application/json'), server(regex('application/json.*'))) + header 'Location': $(client('https://localhost:8080'), server(execute('isEmpty($it)'))) + } body ( path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy index 6b8e7e630e..37f40e1ba9 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy @@ -13,4 +13,9 @@ abstract class BaseMockMvcSpec extends Specification { void isProperCorrelationId(Integer correlationId) { assert correlationId == 123456 } + + void isEmpty(String value) { + assert value == null + } + } From 33c2fdf300f26b6a8d5e038bd95b57ad8908ed05 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 12 Apr 2016 16:59:06 +0200 Subject: [PATCH 452/719] Allow external usage of StubRunner --- .../accurest/stubrunner/StubRunner.groovy | 20 ++++++++++++++----- .../stubrunner/StubRunnerFactory.groovy | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy index 0777d7d56a..b28238cddc 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -15,21 +15,31 @@ import groovy.util.logging.Slf4j class StubRunner implements StubRunning { private StubRunnerExecutor localStubRunner - private final Arguments arguments private final StubRepository stubRepository + private StubConfiguration stubsConfiguration + private StubRunnerOptions stubRunnerOptions + @Deprecated StubRunner(Arguments arguments) { - this.arguments = arguments + stubsConfiguration = arguments.stub + stubRunnerOptions = arguments.stubRunnerOptions this.stubRepository = new StubRepository(new File(arguments.repositoryPath)) } + StubRunner(StubRunnerOptions stubRunnerOptions, String repositoryPath, StubConfiguration stubsConfiguration) { + this.stubsConfiguration = stubsConfiguration + this.stubRunnerOptions = stubRunnerOptions + this.stubRepository = new StubRepository(new File(repositoryPath)) + } + @Override RunningStubs runStubs() { - AvailablePortScanner portScanner = new AvailablePortScanner(arguments.stubRunnerOptions.minPortValue, - arguments.stubRunnerOptions.maxPortValue) + AvailablePortScanner portScanner = new AvailablePortScanner(stubRunnerOptions.minPortValue, + stubRunnerOptions.maxPortValue) localStubRunner = new StubRunnerExecutor(portScanner) registerShutdownHook() - return localStubRunner.runStubs(stubRepository, arguments.stub) + + return localStubRunner.runStubs(stubRepository, stubsConfiguration) } @Override diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy index d06ae1f190..9ea6992988 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -42,7 +42,7 @@ class StubRunnerFactory { private StubRunner createStubRunner(File unzippedStubsDir, StubConfiguration stubsConfiguration, StubRunnerOptions stubRunnerOptions) { - return new StubRunner(new Arguments(stubRunnerOptions, unzippedStubsDir.path, stubsConfiguration)) + return new StubRunner(stubRunnerOptions, unzippedStubsDir.path, stubsConfiguration) } } From 9b591edca8e3953a8cf52f087da4c8f4a3629a8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 12 Apr 2016 21:26:33 +0200 Subject: [PATCH 453/719] Use src/test/accurest as default directory for contracts (#227) --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 f13dca4039..6288fa93b4 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 @@ -47,7 +47,7 @@ class AccurestGradlePlugin implements Plugin { void setConfigurationDefaults(AccurestConfigProperties extension) { extension.with { generatedTestSourcesDir = project.file("${project.buildDir}/generated-test-sources/accurest") - contractsDslDir = project.file("${project.rootDir}/src/test/resources/stubs") //TODO: Use sourceset + contractsDslDir = project.file("${project.rootDir}/src/test/accurest") //TODO: Use sourceset basePackageForTests = 'io.codearte.accurest.tests' } } From 79634f48fcdfe2483e9e039547bbc8cff4099abc Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 12 Apr 2016 16:04:46 -0400 Subject: [PATCH 454/719] Fixed the way we parse lists with regexps in responses (#224) * Fixed the way we parse lists with regexps in responses fixes #216 --- .../accurest/util/ContentUtils.groovy | 30 ++++++-- .../util/DelegatingJsonVerifiable.java | 1 + .../util/JsonToJsonPathsConverter.groovy | 26 +++++-- .../accurest/util/MapConverter.groovy | 3 +- .../MockMvcMethodBodyBuilderSpec.groovy | 73 ++++++++++++++++++- 5 files changed, 116 insertions(+), 17 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy index 87e93b4e9e..d2916f36d5 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy @@ -27,8 +27,12 @@ class ContentUtils { it instanceof DslProperty ? it.clientValue : it } + public static final Closure GET_TEST_SIDE = { + it instanceof DslProperty ? it.serverValue : it + } + private static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile('.*REGEXP>>(.*)<<.*') - private static final Pattern TEMPORARY_EXECUTION_PATTERN_HOLDER = Pattern.compile('EXECUTION>>(.*)<<') + private static final Pattern TEMPORARY_EXECUTION_PATTERN_HOLDER = Pattern.compile('["]?EXECUTION>>(.*)<<["]?') private static final Pattern TEMPORARY_OPTIONAL_PATTERN_HOLDER = Pattern.compile('OPTIONAL>>(.*)<<') private static final String JSON_VALUE_PATTERN_FOR_REGEX = 'REGEXP>>%s<<' private static final String JSON_VALUE_PATTERN_FOR_OPTIONAL = 'OPTIONAL>>%s<<' @@ -150,23 +154,23 @@ class ContentUtils { ) } - private static String transformJSONStringValue(Object obj, Closure valueProvider) { - return obj.toString() + protected static Object transformJSONStringValue(Object obj, Closure valueProvider) { + return obj } - private static String transformJSONStringValue(DslProperty dslProperty, Closure valueProvider) { + protected static Object transformJSONStringValue(DslProperty dslProperty, Closure valueProvider) { return transformJSONStringValue(valueProvider(dslProperty), valueProvider) } - private static String transformJSONStringValue(Pattern pattern, Closure valueProvider) { + protected static Object transformJSONStringValue(Pattern pattern, Closure valueProvider) { return String.format(JSON_VALUE_PATTERN_FOR_REGEX, pattern.pattern()) } - private static String transformJSONStringValue(OptionalProperty optional, Closure valueProvider) { + protected static Object transformJSONStringValue(OptionalProperty optional, Closure valueProvider) { return String.format(JSON_VALUE_PATTERN_FOR_OPTIONAL, optional.value) } - private static String transformJSONStringValue(ExecutionProperty property, Closure valueProvider) { + protected static Object transformJSONStringValue(ExecutionProperty property, Closure valueProvider) { return String.format(JSON_VALUE_PATTERN_FOR_EXECUTION, property.executionCommand) } @@ -178,6 +182,12 @@ class ContentUtils { return transformXMLStringValue(valueProvider(dslProperty), valueProvider) } + protected static Object convertDslPropsToTemporaryRegexPatterns(parsedJson) { + MapConverter.transformValues(parsedJson, { Object value -> + return transformJSONStringValue(value, GET_TEST_SIDE) + }) + } + private static Object convertAllTemporaryRegexPlaceholdersBackToPatterns(parsedJson) { MapConverter.transformValues(parsedJson, { Object value -> if (value instanceof String) { @@ -212,7 +222,11 @@ class ContentUtils { * @param string to match the regexps against * @return object converted from temporary holders */ - static Object returnParsedObject(String string) { + static Object returnParsedObject(Object object) { + if (!(object instanceof String)) { + return object + } + String string = (String) object Matcher matcher = TEMPORARY_PATTERN_HOLDER.matcher(string.trim()) if (matcher.matches()) { return Pattern.compile(patternFromMatchingGroup(matcher)) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index bafc287877..dae53a5fc1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -137,6 +137,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { public MethodBufferingJsonVerifiable matches(String value) { DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.matches(value), methodsBuffer); if (delegate.isAssertingAValueInArray()) { + readyToCheck.appendMethodWithQuotedValue("matches", escapeJava(value)); readyToCheck.methodsBuffer.append(".value()"); } else { readyToCheck.appendMethodWithQuotedValue("matches", escapeJava(value)); diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 8ab311fdb6..a3d0576cd2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -29,9 +29,10 @@ class JsonToJsonPathsConverter { } JsonPaths pathsAndValues = [] as Set Object convertedJson = MapConverter.getClientOrServerSideValues(json, clientSide) + Object jsonWithPatterns = ContentUtils.convertDslPropsToTemporaryRegexPatterns(convertedJson) MethodBufferingJsonVerifiable methodBufferingJsonPathVerifiable = - new DelegatingJsonVerifiable(JsonAssertion.assertThat(JsonOutput.toJson(convertedJson)).withoutThrowingException()) - traverseRecursivelyForKey(convertedJson, methodBufferingJsonPathVerifiable) + new DelegatingJsonVerifiable(JsonAssertion.assertThat(JsonOutput.toJson(jsonWithPatterns)).withoutThrowingException()) + traverseRecursivelyForKey(jsonWithPatterns, methodBufferingJsonPathVerifiable) { MethodBufferingJsonVerifiable key, Object value -> if (value instanceof ExecutionProperty || !(key instanceof FinishedDelegatingJsonVerifiable)) { return @@ -42,6 +43,7 @@ class JsonToJsonPathsConverter { } protected static def traverseRecursively(Class parentType, MethodBufferingJsonVerifiable key, def value, Closure closure) { + value = ContentUtils.returnParsedObject(value) if (value instanceof String && value) { try { def json = new JsonSlurper().parseText(value) @@ -91,7 +93,11 @@ class JsonToJsonPathsConverter { private static MethodBufferingJsonVerifiable createAsserterFromListElement(MethodBufferingJsonVerifiable jsonPathVerifiable, def element) { if (jsonPathVerifiable.isAssertingAValueInArray()) { - return jsonPathVerifiable.contains(element) + def object = ContentUtils.returnParsedObject(element) + if (object instanceof Pattern) { + return jsonPathVerifiable.matches((object as Pattern).pattern()) + } + return jsonPathVerifiable.contains(object) } return jsonPathVerifiable } @@ -145,13 +151,14 @@ class JsonToJsonPathsConverter { private static Map convertWithKey(Class parentType, MethodBufferingJsonVerifiable parentKey, Map map, Closure closureToExecute) { return map.collectEntries { Object entrykey, value -> + def convertedValue = ContentUtils.returnParsedObject(value) [entrykey, traverseRecursively(parentType, - value instanceof List ? listContainsOnlyPrimitives(value) ? + convertedValue instanceof List ? listContainsOnlyPrimitives(convertedValue) ? parentKey.arrayField(entrykey) : parentKey.array(entrykey) : - value instanceof Map ? parentKey.field(new ShouldTraverse(entrykey)) : - valueToAsserter(parentKey.field(entrykey), value) - , value, closureToExecute)] + convertedValue instanceof Map ? parentKey.field(new ShouldTraverse(entrykey)) : + valueToAsserter(parentKey.field(entrykey), convertedValue) + , convertedValue, closureToExecute)] } } @@ -160,12 +167,17 @@ class JsonToJsonPathsConverter { } protected static MethodBufferingJsonVerifiable valueToAsserter(MethodBufferingJsonVerifiable key, Object value) { + if (key instanceof FinishedDelegatingJsonVerifiable) { + return key + } if (value instanceof Pattern) { return key.matches((value as Pattern).pattern()) } else if (value instanceof OptionalProperty) { return key.matches((value as OptionalProperty).optionalPattern()) } else if (value instanceof GString) { return key.matches(RegexpBuilders.buildGStringRegexpForTestSide(value)) + } else if (ContentUtils.returnParsedObject(value) instanceof ExecutionProperty) { + return key } return key.isEqualTo(value) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy index 477f0fef78..4f21f880ff 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy @@ -1,12 +1,13 @@ package io.codearte.accurest.util + import groovy.json.JsonSlurper import io.codearte.accurest.dsl.internal.DslProperty + /** * @author Marcin Grzejszczak */ class MapConverter { - public static final boolean STUB_SIDE = true public static final boolean TEST_SIDE = false diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index c38b346d37..349b244f97 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -8,7 +8,6 @@ import spock.lang.Specification import spock.lang.Unroll import java.util.regex.Pattern - /** * @author Jakub Kubrynski */ @@ -1118,4 +1117,76 @@ World.'''""" "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } + @Issue('#216') + @Unroll + def "should parse JSON with arrays using #methodBuilderName"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + urlPath('/auth/oauth/check_token') { + queryParameters { + parameter 'token': + value( + client(regex('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')), + server('6973b31d-7140-402a-bca6-1cdb954e03a7') + ) + } + } + } + response { + status 200 + body( + authorities: [ + value(stub('ROLE_ADMIN'), test(regex('^[a-zA-Z0-9_\\- ]+$'))) + ] + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThatJson(parsedJson).array("authorities").matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''') + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + } + + @Unroll + def "should work with execution property"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'PUT' + url '/fraudcheck' + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + } + + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + !test.contains('''assertThatJson(parsedJson).field("rejectionReason").isEqualTo("assertThatRejectionReasonIsNull("''') + test.contains('''assertThatRejectionReasonIsNull(''') + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + } + + + } From e32fdfea7c20debd3ddfc76ae27c29a27ae20c65 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 12 Apr 2016 22:55:14 +0200 Subject: [PATCH 455/719] Release version: 1.0.5 [ci skip] From 401e5e5e2233b8864568b2ba54cf0641aca86fb8 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 12 Apr 2016 22:55:14 +0200 Subject: [PATCH 456/719] Release version: 1.0.5 [ci skip] From ea9ebe43f3b97c2467bf743ca5f38382739476a4 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 12 Apr 2016 22:55:14 +0200 Subject: [PATCH 457/719] Release version: 1.0.5 [ci skip] From 038a17d66e4f53432b5a9cd561372c2025033c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Wed, 13 Apr 2016 09:17:29 +0200 Subject: [PATCH 458/719] Implement stub-runner and change source to groovy (#3) --- pom.xml | 858 ++++++++++-------- .../accurest/maven/AccurestConverter.groovy | 17 + .../accurest/maven/ConvertMojo.groovy | 36 + .../accurest/maven/GenerateStubsMojo.groovy | 42 + .../accurest/maven/GenerateTestsMojo.groovy | 77 ++ .../io/codearte/accurest/maven/RunMojo.groovy | 66 ++ .../stubrunner/AetherStubDownloader.groovy | 55 ++ .../AetherStubDownloaderFactory.groovy | 32 + .../maven/stubrunner/LocalStubRunner.groovy | 29 + .../maven/stubrunner/RemoteStubRunner.groovy | 38 + .../accurest/maven/AccurestConverter.java | 14 - .../codearte/accurest/maven/ConvertMojo.java | 39 - .../accurest/maven/GenerateStubsMojo.java | 45 - .../accurest/maven/GenerateTestsMojo.java | 78 -- .../io/codearte/accurest/maven/RunMojo.java | 68 -- .../src/test/accurest/greetings_ok.json | 21 + .../greetings_with_default_value.json | 16 + 17 files changed, 889 insertions(+), 642 deletions(-) create mode 100644 src/main/groovy/io/codearte/accurest/maven/AccurestConverter.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy delete mode 100644 src/main/java/io/codearte/accurest/maven/AccurestConverter.java delete mode 100644 src/main/java/io/codearte/accurest/maven/ConvertMojo.java delete mode 100644 src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java delete mode 100644 src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java delete mode 100644 src/main/java/io/codearte/accurest/maven/RunMojo.java create mode 100644 src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.json create mode 100644 src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.json diff --git a/pom.xml b/pom.xml index c6e124f418..a7efd84bb8 100644 --- a/pom.xml +++ b/pom.xml @@ -1,419 +1,481 @@ - 4.0.0 + 4.0.0 - io.codearte.accurest - accurest-maven-plugin - maven-plugin - 0.5.1-SNAPSHOT + io.codearte.accurest + accurest-maven-plugin + maven-plugin + 0.5.1-SNAPSHOT - Accurate Maven Plugin Project - Accurate REST Maven Plugin - https://github.com/Codearte/accurest-maven-plugin + Accurate Maven Plugin Project + Accurate REST Maven Plugin + https://github.com/Codearte/accurest-maven-plugin - - [3.2.1,) - + + [3.2.1,) + - - - mariuszs - Mariusz Smykula - mariuszs@gmail.com - - + + + mariuszs + Mariusz Smykula + mariuszs@gmail.com + + - - 3.2.5 - 3.4 + + 3.2.5 + 3.4 - UTF-8 - 1.0.4 - + UTF-8 + 1.0.5 - - - Apache 2 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - A business-friendly OSS license - - + 1.1.0 - - scm:git:https://github.com/Codearte/accurest-maven-plugin.git - scm:git:git@github.com:Codearte/accurest-maven-plugin.git - https://github.com/Codearte/accurest-maven-plugin - HEAD - + 1.7 + 1.7 + - - - oss - Sonatype Nexus Snapshots - http://oss.sonatype.org/content/repositories/snapshots - - - oss - Nexus Release Repository - http://oss.sonatype.org/service/local/staging/deploy/maven2/ - - + + + Apache 2 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + - - - - org.codehaus.plexus - plexus-component-metadata - 1.6 - - - - generate-metadata - generate-test-metadata - - - - - - maven-plugin-plugin - ${mavenPluginPluginVersion} - - true - - - - generated-helpmojo - - helpmojo - - - - generate-descriptor - - descriptor - - - - - - io.takari.maven.plugins - takari-lifecycle-plugin - 1.11.12 - true - - - testProperties - process-test-resources - - testProperties - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.19.1 - - - - integration-test - verify - - - - - - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - **/HelpMojo.class - - - - - prepare-agent - - prepare-agent - - - - - - org.eluder.coveralls - coveralls-maven-plugin - 4.1.0 - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - false - true - v@{project.version} - - - + + scm:git:https://github.com/Codearte/accurest-maven-plugin.git + scm:git:git@github.com:Codearte/accurest-maven-plugin.git + https://github.com/Codearte/accurest-maven-plugin + HEAD + - - - - maven-install-plugin - 2.5.2 - - - maven-source-plugin - 3.0.0 - - - maven-javadoc-plugin - 2.10.3 - - - - + + + oss + Sonatype Nexus Snapshots + http://oss.sonatype.org/content/repositories/snapshots + + + oss + Nexus Release Repository + http://oss.sonatype.org/service/local/staging/deploy/maven2/ + + - - - io.codearte.accurest - accurest-core - ${accurest.version} - - - io.codearte.accurest - accurest-converters - ${accurest.version} - - - org.codehaus.groovy - groovy-all - 2.4.6 - + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.5 + + + + compile + + + + + + org.codehaus.plexus + plexus-component-metadata + 1.6 + + + + generate-metadata + generate-test-metadata + + + + + + maven-plugin-plugin + ${mavenPluginPluginVersion} + + true + + + + generated-helpmojo + + helpmojo + + + + generate-descriptor + + descriptor + + + + + + io.takari.maven.plugins + takari-lifecycle-plugin + 1.11.12 + true + + + testProperties + process-test-resources + + testProperties + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.19.1 + + + + integration-test + verify + + + + + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + **/HelpMojo.class + + + + + prepare-agent + + prepare-agent + + + + + + org.eluder.coveralls + coveralls-maven-plugin + 4.1.0 + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + false + true + v@{project.version} + + + - - ch.qos.logback - logback-core - 1.1.3 - - - org.slf4j - slf4j-simple - 1.7.12 - test - - - org.apache.maven - maven-core - ${mavenVersion} - test - - - org.apache.maven - maven-compat - ${mavenVersion} - test - + + + + maven-install-plugin + 2.5.2 + + + maven-source-plugin + 3.0.0 + + + maven-javadoc-plugin + 2.10.3 + + + + - - org.apache.maven - maven-plugin-api - ${mavenVersion} - provided - - - org.apache.maven.plugin-tools - maven-plugin-annotations - ${mavenPluginPluginVersion} - provided - + + + io.codearte.accurest + accurest-core + ${accurest.version} + + + io.codearte.accurest + accurest-converters + ${accurest.version} + + + io.codearte.accurest + stub-runner + ${accurest.version} + + + com.github.tomakehurst + wiremock + 2.0.8-beta + - - io.takari.maven.plugins - takari-plugin-testing - 2.8.0 - test - - - io.takari.maven.plugins - takari-plugin-integration-testing - 2.8.0 - pom - test - - - junit - junit - 4.12 - test - - + + org.codehaus.groovy + groovy-all + 2.4.6 + - - - release - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.0 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - oss - https://oss.sonatype.org/ - true - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.10 - - - parse-version - deploy - - parse-version - - - - - - org.codehaus.mojo - versions-maven-plugin - 2.2 - - - switch-to-snapshot-version - deploy - - set - - - - ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT - - - - - - org.apache.maven.plugins - maven-scm-plugin - 1.9.4 - false - - - tag-new-release - deploy - - tag - - - v${project.version} - - - - save-changes - deploy - - checkin - - - connection - pom.xml - Setting next development version to ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT. + + org.eclipse.aether + aether-api + ${aetherVersion} + provided + - [ci skip] - - - - - - - - - - version - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.10 - - - parse-version - initialize - - parse-version - - - - - - org.codehaus.mojo - versions-maven-plugin - 2.2 - - - set-release-version - initialize - - set - - - ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion} - - - - - - - - + + ch.qos.logback + logback-core + 1.1.3 + + + org.slf4j + slf4j-simple + 1.7.12 + test + + + + javax.inject + javax.inject + 1 + provided + + + org.apache.maven + maven-core + ${mavenVersion} + provided + + + + org.apache.maven + maven-plugin-api + ${mavenVersion} + provided + + + org.apache.maven + maven-model + + + org.apache.maven + maven-artifact + + + org.eclipse.sisu + org.eclipse.sisu.plexus + + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${mavenPluginPluginVersion} + provided + + + + io.takari.maven.plugins + takari-plugin-testing + 2.8.0 + test + + + io.takari.maven.plugins + takari-plugin-integration-testing + 2.8.0 + pom + test + + + org.apache.maven + maven-compat + ${mavenVersion} + test + + + junit + junit + 4.12 + test + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + oss + https://oss.sonatype.org/ + true + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + parse-version + deploy + + parse-version + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.2 + + + switch-to-snapshot-version + deploy + + set + + + + + ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT + + + + + + + org.apache.maven.plugins + maven-scm-plugin + 1.9.4 + false + + + tag-new-release + deploy + + tag + + + v${project.version} + + + + save-changes + deploy + + checkin + + + connection + pom.xml + Setting next development version to + ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT. + + [ci skip] + + + + + + + + + + + version + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.10 + + + parse-version + initialize + + parse-version + + + + + + org.codehaus.mojo + versions-maven-plugin + 2.2 + + + set-release-version + initialize + + set + + + + ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion} + + + + + + + + + diff --git a/src/main/groovy/io/codearte/accurest/maven/AccurestConverter.groovy b/src/main/groovy/io/codearte/accurest/maven/AccurestConverter.groovy new file mode 100644 index 0000000000..dba4190397 --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/AccurestConverter.groovy @@ -0,0 +1,17 @@ +package io.codearte.accurest.maven; + +import groovy.transform.CompileStatic; +import groovy.transform.PackageScope; +import io.codearte.accurest.config.AccurestConfigProperties; +import io.codearte.accurest.wiremock.DslToWireMockClientConverter; +import io.codearte.accurest.wiremock.RecursiveFilesConverter; + +@CompileStatic +class AccurestConverter { + + static void convertAccurestToStubs(AccurestConfigProperties config) { + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config) + converter.processFiles() + } + +} diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy new file mode 100644 index 0000000000..d90cbc7133 --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -0,0 +1,36 @@ +package io.codearte.accurest.maven + +import groovy.transform.CompileStatic +import io.codearte.accurest.config.AccurestConfigProperties +import org.apache.maven.plugin.AbstractMojo +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.plugins.annotations.Mojo +import org.apache.maven.plugins.annotations.Parameter + +import static io.codearte.accurest.maven.AccurestConverter.convertAccurestToStubs + +@Mojo(name = 'convert', requiresProject = false) +@CompileStatic +public class ConvertMojo extends AbstractMojo { + + @Parameter(property = 'contractsDir', defaultValue = '${basedir}') + private File contractsDir + + @Parameter(property = 'mappingsDir', defaultValue = '${basedir}') + private File mappingsDir + + public void execute() throws MojoExecutionException, MojoFailureException { + + AccurestConfigProperties config = new AccurestConfigProperties() + config.contractsDslDir = contractsDir + config.stubsOutputDir = mappingsDir + + log.info('Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings') + log.info(" Accurest contracts directory: ${config.contractsDslDir.absolutePath}") + log.info("WireMock stubs mappings directory: ${config.stubsOutputDir.absolutePath}") + + convertAccurestToStubs(config) + } + +} diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy new file mode 100644 index 0000000000..82ec235e0f --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy @@ -0,0 +1,42 @@ +package io.codearte.accurest.maven + +import groovy.transform.CompileStatic +import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.wiremock.DslToWireMockClientConverter +import io.codearte.accurest.wiremock.RecursiveFilesConverter +import org.apache.maven.plugin.AbstractMojo +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.plugins.annotations.LifecyclePhase +import org.apache.maven.plugins.annotations.Mojo +import org.apache.maven.plugins.annotations.Parameter + +@Mojo(name = 'generateStubs', defaultPhase = LifecyclePhase.PROCESS_RESOURCES) +@CompileStatic +public class GenerateStubsMojo extends AbstractMojo { + + @Parameter(defaultValue = '${basedir}', readonly = true, required = true) + private File baseDir + + @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) + private File projectBuildDirectory + + @Parameter(defaultValue = '/src/test/accurest') + private String contractsDir + + @Parameter(defaultValue = 'mappings') + private String mappingsDir + + public void execute() throws MojoExecutionException, MojoFailureException { + AccurestConfigProperties config = new AccurestConfigProperties() + config.contractsDslDir = new File(baseDir, contractsDir) + config.stubsOutputDir = new File(projectBuildDirectory, mappingsDir) + + log.info('Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion') + log.info("From '${config.contractsDslDir}' to '${config.stubsOutputDir}'") + + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config) + converter.processFiles() + } + +} diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy new file mode 100644 index 0000000000..1f642b109b --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy @@ -0,0 +1,77 @@ +package io.codearte.accurest.maven + +import groovy.transform.CompileStatic +import io.codearte.accurest.AccurestException +import io.codearte.accurest.TestGenerator +import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.config.TestFramework +import io.codearte.accurest.config.TestMode +import org.apache.maven.plugin.AbstractMojo +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.plugins.annotations.LifecyclePhase +import org.apache.maven.plugins.annotations.Mojo +import org.apache.maven.plugins.annotations.Parameter + +import static java.lang.String.format + +@Mojo(name = 'generateTests', defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) +@CompileStatic +public class GenerateTestsMojo extends AbstractMojo { + + @Parameter(defaultValue = '${basedir}', readonly = true, required = true) + private File baseDir + + @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) + private File projectBuildDirectory + + @Parameter(defaultValue = '/src/test/accurest') + private String contractsDir + + @Parameter(defaultValue = '/generated-test-sources/accurest') + private String generatedTestSourcesDir + + @Parameter(defaultValue = 'io.codearte.accurest.tests') + private String basePackageForTests + + @Parameter + private String baseClassForTests + + @Parameter(defaultValue = 'MOCKMVC') + private TestMode testMode + + @Parameter(defaultValue = 'JUNIT') + private TestFramework testFramework + + @Parameter + private String ruleClassForTests + + @Parameter + private String nameSuffixForTests + + public void execute() throws MojoExecutionException, MojoFailureException { + log.info('Generating server tests source code for Accurest contract verification') + + AccurestConfigProperties config = new AccurestConfigProperties() + config.contractsDslDir = new File(baseDir, contractsDir) + config.generatedTestSourcesDir = new File(projectBuildDirectory, generatedTestSourcesDir) + config.targetFramework = testFramework + config.testMode = testMode + config.basePackageForTests = basePackageForTests + config.baseClassForTests = baseClassForTests + config.ruleClassForTests = ruleClassForTests + config.nameSuffixForTests = nameSuffixForTests + + log.info("Using ${config.generatedTestSourcesDir} as test source directory") + log.info("Using ${config.baseClassForTests} as base class for test classes") + + try { + TestGenerator generator = new TestGenerator(config) + int generatedClasses = generator.generate() + log.info("Generated $generatedClasses test classes.") + } catch (AccurestException e) { + throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e) + } + } + +} diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy new file mode 100644 index 0000000000..5f72edbbdb --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -0,0 +1,66 @@ +package io.codearte.accurest.maven + +import groovy.transform.CompileStatic +import io.codearte.accurest.maven.stubrunner.LocalStubRunner +import io.codearte.accurest.maven.stubrunner.RemoteStubRunner +import io.codearte.accurest.stubrunner.StubRunnerOptions +import org.apache.maven.plugin.AbstractMojo +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.plugins.annotations.Mojo +import org.apache.maven.plugins.annotations.Parameter +import org.eclipse.aether.RepositorySystemSession + +import javax.inject.Inject + +@Mojo(name = 'run', requiresProject = false) +@CompileStatic +public class RunMojo extends AbstractMojo { + + @Parameter(defaultValue = '${repositorySystemSession}', readonly = true) + private RepositorySystemSession repoSession + + @Parameter(property = 'contractsDir', defaultValue = '${basedir}') + private File contractsDir + + @Parameter(property = 'stubs') + private String stubs + + @Parameter(property = 'minPort', defaultValue = '10000') + private int minPort + + @Parameter(property = 'maxPort', defaultValue = '15000') + private int maxPort + + + private String stubsClassifier = 'stubs' + + private final LocalStubRunner localStubRunner + private final RemoteStubRunner remoteStubRunner + + @Inject + public RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner) { + this.localStubRunner = localStubRunner + this.remoteStubRunner = remoteStubRunner + } + + public void execute() throws MojoExecutionException, MojoFailureException { + StubRunnerOptions options = new StubRunnerOptions(minPort, maxPort, "", false, stubsClassifier) + log.debug("Launching StubRunner with args: $options") + if (!stubs) { + localStubRunner.run(contractsDir, options) + } else { + remoteStubRunner.run(stubs, options, repoSession) + } + pressAnyKeyToContinue() + } + + private void pressAnyKeyToContinue() { + log.info("Press ENTER to continue...") + try { + System.in.read() + } catch (Exception ignored) { + } + } + +} diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy new file mode 100644 index 0000000000..11fa13a111 --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy @@ -0,0 +1,55 @@ +package io.codearte.accurest.maven.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.StubDownloader +import org.eclipse.aether.RepositorySystem +import org.eclipse.aether.RepositorySystemSession +import org.eclipse.aether.artifact.Artifact +import org.eclipse.aether.artifact.DefaultArtifact +import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.resolution.ArtifactRequest +import org.eclipse.aether.resolution.ArtifactResult + +import static io.codearte.accurest.stubrunner.util.ZipCategory.unzipTo +import static java.nio.file.Files.createTempDirectory + +@PackageScope +@CompileStatic +@Slf4j +class AetherStubDownloader implements StubDownloader { + + private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest' + private static final String ARTIFACT_EXTENSION = 'jar' + private static final String ARTIFACT_VERSION = 'LATEST' + + private final List remoteRepos + private final RepositorySystem repoSystem + private final RepositorySystemSession repoSession + + AetherStubDownloader(RepositorySystem repoSystem, List remoteRepos, RepositorySystemSession repoSession) { + this.remoteRepos = remoteRepos + this.repoSystem = repoSystem + this.repoSession = repoSession + } + + @Override + public File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { + Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, ARTIFACT_VERSION) + ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos) + log.info("Resolving artifact $artifact from $remoteRepos") + ArtifactResult result = repoSystem.resolveArtifact(repoSession, request) + log.info("Resolved artifact $artifact to ${result.getArtifact().getFile()} from ${result.getRepository()}") + return unpackStubJarToATemporaryFolder(result.getArtifact().getFile().toURI()) + } + + private static File unpackStubJarToATemporaryFolder(URI stubJarUri) { + File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(ACCUREST_TEMP_DIR_PREFIX).toFile() + tmpDirWhereStubsWillBeUnzipped.deleteOnExit() + log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") + unzipTo(new File(stubJarUri), tmpDirWhereStubsWillBeUnzipped) + return tmpDirWhereStubsWillBeUnzipped + } + +} diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy new file mode 100644 index 0000000000..241b9a6cac --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy @@ -0,0 +1,32 @@ +package io.codearte.accurest.maven.stubrunner + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import org.apache.maven.project.MavenProject +import org.eclipse.aether.RepositorySystem +import org.eclipse.aether.RepositorySystemSession + +import javax.inject.Inject +import javax.inject.Named +import javax.inject.Singleton + +@Named +@Singleton +@CompileStatic +@Slf4j +public class AetherStubDownloaderFactory { + + private final MavenProject project + private final RepositorySystem repoSystem + + @Inject + public AetherStubDownloaderFactory(RepositorySystem repoSystem, MavenProject project) { + this.repoSystem = repoSystem + this.project = project + } + + AetherStubDownloader build(RepositorySystemSession repoSession) { + return new AetherStubDownloader(repoSystem, project.getRemoteProjectRepositories(), repoSession) + } + +} diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy new file mode 100644 index 0000000000..441a150881 --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy @@ -0,0 +1,29 @@ +package io.codearte.accurest.maven.stubrunner + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.maven.AccurestConverter +import io.codearte.accurest.stubrunner.StubConfiguration +import io.codearte.accurest.stubrunner.StubRunner +import io.codearte.accurest.stubrunner.StubRunnerOptions + +import javax.inject.Named +import java.nio.file.Files + +import static io.codearte.accurest.maven.AccurestConverter.convertAccurestToStubs + +@Named +@CompileStatic +@Slf4j +class LocalStubRunner { + + void run(File contractsDir, StubRunnerOptions options) { + log.info("Launching StubRunner with contracts from ${contractsDir}") + File mappingsOutput = Files.createTempDirectory('accurest').toFile() + mappingsOutput.deleteOnExit() + AccurestConfigProperties config = new AccurestConfigProperties(contractsDslDir: contractsDir, stubsOutputDir: mappingsOutput) + convertAccurestToStubs(config) + new StubRunner(options, contractsDir.getPath(), new StubConfiguration(mappingsOutput.toString())).runStubs() + } +} diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy new file mode 100644 index 0000000000..eceb17b032 --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy @@ -0,0 +1,38 @@ +package io.codearte.accurest.maven.stubrunner + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.* +import io.codearte.accurest.stubrunner.util.StubsParser +import org.eclipse.aether.RepositorySystemSession + +import javax.inject.Inject +import javax.inject.Named + +@Named +@CompileStatic +@Slf4j +class RemoteStubRunner { + + private final AetherStubDownloaderFactory aetherStubDownloaderFactory + + @Inject + RemoteStubRunner(AetherStubDownloaderFactory aetherStubDownloaderFactory) { + this.aetherStubDownloaderFactory = aetherStubDownloaderFactory + } + + void run(String stubs, StubRunnerOptions options, RepositorySystemSession repositorySystemSession) { + AetherStubDownloader stubDownloader = aetherStubDownloaderFactory.build(repositorySystemSession) + try { + log.debug("Launching StubRunner with args: $options") + Collection collaborators = StubsParser.fromString(stubs, options.stubsClassifier) + BatchStubRunner stubRunner = new BatchStubRunnerFactory(options, collaborators, stubDownloader) + .buildBatchStubRunner() + RunningStubs runningCollaborators = stubRunner.runStubs() + log.info(runningCollaborators.toString()) + } catch (Exception e) { + log.error("An exception occurred while trying to execute the stubs: ${e.getMessage()}") + throw e + } + } +} diff --git a/src/main/java/io/codearte/accurest/maven/AccurestConverter.java b/src/main/java/io/codearte/accurest/maven/AccurestConverter.java deleted file mode 100644 index e04b814bce..0000000000 --- a/src/main/java/io/codearte/accurest/maven/AccurestConverter.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.codearte.accurest.maven; - -import io.codearte.accurest.config.AccurestConfigProperties; -import io.codearte.accurest.wiremock.DslToWireMockClientConverter; -import io.codearte.accurest.wiremock.RecursiveFilesConverter; - -public class AccurestConverter { - - public void convert(AccurestConfigProperties config){ - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); - converter.processFiles(); - } - -} diff --git a/src/main/java/io/codearte/accurest/maven/ConvertMojo.java b/src/main/java/io/codearte/accurest/maven/ConvertMojo.java deleted file mode 100644 index 16ee3642db..0000000000 --- a/src/main/java/io/codearte/accurest/maven/ConvertMojo.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.codearte.accurest.maven; - -import static java.lang.String.format; - -import java.io.File; - -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; - -import io.codearte.accurest.config.AccurestConfigProperties; -import io.codearte.accurest.wiremock.DslToWireMockClientConverter; -import io.codearte.accurest.wiremock.RecursiveFilesConverter; - -@Mojo(name = "convert", requiresProject = false) -public class ConvertMojo extends AbstractMojo { - - @Parameter(property = "contractsDir", defaultValue = "${basedir}") - private File contractsDir; - - @Parameter(property = "mappingsDir", defaultValue = "${basedir}") - private File mappingsDir; - - public void execute() throws MojoExecutionException, MojoFailureException { - - AccurestConfigProperties config = new AccurestConfigProperties(); - config.setContractsDslDir(contractsDir); - config.setStubsOutputDir(mappingsDir); - - getLog().info("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings"); - getLog().info(format(" Accurest contracts directory: %s", config.getContractsDslDir().getAbsolutePath())); - getLog().info(format("WireMock stubs mappings directory: %s", config.getStubsOutputDir().getAbsolutePath())); - - new AccurestConverter().convert(config); - } - -} diff --git a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java deleted file mode 100644 index ed907e577d..0000000000 --- a/src/main/java/io/codearte/accurest/maven/GenerateStubsMojo.java +++ /dev/null @@ -1,45 +0,0 @@ -package io.codearte.accurest.maven; - -import static java.lang.String.format; - -import java.io.File; - -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; - -import io.codearte.accurest.config.AccurestConfigProperties; -import io.codearte.accurest.wiremock.DslToWireMockClientConverter; -import io.codearte.accurest.wiremock.RecursiveFilesConverter; - -@Mojo(name = "generateStubs", defaultPhase = LifecyclePhase.PROCESS_RESOURCES) -public class GenerateStubsMojo extends AbstractMojo { - - @Parameter(defaultValue = "${basedir}", readonly = true, required = true) - private File baseDir; - - @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) - private File projectBuildDirectory; - - @Parameter(defaultValue = "/src/test/accurest") - private String contractsDir; - - @Parameter(defaultValue = "mappings") - private String mappingsDir; - - public void execute() throws MojoExecutionException, MojoFailureException { - AccurestConfigProperties config = new AccurestConfigProperties(); - config.setContractsDslDir(new File(baseDir, contractsDir)); - config.setStubsOutputDir(new File(projectBuildDirectory, mappingsDir)); - - getLog().info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion"); - getLog().info(format("From '%s' to '%s'", config.getContractsDslDir(), config.getStubsOutputDir())); - - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); - converter.processFiles(); - } - -} diff --git a/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java b/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java deleted file mode 100644 index 467e60abe0..0000000000 --- a/src/main/java/io/codearte/accurest/maven/GenerateTestsMojo.java +++ /dev/null @@ -1,78 +0,0 @@ -package io.codearte.accurest.maven; - -import static java.lang.String.format; - -import java.io.File; - -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.LifecyclePhase; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; - -import io.codearte.accurest.AccurestException; -import io.codearte.accurest.TestGenerator; -import io.codearte.accurest.config.AccurestConfigProperties; -import io.codearte.accurest.config.TestFramework; -import io.codearte.accurest.config.TestMode; - -@Mojo(name = "generateTests", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) -public class GenerateTestsMojo extends AbstractMojo { - - @Parameter(defaultValue = "${basedir}", readonly = true, required = true) - private File baseDir; - - @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) - private File projectBuildDirectory; - - @Parameter(defaultValue = "/src/test/accurest") - private String contractsDir; - - @Parameter(defaultValue = "/generated-test-sources/accurest") - private String generatedTestSourcesDir; - - @Parameter(defaultValue = "io.codearte.accurest.tests") - private String basePackageForTests; - - @Parameter - private String baseClassForTests; - - @Parameter(defaultValue = "MOCKMVC") - private TestMode testMode; - - @Parameter(defaultValue = "JUNIT") - private TestFramework testFramework; - - @Parameter - private String ruleClassForTests; - - @Parameter - private String nameSuffixForTests; - - public void execute() throws MojoExecutionException, MojoFailureException { - getLog().info("Generating server tests source code for Accurest contract verification"); - - AccurestConfigProperties config = new AccurestConfigProperties(); - config.setContractsDslDir(new File(baseDir, contractsDir)); - config.setGeneratedTestSourcesDir(new File(projectBuildDirectory, generatedTestSourcesDir)); - config.setTargetFramework(testFramework); - config.setTestMode(testMode); - config.setBasePackageForTests(basePackageForTests); - config.setBaseClassForTests(baseClassForTests); - config.setRuleClassForTests(ruleClassForTests); - config.setNameSuffixForTests(nameSuffixForTests); - - getLog().info(format("Using %s as test source directory", config.getGeneratedTestSourcesDir())); - getLog().info(format("Using %s as base class for test classes", config.getBaseClassForTests())); - - try { - TestGenerator generator = new TestGenerator(config); - int generatedClasses = generator.generate(); - getLog().info(format("Generated %s test classes.", generatedClasses)); - } catch (AccurestException e) { - throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e); - } - } - -} diff --git a/src/main/java/io/codearte/accurest/maven/RunMojo.java b/src/main/java/io/codearte/accurest/maven/RunMojo.java deleted file mode 100644 index 5744ab4170..0000000000 --- a/src/main/java/io/codearte/accurest/maven/RunMojo.java +++ /dev/null @@ -1,68 +0,0 @@ -package io.codearte.accurest.maven; - -import static java.lang.String.format; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import org.apache.maven.plugin.AbstractMojo; -import org.apache.maven.plugin.MojoExecutionException; -import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.Mojo; -import org.apache.maven.plugins.annotations.Parameter; - -import com.github.tomakehurst.wiremock.WireMockServer; -import com.github.tomakehurst.wiremock.common.SingleRootFileSource; -import com.github.tomakehurst.wiremock.core.WireMockConfiguration; -import com.github.tomakehurst.wiremock.standalone.JsonFileMappingsLoader; -import io.codearte.accurest.config.AccurestConfigProperties; - -@Mojo(name = "run", requiresProject = false) -public class RunMojo extends AbstractMojo { - - @Parameter(property = "contractsDir", defaultValue = "${basedir}") - private File contractsDir; - - @Parameter(property = "port", defaultValue = "8089") - private int port; - - public void execute() throws MojoExecutionException, MojoFailureException { - - try { - Path mappingsPath = Files.createTempDirectory("mappings"); - AccurestConfigProperties config = new AccurestConfigProperties(); - config.setContractsDslDir(contractsDir); - config.setStubsOutputDir(mappingsPath.toFile()); - new AccurestConverter().convert(config); - getLog().info( - format(" Accurest contracts directory: %s", config.getContractsDslDir().getAbsolutePath())); - getLog().info( - format("WireMock stubs mappings directory: %s", config.getStubsOutputDir().getAbsolutePath())); - - WireMockServer wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(port)); - wireMockServer.loadMappingsUsing( - new JsonFileMappingsLoader(new SingleRootFileSource(mappingsPath.toFile()))); - wireMockServer.start(); - - pressAnyKeyToContinue(); - getLog().info("Shutting down ..."); - - wireMockServer.stop(); - - } catch (IOException e) { - e.printStackTrace(); - } - - } - - private void pressAnyKeyToContinue() { - getLog().info("Press any key to continue..."); - try { - System.in.read(); - } catch (Exception ignored) { - } - } - -} diff --git a/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.json b/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.json new file mode 100644 index 0000000000..548fb8e723 --- /dev/null +++ b/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.json @@ -0,0 +1,21 @@ +{ + "request" : { + "urlPath" : "/greeting", + "method" : "GET", + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + }, + "queryParameters" : { + "name" : { + "equalTo" : "Something" + } + } + }, + "response" : { + "status" : 200, + "body" : "{\"id\":1,\"content\":\"Hello, Something!\"}" + }, + "priority" : 2 +} \ No newline at end of file diff --git a/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.json b/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.json new file mode 100644 index 0000000000..e014f2ab69 --- /dev/null +++ b/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.json @@ -0,0 +1,16 @@ +{ + "request" : { + "url" : "/greeting", + "method" : "GET", + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 200, + "body" : "{\"id\":1,\"content\":\"Hello, World!\"}" + }, + "priority" : 2 +} \ No newline at end of file From c6f1abc35b82bbed06d6718efc233cc6ad41315a Mon Sep 17 00:00:00 2001 From: Travis CI Date: Wed, 13 Apr 2016 07:21:36 +0000 Subject: [PATCH 459/719] Setting next development version to 0.5.2-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a7efd84bb8..fec9ec8855 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.1-SNAPSHOT + 0.5.2-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin From cbd3362088a12a5d24e19291dfb4fb16466fb745 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 14 Apr 2016 09:24:52 +0200 Subject: [PATCH 460/719] removed coverage information [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 06f7e4c857..9c3f0fbfe3 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![Coverage Status](https://coveralls.io/repos/github/Codearte/accurest-maven-plugin/badge.svg?branch=master)](https://coveralls.io/github/Codearte/accurest-maven-plugin?branch=master) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) +[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) Accurate REST Maven Plugin ==== From 77faffce48b4d821566da8a92f2a2b25bd3fdacb Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 14 Apr 2016 22:46:11 +0200 Subject: [PATCH 461/719] readme about running stubs [ci skip] --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c3f0fbfe3..ccb0b1594c 100644 --- a/README.md +++ b/README.md @@ -16,15 +16,23 @@ For more information please go to the [Accurest Wiki](https://github.com/Codeart -Accurest Runner +Accurest Stub Runner --- +Run contracts from current directory: + mvn io.codearte.accurest:accurest-maven-plugin:run or shortly * mvn accurest:run +Running stubs from repository: + + mvn accurest:run -Dstubs="org.springframework:gs-rest-service" + +where `org.springframework:gs-rest-service` is artifact with 'stubs` classifier contains wiremock mappings. + --- * Additional configuration inside `~/.m2/settings.xml` is required. From c142850aae6db851d5b1567520908ea7db716c3c Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 14 Apr 2016 22:47:01 +0200 Subject: [PATCH 462/719] formatting [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ccb0b1594c..adeaaed9cc 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Running stubs from repository: mvn accurest:run -Dstubs="org.springframework:gs-rest-service" -where `org.springframework:gs-rest-service` is artifact with 'stubs` classifier contains wiremock mappings. +where `org.springframework:gs-rest-service` is artifact with `stubs` classifier contains wiremock mappings. --- From df15d9f4c461ef1164e45ccf88726c334999acf2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Zaj=C4=85czkowski?= Date: Fri, 15 Apr 2016 12:25:23 +0200 Subject: [PATCH 463/719] Upgrade Gradle to 2.12 (#229) --- .../plugin/AccurestIntegrationSpec.groovy | 10 +++++++--- .../plugin/BasicFunctionalSpec.groovy | 3 +-- .../plugin/ScenarioProjectSpec.groovy | 1 - .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- build.gradle | 9 +++++---- gradle/wrapper/gradle-wrapper.jar | Bin 53638 -> 53639 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- 10 files changed, 19 insertions(+), 16 deletions(-) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy index 8454662519..ffcfe16442 100644 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy @@ -1,24 +1,28 @@ package io.codearte.accurest.plugin import nebula.test.IntegrationSpec +import nebula.test.functional.GradleRunner import java.nio.file.Files import java.nio.file.Path -import static java.nio.charset.StandardCharsets.UTF_8 import static java.nio.charset.StandardCharsets.UTF_8 /** * @author Olga Maciaszek-Sharma - @since 23.02.16 + * @since 23.02.16 */ -class AccurestIntegrationSpec extends IntegrationSpec{ +class AccurestIntegrationSpec extends IntegrationSpec { public static final String SPOCK = "targetFramework = 'Spock'" public static final String JUNIT = "targetFramework = 'JUnit'" public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + void setup() { + classpathFilter = GradleRunner.CLASSPATH_ALL //workaround for removing dependant modules by default filter + } + protected void switchToJunitTestFramework() { Path path = buildFile.toPath() String content = new StringBuilder(new String(Files.readAllBytes(path), UTF_8)).replaceAll(SPOCK, JUNIT) 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 a8fd7cc7ef..c9278e5f0b 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 @@ -1,11 +1,10 @@ package io.codearte.accurest.plugin import io.codearte.accurest.util.AssertionUtil -import nebula.test.IntegrationSpec import spock.lang.Stepwise @Stepwise -class BasicFunctionalSpec extends IntegrationSpec { +class BasicFunctionalSpec extends AccurestIntegrationSpec { private static final String GENERATED_TEST = "build//generated-test-sources//accurest//accurest//twitter_places_analyzer//PairIdSpec.groovy" private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.json" diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy index 9fafcc39e7..3b300a3ad7 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy @@ -1,6 +1,5 @@ package io.codearte.accurest.plugin -import nebula.test.IntegrationSpec import spock.lang.Stepwise @Stepwise diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties index 5f8711f6f1..cfa20637e3 100755 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.2.1-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties index b4603dcb69..8b2268d1ba 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties index b4603dcb69..8b2268d1ba 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties index b4603dcb69..8b2268d1ba 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=http\://services.gradle.org/distributions/gradle-2.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.12-bin.zip diff --git a/build.gradle b/build.gradle index aa84447761..b679ef0101 100644 --- a/build.gradle +++ b/build.gradle @@ -61,7 +61,7 @@ subprojects { dependencies { compile localGroovy() - testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } } @@ -98,7 +98,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.3.10' + compile 'org.codehaus.groovy:groovy-all:2.4.4' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') @@ -129,8 +129,9 @@ project(':accurest-gradle-plugin') { dependencies { compile project(':accurest-core') compile project(':accurest-converters') + compile gradleApi() - testCompile('com.netflix.nebula:nebula-test:2.2.1') { + testCompile('com.netflix.nebula:nebula-test:4.0.0') { exclude(group: 'org.spockframework') } testCompile project(':accurest-testing-utils') @@ -151,5 +152,5 @@ project(':accurest-gradle-plugin') { } task wrapper(type: Wrapper) { - gradleVersion = '2.4' + gradleVersion = '2.12' } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5ccda13e9cb94678ba179b32452cf3d60dc36353..2c6137b87896c8f70315ae454e00a969ef5f6019 100644 GIT binary patch delta 1762 zcmY*Z3rv$&6u$inv`UK;1cg>AAP<3I*QyZ#iC_c)5wQ50V{{aR$v}Zv1viU2n4rAw zHXk9|7`Qrh0WIp7z(AnoQJ^@Taf|a2Ky)&#+2S6eyZ^ZaY?J0Y_xrzd&i9{t+M-%+ zaV=LE7tOVri4dQUq%m2QLN7jn$jkc8K9xaR9n3lA91fb6coNBJH!cfCAAsjl7O*ep z9*a6VCYJ%?kktbqvaIWX&^huQY=H5zyG0q^Y^gOcE1W7Q(?4$`4;Zfn8yz6nFBecv z*>WdaV6@@SXF^aDdz%(4Oytq@(oKncK5-G5byoW!9(y<9ji>AU6QoPxr45a;WtU`2 z6gV_lHe()9e0DOx*@W|xJ@zjxZ^`PA3J$4Tqh=RYi36P*^Zepe8K#S-S>rwp3&X39 zuKZ}+>)vk3-r#Ei%4f$sxB9LaS)HujDXe^7zUybEDXb?bcx~Y`;brDnieS8Bhu^@# zi)Z9XTNK{gM>K{StzFB8klihJ?`O`x`sU5gV-}8QjAZ)j*LUVPyIrqWC5`6yt(%p0 z#!9U_neDrDxGwN_=a*k;wk^K$kGyU~?NHyU+9nJB^N}>+YkRTL^G?swiAc@;FTQL~ z`1XawRDG*RRQ%WZ;oFL92X>j6^@g&SuiX}TQM^~_&n2ikt^9;x11wiP1VWPf3J9HB z`a>EBcVG@Ys?C(}A?V7Ja3Of04x)i)!B5t}{HOVsivK=vg9nVMWQa0#N6s>K?2tb` z)i`&%Jwke4EG<}opXS-<4wkF!K|N7prd`c-cWH24d&vqO9X-dT&2arw`l#r_JGAtu zZWYz|es7}8M3aJQ6wR2+XS+6(y0oqhaBl8O1e~L%byfNlIQQyfrgz!Zu=cgJ-DwD62Zb99BF+ccXmEwoxIx5J zE3tII8JmOq(M($4;qUt9gR}lV5%c%} zu0H3E1x8q5>}C`(ohA5AN$}LL4-@M65lHSf${=xqP;1Hw<%16o(kqGY7cu46L2-sK*z`-)^Mgj{S93bIJ-#)}7{ zz{0)(5mR`Mcn_F*_e*UJxyMPrGh_uUZ=|?>s-Jk!o!-izh{?Y|XfYO)&SGB{JckcC zjXol?+ecbkuF)?#sBv@9N5XoObLlMC-@c~YRNFxkX96ALjV35h+ zD2{+Zvr%sKpq9kbB<)Nun7`{umQR(Dsi}T|C`9JO>Vw(zJA~TI_KVuYjpZG z+B8T*o6JW@BtrITb&jc0L_i%~`zkKSYp2zVgy#u7G$%19lCotq1Dz`XUaAwwT(i>w5|IGYWyjL<^G2gcLpdzR^1yh8|#Qoh3q7N^|BtmgcB zn+3p>`n{YFi{dRqY{1k|A!|SPd8kN4s!)f^PcFq{d;J&2YXXB+l|ib?8aGv?n@14# ziEx`o6GiTzhieZ`j&L~To$VXfBp0Vmy}5Wp^hl6PU;14cSf?F4LOr=2!c)lmPR{1u zDu|oX7Zv@Lr+RI)lv?8i#nYqH7K;7@PqaF;TsM|BDF|A<&pCZVYww=A@fnfdZ+xlzjFDU^>CNsOu?nmF*6<(c_Rciezti0&#Gq>uXKk((<6E5o#Z*5wiMSJ#WJQ>MRNPjTyoj+O%YOZ#EY@Y zxE8V(YIpUNlAf;92(9O6CQ~5$Pev)squVHg(uq1!|U1A7>LvfxWxfaC^-+{d|q|wvzPb&IvbN3|`e$ z%T+-d9<_*OKk7`6oR^AY8r5N5$y(?44abxtArU4B*)KrIi(@cgRd)as_f5BiN+~D3 ze)#SWRk(?6uIMXX&PSPF)48_qzEw&>=iDo+C#Q(aQ2$x`Orv#GZ_eiJ# zJv27Z;|K?akyk!5&^N@pf#a28S+5#w2YV&d^gVVS_br&S2D*dL{ Date: Fri, 15 Apr 2016 19:48:55 +0200 Subject: [PATCH 464/719] Fixes #230 Cannot match url with query parameters when both contain regular expressions (#231) --- .../wiremock/WireMockToDslConverter.groovy | 2 + .../dsl/WireMockRequestStubStrategy.groovy | 8 +++- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 41 +++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy index 4107d2dcdf..0a7bfc8bb8 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 @@ -24,12 +24,14 @@ class WireMockToDslConverter { def response = wireMockStub.response def bodyPatterns = request.bodyPatterns String urlPattern = request.urlPattern + String urlPathPattern = request.urlPathPattern return """\ ${priority ? "priority ${priority}" : ''} request { ${request.method ? "method \"\"\"$request.method\"\"\"" : ""} ${request.url ? "url \"\"\"$request.url\"\"\"" : ""} ${urlPattern ? "url \$(client(regex('${escapeJava(urlPattern)}')), server('${new Xeger(escapeJava(urlPattern)).generate()}'))" : ""} + ${urlPathPattern ? "urlPath \$(client(regex('${escapeJava(urlPattern)}')), server('${new Xeger(escapeJava(urlPattern)).generate()}'))" : ""} ${request.urlPath ? "url \"\"\"$request.urlPath\"\"\"" : ""} ${ request.headers ? """headers { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index 1c3bbb6016..e3736d0a7a 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -108,13 +108,17 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { private void appendUrl(RequestPattern requestPattern) { Object urlPath = request?.urlPath?.clientValue if (urlPath) { - requestPattern.setUrlPath(getStubSideValue(urlPath.toString()).toString()) + if(urlPath instanceof Pattern) { + requestPattern.setUrlPathPattern(getStubSideValue(urlPath.toString()).toString()) + } else { + requestPattern.setUrlPath(getStubSideValue(urlPath.toString()).toString()) + } } if(!request.url) { return } Object url = getUrlIfGstring(request?.url?.clientValue) - if(url instanceof Pattern) { + if (url instanceof Pattern) { requestPattern.setUrlPattern(url.pattern()) } else { requestPattern.setUrl(url.toString()) 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 6288301bdb..df097affe8 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 @@ -713,6 +713,47 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie stubMappingIsValidWireMockStub(json) } + @Issue('#230') + def "should generate request with urlPathPattern and queryParameters for client side\ + when both contains regular expressions"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPath($(client(regex("/users/[0-9]+")), server("/users/1"))) { + queryParameters { + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("10")) + } + } + } + response { + status 200 + } + } + when: + def json = toWireMockClientJsonStub(groovyDsl) + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request": { + "method": "GET", + "urlPathPattern": "/users/[0-9]+", + "queryParameters": { + "search": { + "doesNotMatch": "^/[0-9]{2}$" + } + } + }, + "response": { + "status": 200, + } + } + '''), json) + and: + stubMappingIsValidWireMockStub(json) + } + + def "should generate request with urlPath for client side"() { given: GroovyDsl groovyDsl = GroovyDsl.make { From 19b5b120fbcdfba8f5709b9c63c398a700ce3dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Fri, 15 Apr 2016 20:41:02 +0200 Subject: [PATCH 465/719] Allow to run wiremocks stubs from current directory (#4) --- README.md | 2 +- .../io/codearte/accurest/maven/RunMojo.groovy | 3 +-- .../maven/stubrunner/LocalStubRunner.groovy | 13 ++----------- 3 files changed, 4 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index adeaaed9cc..e2a40fc7c6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ For more information please go to the [Accurest Wiki](https://github.com/Codeart Accurest Stub Runner --- -Run contracts from current directory: +Run stubs mappings from current directory: mvn io.codearte.accurest:accurest-maven-plugin:run diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index 5f72edbbdb..82c1b49f8c 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -32,7 +32,6 @@ public class RunMojo extends AbstractMojo { @Parameter(property = 'maxPort', defaultValue = '15000') private int maxPort - private String stubsClassifier = 'stubs' private final LocalStubRunner localStubRunner @@ -48,7 +47,7 @@ public class RunMojo extends AbstractMojo { StubRunnerOptions options = new StubRunnerOptions(minPort, maxPort, "", false, stubsClassifier) log.debug("Launching StubRunner with args: $options") if (!stubs) { - localStubRunner.run(contractsDir, options) + localStubRunner.run(contractsDir.getAbsolutePath(), options) } else { remoteStubRunner.run(stubs, options, repoSession) } diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy index 441a150881..5239b412a6 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy @@ -2,28 +2,19 @@ package io.codearte.accurest.maven.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.maven.AccurestConverter import io.codearte.accurest.stubrunner.StubConfiguration import io.codearte.accurest.stubrunner.StubRunner import io.codearte.accurest.stubrunner.StubRunnerOptions import javax.inject.Named -import java.nio.file.Files - -import static io.codearte.accurest.maven.AccurestConverter.convertAccurestToStubs @Named @CompileStatic @Slf4j class LocalStubRunner { - void run(File contractsDir, StubRunnerOptions options) { + void run(String contractsDir, StubRunnerOptions options) { log.info("Launching StubRunner with contracts from ${contractsDir}") - File mappingsOutput = Files.createTempDirectory('accurest').toFile() - mappingsOutput.deleteOnExit() - AccurestConfigProperties config = new AccurestConfigProperties(contractsDslDir: contractsDir, stubsOutputDir: mappingsOutput) - convertAccurestToStubs(config) - new StubRunner(options, contractsDir.getPath(), new StubConfiguration(mappingsOutput.toString())).runStubs() + new StubRunner(options, contractsDir, new StubConfiguration(contractsDir)).runStubs() } } From e7a0762a45265bf9f144d4a1656638b511bccefa Mon Sep 17 00:00:00 2001 From: Travis CI Date: Fri, 15 Apr 2016 18:46:07 +0000 Subject: [PATCH 466/719] Setting next development version to 0.5.3-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fec9ec8855..5b7b0e9c4f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.2-SNAPSHOT + 0.5.3-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin From ba4765f23b2f4019226fa930f2c34e582c46ee08 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 15 Apr 2016 21:05:58 +0200 Subject: [PATCH 467/719] shorter commit message [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5b7b0e9c4f..fb324903eb 100644 --- a/pom.xml +++ b/pom.xml @@ -424,7 +424,7 @@ connection pom.xml - Setting next development version to + Sets project version to ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT. [ci skip] From 30bb65b47e82daed7fcce94de3ce99e0cd891b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Fri, 15 Apr 2016 23:36:29 +0200 Subject: [PATCH 468/719] replace generateStubs with convert (#5) --- .../accurest/maven/AccurestConverter.groovy | 17 ----- .../accurest/maven/ConvertMojo.groovy | 62 +++++++++++++++---- .../accurest/maven/GenerateStubsMojo.groovy | 39 +++--------- .../accurest/maven/GenerateTestsMojo.groovy | 4 +- .../io/codearte/accurest/maven/RunMojo.groovy | 6 +- .../AetherStubDownloaderFactory.groovy | 4 +- .../io/codearte/accurest/maven/PluginIT.java | 4 +- .../accurest/maven/PluginUnitTest.java | 6 +- src/test/projects/spring-boot-groovy/pom.xml | 4 +- src/test/projects/spring-boot-java/pom.xml | 2 +- 10 files changed, 72 insertions(+), 76 deletions(-) delete mode 100644 src/main/groovy/io/codearte/accurest/maven/AccurestConverter.groovy diff --git a/src/main/groovy/io/codearte/accurest/maven/AccurestConverter.groovy b/src/main/groovy/io/codearte/accurest/maven/AccurestConverter.groovy deleted file mode 100644 index dba4190397..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/AccurestConverter.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package io.codearte.accurest.maven; - -import groovy.transform.CompileStatic; -import groovy.transform.PackageScope; -import io.codearte.accurest.config.AccurestConfigProperties; -import io.codearte.accurest.wiremock.DslToWireMockClientConverter; -import io.codearte.accurest.wiremock.RecursiveFilesConverter; - -@CompileStatic -class AccurestConverter { - - static void convertAccurestToStubs(AccurestConfigProperties config) { - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config) - converter.processFiles() - } - -} diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy index d90cbc7133..662911053e 100644 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -2,35 +2,71 @@ package io.codearte.accurest.maven import groovy.transform.CompileStatic import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.wiremock.DslToWireMockClientConverter +import io.codearte.accurest.wiremock.RecursiveFilesConverter +import org.apache.maven.execution.MavenSession +import org.apache.maven.model.path.PathTranslator import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.plugins.annotations.Component +import org.apache.maven.plugins.annotations.LifecyclePhase import org.apache.maven.plugins.annotations.Mojo import org.apache.maven.plugins.annotations.Parameter -import static io.codearte.accurest.maven.AccurestConverter.convertAccurestToStubs +import javax.inject.Inject -@Mojo(name = 'convert', requiresProject = false) +@Mojo(name = 'convert', requiresProject = false, defaultPhase = LifecyclePhase.PROCESS_RESOURCES) @CompileStatic -public class ConvertMojo extends AbstractMojo { +class ConvertMojo extends AbstractMojo { - @Parameter(property = 'contractsDir', defaultValue = '${basedir}') - private File contractsDir + @Parameter(defaultValue = '${basedir}', readonly = true, required = true) + private File baseDir - @Parameter(property = 'mappingsDir', defaultValue = '${basedir}') - private File mappingsDir + @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) + private File projectBuildDirectory - public void execute() throws MojoExecutionException, MojoFailureException { + @Parameter(property = 'contractsDir') + private String contractsDir + + @Parameter(property = 'mappingsDir') + private String mappingsDir + + @Component + private MavenSession mavenSession + + private final PathTranslator translator + + @Inject + ConvertMojo(PathTranslator translator) { + this.translator = translator + } + + void execute() throws MojoExecutionException, MojoFailureException { AccurestConfigProperties config = new AccurestConfigProperties() - config.contractsDslDir = contractsDir - config.stubsOutputDir = mappingsDir + + config.contractsDslDir = resolveFile(baseDir, contractsDir, isInsideProject() ? 'src/test/accurest' : '') + config.stubsOutputDir = resolveFile(projectBuildDirectory, mappingsDir, isInsideProject() ? 'mappings' : '') log.info('Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings') - log.info(" Accurest contracts directory: ${config.contractsDslDir.absolutePath}") - log.info("WireMock stubs mappings directory: ${config.stubsOutputDir.absolutePath}") + log.info(" Accurest contracts directory: ${config.contractsDslDir}") + log.info("WireMock stubs mappings directory: ${config.stubsOutputDir}") - convertAccurestToStubs(config) + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config) + converter.processFiles() + } + + private boolean isInsideProject() { + mavenSession.getRequest().isProjectPresent() + } + + private File resolveFile(File baseDir, String requestedPath, String defaultPath) { + requestedPath ? alignToBaseDirectory(requestedPath, baseDir) : alignToBaseDirectory(defaultPath, baseDir) + } + + private File alignToBaseDirectory(String dir1, File dir) { + return new File(translator.alignToBaseDirectory(dir1, dir)) } } diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy index 82ec235e0f..165dc96663 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy @@ -1,42 +1,19 @@ package io.codearte.accurest.maven import groovy.transform.CompileStatic -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.wiremock.DslToWireMockClientConverter -import io.codearte.accurest.wiremock.RecursiveFilesConverter -import org.apache.maven.plugin.AbstractMojo -import org.apache.maven.plugin.MojoExecutionException -import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.model.path.PathTranslator import org.apache.maven.plugins.annotations.LifecyclePhase import org.apache.maven.plugins.annotations.Mojo -import org.apache.maven.plugins.annotations.Parameter + +import javax.inject.Inject @Mojo(name = 'generateStubs', defaultPhase = LifecyclePhase.PROCESS_RESOURCES) @CompileStatic -public class GenerateStubsMojo extends AbstractMojo { +@Deprecated +class GenerateStubsMojo extends ConvertMojo { - @Parameter(defaultValue = '${basedir}', readonly = true, required = true) - private File baseDir - - @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) - private File projectBuildDirectory - - @Parameter(defaultValue = '/src/test/accurest') - private String contractsDir - - @Parameter(defaultValue = 'mappings') - private String mappingsDir - - public void execute() throws MojoExecutionException, MojoFailureException { - AccurestConfigProperties config = new AccurestConfigProperties() - config.contractsDslDir = new File(baseDir, contractsDir) - config.stubsOutputDir = new File(projectBuildDirectory, mappingsDir) - - log.info('Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion') - log.info("From '${config.contractsDslDir}' to '${config.stubsOutputDir}'") - - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config) - converter.processFiles() + @Inject + GenerateStubsMojo(PathTranslator translator) { + super(translator) } - } diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy index 1f642b109b..f13814382c 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy @@ -17,7 +17,7 @@ import static java.lang.String.format @Mojo(name = 'generateTests', defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) @CompileStatic -public class GenerateTestsMojo extends AbstractMojo { +class GenerateTestsMojo extends AbstractMojo { @Parameter(defaultValue = '${basedir}', readonly = true, required = true) private File baseDir @@ -49,7 +49,7 @@ public class GenerateTestsMojo extends AbstractMojo { @Parameter private String nameSuffixForTests - public void execute() throws MojoExecutionException, MojoFailureException { + void execute() throws MojoExecutionException, MojoFailureException { log.info('Generating server tests source code for Accurest contract verification') AccurestConfigProperties config = new AccurestConfigProperties() diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index 82c1b49f8c..9a0e7b539a 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -15,7 +15,7 @@ import javax.inject.Inject @Mojo(name = 'run', requiresProject = false) @CompileStatic -public class RunMojo extends AbstractMojo { +class RunMojo extends AbstractMojo { @Parameter(defaultValue = '${repositorySystemSession}', readonly = true) private RepositorySystemSession repoSession @@ -38,12 +38,12 @@ public class RunMojo extends AbstractMojo { private final RemoteStubRunner remoteStubRunner @Inject - public RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner) { + RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner) { this.localStubRunner = localStubRunner this.remoteStubRunner = remoteStubRunner } - public void execute() throws MojoExecutionException, MojoFailureException { + void execute() throws MojoExecutionException, MojoFailureException { StubRunnerOptions options = new StubRunnerOptions(minPort, maxPort, "", false, stubsClassifier) log.debug("Launching StubRunner with args: $options") if (!stubs) { diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy index 241b9a6cac..63f9e5bef0 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy @@ -14,13 +14,13 @@ import javax.inject.Singleton @Singleton @CompileStatic @Slf4j -public class AetherStubDownloaderFactory { +class AetherStubDownloaderFactory { private final MavenProject project private final RepositorySystem repoSystem @Inject - public AetherStubDownloaderFactory(RepositorySystem repoSystem, MavenProject project) { + AetherStubDownloaderFactory(RepositorySystem repoSystem, MavenProject project) { this.repoSystem = repoSystem this.project = project } diff --git a/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/io/codearte/accurest/maven/PluginIT.java index a13dcc4257..6dd0080e4c 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIT.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIT.java @@ -35,7 +35,7 @@ public class PluginIT { .assertErrorFreeLog() .assertLogText("Generating server tests source code for Accurest contract verification") .assertLogText("Generated 1 test classes.") - .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") + .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") .assertLogText("Creating new json") .assertErrorFreeLog(); } @@ -48,7 +48,7 @@ public class PluginIT { .assertErrorFreeLog() .assertLogText("Generating server tests source code for Accurest contract verification") .assertLogText("Generated 1 test classes.") - .assertLogText("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") + .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") .assertLogText("Creating new json") .assertErrorFreeLog(); } diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 35ebfc472a..1a82b32990 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -22,21 +22,21 @@ public class PluginUnitTest { @Test public void shouldGenerateWireMockStubsInDefaultLocation() throws Exception { File basedir = resources.getBasedir("basic"); - maven.executeMojo(basedir, "generateStubs"); + maven.executeMojo(basedir, "convert"); assertFilesPresent(basedir, "target/mappings/Sample.json"); } @Test public void shouldGenerateWireMockFromStubsDirectory() throws Exception { File basedir = resources.getBasedir("withStubs"); - maven.executeMojo(basedir, "generateStubs", newParameter("contractsDir", "/src/test/resources/stubs")); + maven.executeMojo(basedir, "convert", newParameter("contractsDir", "src/test/resources/stubs")); assertFilesPresent(basedir, "target/mappings/Sample.json"); } @Test public void shouldGenerateWireMockStubsInSelectedLocation() throws Exception { File basedir = resources.getBasedir("basic"); - maven.executeMojo(basedir, "generateStubs", newParameter("mappingsDir", "foo")); + maven.executeMojo(basedir, "convert", newParameter("mappingsDir", "foo")); assertFilesPresent(basedir, "target/foo/Sample.json"); } diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index 12ba2e0d33..66077131b8 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -86,14 +86,14 @@ - generateStubs + convert generateTests com.ofg.twitter.place.BaseMockMvcTest - /src/test/resources/stubs + src/test/resources/stubs SPOCK Test diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index 7ca7455ae5..56ec273c19 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -75,7 +75,7 @@ - generateStubs + convert generateTests From facad58b012b393b9c077ba377d1d71011aeff91 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Fri, 15 Apr 2016 21:41:34 +0000 Subject: [PATCH 469/719] Sets project version to 0.5.4-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fb324903eb..141625014c 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.3-SNAPSHOT + 0.5.4-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin From 6a7f9deece08a8776064530063d6a18d3333eeff Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 16 Apr 2016 08:17:40 +0200 Subject: [PATCH 470/719] Release version: 1.0.6 [ci skip] From e119bb8b1e8fca07878e68d1797190880c23af63 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 16 Apr 2016 08:17:40 +0200 Subject: [PATCH 471/719] Release version: 1.0.6 [ci skip] From e70c0c3a3b7cd6e57d4800524e7c7a952b8f08a5 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 16 Apr 2016 08:17:40 +0200 Subject: [PATCH 472/719] Release version: 1.0.6 [ci skip] From fda80cfa777c519a813f4e5bb08b7753d683e289 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 16 Apr 2016 09:45:55 +0200 Subject: [PATCH 473/719] cleanup [ci skip] --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index e2a40fc7c6..8f60b5171c 100644 --- a/README.md +++ b/README.md @@ -39,9 +39,11 @@ where `org.springframework:gs-rest-service` is artifact with `stubs` classifier ```xml + ... io.codearte.accurest + ... ``` From df9384042665f7f56165822681cf54f709c3b15b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sat, 16 Apr 2016 10:10:09 +0200 Subject: [PATCH 474/719] Update accurest to 1.0.6 (#6) [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 141625014c..b744556018 100644 --- a/pom.xml +++ b/pom.xml @@ -29,7 +29,7 @@ 3.4 UTF-8 - 1.0.5 + 1.0.6 1.1.0 From 10f888449ddd16b1af828425ea3ebd17d0c9ab4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sat, 16 Apr 2016 10:26:08 +0200 Subject: [PATCH 475/719] Fix issue with conversion without pom (#7) --- .../codearte/accurest/maven/ConvertMojo.groovy | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy index 662911053e..e1bbe75a00 100644 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -46,8 +46,13 @@ class ConvertMojo extends AbstractMojo { AccurestConfigProperties config = new AccurestConfigProperties() - config.contractsDslDir = resolveFile(baseDir, contractsDir, isInsideProject() ? 'src/test/accurest' : '') - config.stubsOutputDir = resolveFile(projectBuildDirectory, mappingsDir, isInsideProject() ? 'mappings' : '') + if (insideProject) { + config.contractsDslDir = resolveFile(baseDir, contractsDir, 'src/test/accurest') + config.stubsOutputDir = resolveFile(projectBuildDirectory, mappingsDir, 'mappings') + } else { + config.contractsDslDir = resolveFile(baseDir, contractsDir, '') + config.stubsOutputDir = resolveFile(baseDir, mappingsDir, '') + } log.info('Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings') log.info(" Accurest contracts directory: ${config.contractsDslDir}") @@ -58,15 +63,15 @@ class ConvertMojo extends AbstractMojo { } private boolean isInsideProject() { - mavenSession.getRequest().isProjectPresent() + return mavenSession.getRequest().isProjectPresent() } private File resolveFile(File baseDir, String requestedPath, String defaultPath) { - requestedPath ? alignToBaseDirectory(requestedPath, baseDir) : alignToBaseDirectory(defaultPath, baseDir) + return requestedPath ? alignToBaseDirectory(baseDir, requestedPath) : alignToBaseDirectory(baseDir, defaultPath) } - private File alignToBaseDirectory(String dir1, File dir) { - return new File(translator.alignToBaseDirectory(dir1, dir)) + private File alignToBaseDirectory(File baseDir, String path) { + return new File(translator.alignToBaseDirectory(path, baseDir)) } } From e919900f5e5b8826a1619a071231b969ec14b3df Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sat, 16 Apr 2016 08:31:40 +0000 Subject: [PATCH 476/719] Sets project version to 0.5.5-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b744556018..87f0566356 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.4-SNAPSHOT + 0.5.5-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin From 79155bfde290a78a8c25f97c682aa865cda305e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sat, 16 Apr 2016 16:27:57 +0200 Subject: [PATCH 477/719] simplify min max port usage (#233) --- .../accurest/stubrunner/AvailablePortScanner.groovy | 6 +++--- .../stubrunner/AvailablePortScannerSpec.groovy | 13 +++++++++++-- .../stubrunner/StubRunnerExecutorSpec.groovy | 2 +- .../accurest/stubrunner/StubRunnerSpec.groovy | 2 +- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy index 3b2df9f9b5..db17ee7baa 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy @@ -26,7 +26,7 @@ class AvailablePortScanner { } private void checkPortRanges(int minPortNumber, int maxPortNumber) { - if (minPortNumber >= maxPortNumber) { + if (minPortNumber > maxPortNumber) { throw new InvalidPortRange(minPortNumber, maxPortNumber) } } @@ -34,7 +34,7 @@ class AvailablePortScanner { public T tryToExecuteWithFreePort(Closure closure) { for (i in (1..maxRetryCount)) { try { - int numberOfPortsToBind = maxPortNumber - minPortNumber + int numberOfPortsToBind = maxPortNumber - minPortNumber + 1 int portToScan = new Random().nextInt(numberOfPortsToBind) + minPortNumber checkIfPortIsAvailable(portToScan) return executeLogicForAvailablePort(portToScan, closure) @@ -67,7 +67,7 @@ class AvailablePortScanner { static class InvalidPortRange extends RuntimeException { protected InvalidPortRange(int lowerBound, int upperBound) { - super("Invalid bounds exceptions, min port [$lowerBound] is greater or equal to max port [$upperBound]") + super("Invalid bounds exceptions, min port [$lowerBound] is greater to max port [$upperBound]") } } } diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy index 7e7aee8b69..609e746e66 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy @@ -15,6 +15,16 @@ class AvailablePortScannerSpec extends Specification { int usedPort = portScanner.tryToExecuteWithFreePort { int port -> port } then: noExceptionThrown() + usedPort == MIN_PORT || MAX_PORT + } + + def 'should execute given closure with the available port from specified range'() { + given: + AvailablePortScanner portScanner = new AvailablePortScanner(MIN_PORT, MIN_PORT) + when: + int usedPort = portScanner.tryToExecuteWithFreePort { int port -> port } + then: + noExceptionThrown() usedPort == MIN_PORT } @@ -23,10 +33,9 @@ class AvailablePortScannerSpec extends Specification { new AvailablePortScanner(minPort, maxPort, MAX_RETRY_COUNT_FOR_NEGATIVE_SCENARIOS) then: def ex = thrown(AvailablePortScanner.InvalidPortRange) - ex.message == "Invalid bounds exceptions, min port [$minPort] is greater or equal to max port [$maxPort]" + ex.message == "Invalid bounds exceptions, min port [$minPort] is greater to max port [$maxPort]" where: minPort | maxPort - MIN_PORT | MIN_PORT MAX_PORT | MIN_PORT } diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy index ce378588a5..8548ea38c4 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy @@ -6,7 +6,7 @@ class StubRunnerExecutorSpec extends Specification { static final URL EXPECTED_STUB_URL = new URL('http://localhost:8999') static final int MIN_PORT = 8999 - static final int MAX_PORT = 9000 + static final int MAX_PORT = 8999 private AvailablePortScanner portScanner private StubRepository repository diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy index 1d63e28bfd..6735785f70 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy @@ -5,7 +5,7 @@ import spock.lang.Specification class StubRunnerSpec extends Specification { private static final int MIN_PORT = 8111 - private static final int MAX_PORT = 8112 + private static final int MAX_PORT = 8111 private static final URL EXPECTED_STUB_URL = new URL("http://localhost:$MIN_PORT") def 'should provide stub URL for provided groupid and artifactId'() { From 69f907d69e3040772eedee91201d96e4d2439a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Zaj=C4=85czkowski?= Date: Sat, 16 Apr 2016 16:04:07 +0200 Subject: [PATCH 478/719] Enhance issue badge To show only Maven related issues. [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8f60b5171c..1bc16356cc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) +[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest/maven.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) Accurate REST Maven Plugin ==== From 66fadd100b6a083686a932975ad78399a81bcf00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sat, 16 Apr 2016 19:11:58 +0200 Subject: [PATCH 479/719] Feature/simplify and clean (#9) * parameters refactor, added skip * port * cleanup --- .../accurest/maven/ConvertMojo.groovy | 28 +++++--- .../accurest/maven/GenerateTestsMojo.groovy | 48 ++++++++----- .../io/codearte/accurest/maven/RunMojo.groovy | 70 ++++++++++++++++--- .../stubrunner/AetherStubDownloader.groovy | 4 +- .../AetherStubDownloaderFactory.groovy | 2 +- .../maven/stubrunner/RemoteStubRunner.groovy | 2 +- .../accurest/maven/PluginUnitTest.java | 4 +- src/test/projects/spring-boot-groovy/pom.xml | 34 ++------- src/test/projects/spring-boot-java/pom.xml | 42 ++++------- 9 files changed, 131 insertions(+), 103 deletions(-) diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy index e1bbe75a00..547198b9c9 100644 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -21,16 +21,19 @@ import javax.inject.Inject class ConvertMojo extends AbstractMojo { @Parameter(defaultValue = '${basedir}', readonly = true, required = true) - private File baseDir + private File basedir @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) private File projectBuildDirectory - @Parameter(property = 'contractsDir') - private String contractsDir + @Parameter(property = 'contractsDirectory') + private String contractsDirectory - @Parameter(property = 'mappingsDir') - private String mappingsDir + @Parameter(property = 'stubsDirectory') + private String outputDirectory + + @Parameter(property = 'accurest.skip', defaultValue = 'false') + private boolean skip @Component private MavenSession mavenSession @@ -44,14 +47,19 @@ class ConvertMojo extends AbstractMojo { void execute() throws MojoExecutionException, MojoFailureException { + if (skip) { + log.info("Skipping accurest execution: accurest.skip=${skip}") + return + } + AccurestConfigProperties config = new AccurestConfigProperties() if (insideProject) { - config.contractsDslDir = resolveFile(baseDir, contractsDir, 'src/test/accurest') - config.stubsOutputDir = resolveFile(projectBuildDirectory, mappingsDir, 'mappings') + config.contractsDslDir = resolveFile(basedir, contractsDirectory, 'src/test/accurest') + config.stubsOutputDir = resolveFile(projectBuildDirectory, outputDirectory, 'mappings') } else { - config.contractsDslDir = resolveFile(baseDir, contractsDir, '') - config.stubsOutputDir = resolveFile(baseDir, mappingsDir, '') + config.contractsDslDir = resolveFile(basedir, contractsDirectory, '') + config.stubsOutputDir = resolveFile(basedir, outputDirectory, '') } log.info('Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings') @@ -63,7 +71,7 @@ class ConvertMojo extends AbstractMojo { } private boolean isInsideProject() { - return mavenSession.getRequest().isProjectPresent() + return mavenSession.request.projectPresent } private File resolveFile(File baseDir, String requestedPath, String defaultPath) { diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy index f13814382c..14478e96c9 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy @@ -9,27 +9,20 @@ import io.codearte.accurest.config.TestMode import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.LifecyclePhase -import org.apache.maven.plugins.annotations.Mojo -import org.apache.maven.plugins.annotations.Parameter +import org.apache.maven.plugins.annotations.* +import org.apache.maven.project.MavenProject import static java.lang.String.format -@Mojo(name = 'generateTests', defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES) +@Mojo(name = 'generateTests', defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES, requiresDependencyResolution = ResolutionScope.TEST) @CompileStatic class GenerateTestsMojo extends AbstractMojo { - @Parameter(defaultValue = '${basedir}', readonly = true, required = true) - private File baseDir + @Parameter(property = 'accurest.contractsDirectory', defaultValue = '${project.basedir}/src/test/accurest') + private File contractsDirectory - @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) - private File projectBuildDirectory - - @Parameter(defaultValue = '/src/test/accurest') - private String contractsDir - - @Parameter(defaultValue = '/generated-test-sources/accurest') - private String generatedTestSourcesDir + @Parameter(defaultValue = '${project.build.directory}/generated-test-sources/accurest') + private File generatedTestSourcesDir @Parameter(defaultValue = 'io.codearte.accurest.tests') private String basePackageForTests @@ -49,12 +42,24 @@ class GenerateTestsMojo extends AbstractMojo { @Parameter private String nameSuffixForTests + @Component + private MavenProject project + + @Parameter(property = 'accurest.skip', defaultValue = 'false') + private boolean skip + void execute() throws MojoExecutionException, MojoFailureException { + + if (skip) { + log.info("Skipping accurest execution: accurest.skip=${skip}") + return + } + log.info('Generating server tests source code for Accurest contract verification') AccurestConfigProperties config = new AccurestConfigProperties() - config.contractsDslDir = new File(baseDir, contractsDir) - config.generatedTestSourcesDir = new File(projectBuildDirectory, generatedTestSourcesDir) + config.contractsDslDir = contractsDirectory + config.generatedTestSourcesDir = generatedTestSourcesDir config.targetFramework = testFramework config.testMode = testMode config.basePackageForTests = basePackageForTests @@ -62,16 +67,21 @@ class GenerateTestsMojo extends AbstractMojo { config.ruleClassForTests = ruleClassForTests config.nameSuffixForTests = nameSuffixForTests - log.info("Using ${config.generatedTestSourcesDir} as test source directory") - log.info("Using ${config.baseClassForTests} as base class for test classes") + project.addTestCompileSourceRoot(generatedTestSourcesDir.absolutePath) + + if (log.isInfoEnabled()) { + log.info("Test Source directory: $generatedTestSourcesDir added."); + log.info("Using ${config.baseClassForTests} as base class for test classes") + } try { TestGenerator generator = new TestGenerator(config) int generatedClasses = generator.generate() log.info("Generated $generatedClasses test classes.") } catch (AccurestException e) { - throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.getMessage()), e) + throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.message), e) } + } } diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index 9a0e7b539a..abacda2d43 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -4,9 +4,12 @@ import groovy.transform.CompileStatic import io.codearte.accurest.maven.stubrunner.LocalStubRunner import io.codearte.accurest.maven.stubrunner.RemoteStubRunner import io.codearte.accurest.stubrunner.StubRunnerOptions +import org.apache.maven.execution.MavenSession +import org.apache.maven.model.path.PathTranslator import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.plugins.annotations.Component import org.apache.maven.plugins.annotations.Mojo import org.apache.maven.plugins.annotations.Parameter import org.eclipse.aether.RepositorySystemSession @@ -17,41 +20,75 @@ import javax.inject.Inject @CompileStatic class RunMojo extends AbstractMojo { + @Parameter(defaultValue = '${basedir}', readonly = true, required = true) + private File basedir + + @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) + private File projectBuildDirectory + @Parameter(defaultValue = '${repositorySystemSession}', readonly = true) private RepositorySystemSession repoSession - @Parameter(property = 'contractsDir', defaultValue = '${basedir}') - private File contractsDir + @Parameter(property = 'stubsDirectory', defaultValue = '${basedir}') + private String stubsDirectory - @Parameter(property = 'stubs') + @Parameter(property = 'accurest.http.port', defaultValue = '8080') + private int httpPort; + + @Parameter(property = 'accurest.skip', defaultValue = 'false') + private boolean skip + + @Parameter(property = 'accurest.stubs') private String stubs - @Parameter(property = 'minPort', defaultValue = '10000') + @Parameter(property = 'accurest.http.minPort', defaultValue = '10000') private int minPort - @Parameter(property = 'maxPort', defaultValue = '15000') + @Parameter(property = 'accurest.http.maxPort', defaultValue = '15000') private int maxPort private String stubsClassifier = 'stubs' + @Component + private MavenSession mavenSession + private final LocalStubRunner localStubRunner private final RemoteStubRunner remoteStubRunner + private final PathTranslator translator @Inject - RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner) { + RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner, PathTranslator translator) { this.localStubRunner = localStubRunner this.remoteStubRunner = remoteStubRunner + this.translator = translator } void execute() throws MojoExecutionException, MojoFailureException { - StubRunnerOptions options = new StubRunnerOptions(minPort, maxPort, "", false, stubsClassifier) - log.debug("Launching StubRunner with args: $options") + + if (skip) { + log.info("Skipping accurest execution: accurest.skip=${skip}") + return + } + if (!stubs) { - localStubRunner.run(contractsDir.getAbsolutePath(), options) + StubRunnerOptions options = new StubRunnerOptions(httpPort, httpPort + 1, "", false, stubsClassifier) + localStubRunner.run(resolveStubsDirectory().absolutePath, options) } else { + StubRunnerOptions options = new StubRunnerOptions(minPort, maxPort, "", false, stubsClassifier) remoteStubRunner.run(stubs, options, repoSession) } - pressAnyKeyToContinue() + + if (!insideProject) { + pressAnyKeyToContinue() + } + } + + private File resolveStubsDirectory() { + if (insideProject) { + return resolveFile(projectBuildDirectory, stubsDirectory, 'mappings') + } else { + return resolveFile(basedir, stubsDirectory, '') + } } private void pressAnyKeyToContinue() { @@ -62,4 +99,17 @@ class RunMojo extends AbstractMojo { } } + private boolean isInsideProject() { + return mavenSession.request.projectPresent + } + + private File resolveFile(File baseDir, String requestedPath, String defaultPath) { + return requestedPath ? alignToBaseDirectory(baseDir, requestedPath) : alignToBaseDirectory(baseDir, defaultPath) + } + + private File alignToBaseDirectory(File baseDir, String path) { + return new File(translator.alignToBaseDirectory(path, baseDir)) + } + + } diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy index 11fa13a111..82b0471923 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy @@ -40,8 +40,8 @@ class AetherStubDownloader implements StubDownloader { ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos) log.info("Resolving artifact $artifact from $remoteRepos") ArtifactResult result = repoSystem.resolveArtifact(repoSession, request) - log.info("Resolved artifact $artifact to ${result.getArtifact().getFile()} from ${result.getRepository()}") - return unpackStubJarToATemporaryFolder(result.getArtifact().getFile().toURI()) + log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}") + return unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) } private static File unpackStubJarToATemporaryFolder(URI stubJarUri) { diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy index 63f9e5bef0..10fa5461e8 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy @@ -26,7 +26,7 @@ class AetherStubDownloaderFactory { } AetherStubDownloader build(RepositorySystemSession repoSession) { - return new AetherStubDownloader(repoSystem, project.getRemoteProjectRepositories(), repoSession) + return new AetherStubDownloader(repoSystem, project.remoteProjectRepositories, repoSession) } } diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy index eceb17b032..ca37885758 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy @@ -31,7 +31,7 @@ class RemoteStubRunner { RunningStubs runningCollaborators = stubRunner.runStubs() log.info(runningCollaborators.toString()) } catch (Exception e) { - log.error("An exception occurred while trying to execute the stubs: ${e.getMessage()}") + log.error("An exception occurred while trying to execute the stubs: ${e.message}") throw e } } diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 1a82b32990..5b7e11f812 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -29,14 +29,14 @@ public class PluginUnitTest { @Test public void shouldGenerateWireMockFromStubsDirectory() throws Exception { File basedir = resources.getBasedir("withStubs"); - maven.executeMojo(basedir, "convert", newParameter("contractsDir", "src/test/resources/stubs")); + maven.executeMojo(basedir, "convert", newParameter("contractsDirectory", "src/test/resources/stubs")); assertFilesPresent(basedir, "target/mappings/Sample.json"); } @Test public void shouldGenerateWireMockStubsInSelectedLocation() throws Exception { File basedir = resources.getBasedir("basic"); - maven.executeMojo(basedir, "convert", newParameter("mappingsDir", "foo")); + maven.executeMojo(basedir, "convert", newParameter("outputDirectory", "foo")); assertFilesPresent(basedir, "target/foo/Sample.json"); } diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index 66077131b8..6562e9634a 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -40,36 +40,30 @@ groovy-all - + org.spockframework spock-core 1.0-groovy-2.4 + test com.jayway.restassured rest-assured 2.9.0 + test com.jayway.restassured spring-mock-mvc 2.9.0 - - - com.github.tomakehurst - wiremock - 2.0.10-beta + test com.toomuchcoding.jsonassert jsonassert 0.3.0 - - - org.assertj - assertj-core - 2.3.0 + test @@ -93,7 +87,7 @@ com.ofg.twitter.place.BaseMockMvcTest - src/test/resources/stubs + src/test/resources/stubs SPOCK Test @@ -111,22 +105,6 @@ - - - - ${project.basedir}/src/test/groovy - - **/*.groovy - - - - ${project.build.directory}/generated-test-sources/accurest - - **/*.groovy - - - - - - org.spockframework - spock-core - 1.0-groovy-2.4 - + com.jayway.restassured rest-assured 2.9.0 + test com.jayway.restassured spring-mock-mvc 2.9.0 - - - com.github.tomakehurst - wiremock - 2.0.10-beta + test com.toomuchcoding.jsonassert jsonassert 0.3.0 + test org.assertj assertj-core 2.3.0 + test + + + junit + junit + 4.12 + test @@ -109,25 +109,7 @@ - - org.codehaus.mojo - build-helper-maven-plugin - 1.10 - - - add-accurest-test-sources - generate-test-sources - - add-test-source - - - - ${project.build.directory}/generated-test-sources/accurest - - - - - + From ace432e2c24ff7acaf28ffa5ab4c64bc5240f68c Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sat, 16 Apr 2016 17:16:42 +0000 Subject: [PATCH 480/719] Sets project version to 0.5.6-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 87f0566356..861223fbab 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.5-SNAPSHOT + 0.5.6-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin From 879c30aba1b057d15f0ebe7927189f41bfacb336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sat, 16 Apr 2016 21:28:53 +0200 Subject: [PATCH 481/719] Feature/create stubs (#10) * removed warnings and simplified * automate stub generation --- pom.xml | 11 ++++ .../accurest/maven/ConvertMojo.groovy | 5 +- .../accurest/maven/GenerateStubsMojo.groovy | 66 ++++++++++++++++--- .../accurest/maven/GenerateTestsMojo.groovy | 7 +- .../io/codearte/accurest/maven/RunMojo.groovy | 3 +- src/test/projects/spring-boot-groovy/pom.xml | 25 +------ src/test/projects/spring-boot-java/pom.xml | 39 ++--------- 7 files changed, 83 insertions(+), 73 deletions(-) diff --git a/pom.xml b/pom.xml index 861223fbab..fd3b43a361 100644 --- a/pom.xml +++ b/pom.xml @@ -282,6 +282,17 @@ provided + + org.apache.maven + maven-archiver + 3.0.0 + + + org.codehaus.plexus + plexus-archiver + 3.1 + + io.takari.maven.plugins takari-plugin-testing diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy index 547198b9c9..af0f7d5944 100644 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -9,14 +9,13 @@ import org.apache.maven.model.path.PathTranslator import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.Component import org.apache.maven.plugins.annotations.LifecyclePhase import org.apache.maven.plugins.annotations.Mojo import org.apache.maven.plugins.annotations.Parameter import javax.inject.Inject -@Mojo(name = 'convert', requiresProject = false, defaultPhase = LifecyclePhase.PROCESS_RESOURCES) +@Mojo(name = 'convert', requiresProject = false, defaultPhase = LifecyclePhase.PROCESS_TEST_RESOURCES) @CompileStatic class ConvertMojo extends AbstractMojo { @@ -35,7 +34,7 @@ class ConvertMojo extends AbstractMojo { @Parameter(property = 'accurest.skip', defaultValue = 'false') private boolean skip - @Component + @Parameter(defaultValue = '${session}', readonly = true) private MavenSession mavenSession private final PathTranslator translator diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy index 165dc96663..ea75877350 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy @@ -1,19 +1,67 @@ package io.codearte.accurest.maven import groovy.transform.CompileStatic -import org.apache.maven.model.path.PathTranslator +import org.apache.maven.plugin.AbstractMojo +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.plugins.annotations.Component import org.apache.maven.plugins.annotations.LifecyclePhase import org.apache.maven.plugins.annotations.Mojo +import org.apache.maven.plugins.annotations.Parameter +import org.apache.maven.project.MavenProject +import org.apache.maven.project.MavenProjectHelper +import org.codehaus.plexus.archiver.Archiver +import org.codehaus.plexus.archiver.jar.JarArchiver -import javax.inject.Inject - -@Mojo(name = 'generateStubs', defaultPhase = LifecyclePhase.PROCESS_RESOURCES) +@Mojo(name = 'generateStubs', defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true) @CompileStatic -@Deprecated -class GenerateStubsMojo extends ConvertMojo { +class GenerateStubsMojo extends AbstractMojo { - @Inject - GenerateStubsMojo(PathTranslator translator) { - super(translator) + @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) + private File projectBuildDirectory + + @Parameter(property = 'stubsDirectory', defaultValue = '${project.build.directory}/mappings') + private File outputDirectory + + @Parameter(property = 'accurest.skip', defaultValue = 'false') + private boolean skip + + @Component + private MavenProjectHelper projectHelper; + + @Parameter(defaultValue = '${project}', readonly = true) + private MavenProject project + + @Component(role = Archiver.class, hint = "jar") + private JarArchiver jarArchiver; + + void execute() throws MojoExecutionException, MojoFailureException { + + if (skip) { + log.info("Skipping accurest execution: accurest.skip=${skip}") + return + } + + File stubJarFile = createStubJar(outputDirectory) + projectHelper.attachArtifact(project, 'jar', 'stubs', stubJarFile) } + + private File createStubJar(File stubsOutputDir) { + if (!stubsOutputDir.exists()) { + throw new MojoExecutionException("Stubs could not be found: $stubsOutputDir.\nPlease make sure that accurest:convert was invoked"); + } + String stubArchiveName = project.getBuild().getFinalName() + "-stubs.jar"; + File stubJarFile = new File(projectBuildDirectory, stubArchiveName); + + try { + jarArchiver.addDirectory(stubsOutputDir); + jarArchiver.setCompress(true); + jarArchiver.setDestFile(stubJarFile); + jarArchiver.createArchive(); + } catch (Exception e) { + throw new MojoFailureException('Exception while packaging.', e); + } + return stubJarFile + } + } diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy index 14478e96c9..cef5361d73 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy @@ -9,7 +9,10 @@ import io.codearte.accurest.config.TestMode import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.* +import org.apache.maven.plugins.annotations.LifecyclePhase +import org.apache.maven.plugins.annotations.Mojo +import org.apache.maven.plugins.annotations.Parameter +import org.apache.maven.plugins.annotations.ResolutionScope import org.apache.maven.project.MavenProject import static java.lang.String.format @@ -42,7 +45,7 @@ class GenerateTestsMojo extends AbstractMojo { @Parameter private String nameSuffixForTests - @Component + @Parameter(defaultValue = '${project}', readonly = true) private MavenProject project @Parameter(property = 'accurest.skip', defaultValue = 'false') diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index abacda2d43..ea33e18ca8 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -9,7 +9,6 @@ import org.apache.maven.model.path.PathTranslator import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.Component import org.apache.maven.plugins.annotations.Mojo import org.apache.maven.plugins.annotations.Parameter import org.eclipse.aether.RepositorySystemSession @@ -49,7 +48,7 @@ class RunMojo extends AbstractMojo { private String stubsClassifier = 'stubs' - @Component + @Parameter(defaultValue = '${session}', readonly = true) private MavenSession mavenSession private final LocalStubRunner localStubRunner diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index 6562e9634a..d1adb9b706 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -81,6 +81,7 @@ convert + generateStubs generateTests @@ -115,30 +116,6 @@ --> - - maven-assembly-plugin - 2.6 - - - io.codearte.accurest - stubs-assembly-descriptor - 1.1 - - - - - package - - single - - - - - - stubs - - - diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index 84432a4b1c..3f1f635dbd 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -18,11 +18,14 @@ org.springframework.boot spring-boot-starter-web - + + org.springframework.boot + spring-boot-starter-test + test + ch.qos.logback logback-classic - 1.1.3 @@ -50,12 +53,6 @@ 2.3.0 test - - junit - junit - 4.12 - test - @@ -76,6 +73,7 @@ convert + generateStubs generateTests @@ -85,31 +83,6 @@ hello.BaseMockMvcTest - - maven-assembly-plugin - 2.6 - - - io.codearte.accurest - stubs-assembly-descriptor - 1.1 - - - - - package - - single - - - - - - stubs - - - - From fcb447575339f29fe5896e265b00d121b790da10 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sat, 16 Apr 2016 19:32:59 +0000 Subject: [PATCH 482/719] Sets project version to 0.5.7-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index fd3b43a361..769d08889f 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.6-SNAPSHOT + 0.5.7-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin From aeb57dc3553e7b4758d2c6e410baf5d81123add0 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 17 Apr 2016 20:15:47 +0200 Subject: [PATCH 483/719] fixed groovy configuration and additional tests for this case [ci skip] --- .../io/codearte/accurest/maven/PluginIT.java | 2 ++ src/test/projects/spring-boot-groovy/pom.xml | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/io/codearte/accurest/maven/PluginIT.java index 6dd0080e4c..15305cf7d2 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIT.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIT.java @@ -37,6 +37,7 @@ public class PluginIT { .assertLogText("Generated 1 test classes.") .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") .assertLogText("Creating new json") + .assertLogText("Compiled 3 files.") // groovy test classes .assertErrorFreeLog(); } @@ -50,6 +51,7 @@ public class PluginIT { .assertLogText("Generated 1 test classes.") .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") .assertLogText("Creating new json") + .assertLogText("Compiling 2 source files") .assertErrorFreeLog(); } diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index d1adb9b706..50d56c8e6a 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -106,6 +106,22 @@ + + + + ${project.basedir}/src/test/groovy + + **/*.groovy + + + + ${project.build.directory}/generated-test-sources/accurest + + **/*.groovy + + + + + + + + + + + \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy new file mode 100644 index 0000000000..8d25db00f6 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy @@ -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() + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java new file mode 100644 index 0000000000..c5ee6bf196 --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java @@ -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(); + } +} diff --git a/accurest-messaging/accurest-messaging-camel/build.gradle b/accurest-messaging/accurest-messaging-camel/build.gradle new file mode 100644 index 0000000000..ed24c577eb --- /dev/null +++ b/accurest-messaging/accurest-messaging-camel/build.gradle @@ -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,)' +} \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelConfiguration.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelConfiguration.java new file mode 100644 index 0000000000..b96caf5ccc --- /dev/null +++ b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelConfiguration.java @@ -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(); + } +} diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java new file mode 100644 index 0000000000..94b808d8b5 --- /dev/null +++ b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java @@ -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 implements AccurestMessageBuilder { + + @Override + public AccurestMessage create(T payload, Map headers) { + DefaultMessage message = new DefaultMessage(); + message.setBody(payload); + message.setHeaders(headers); + return new CamelMessage<>(message); + } + + @Override + public AccurestMessage create(Message message) { + return new CamelMessage<>(message); + } +} diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java new file mode 100644 index 0000000000..bf1eef7dc1 --- /dev/null +++ b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java @@ -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 implements AccurestMessaging { + + 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 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 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 receiveMessage(String destination) { + return receiveMessage(destination, 5, TimeUnit.SECONDS); + } + + @Override + @SuppressWarnings("unchecked") + public AccurestMessage create(T t, Map headers) { + return builder.create(t, headers); + } + + @Override + @SuppressWarnings("unchecked") + public AccurestMessage create(Message message) { + return builder.create(message); + } +} diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/CamelMessage.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/CamelMessage.java new file mode 100644 index 0000000000..6511617a89 --- /dev/null +++ b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/CamelMessage.java @@ -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 implements AccurestMessage { + + private final Message delegate; + + public CamelMessage(Message delegate) { + this.delegate = delegate; + } + + @Override + @SuppressWarnings("unchecked") + public T getPayload() { + return (T) delegate.getBody(); + } + + @Override + public Map getHeaders() { + return delegate.getHeaders(); + } + + @Override + public Object getHeader(String key) { + return getHeaders().get(key); + } + + @Override + public Message convert() { + return delegate; + } + +} diff --git a/accurest-messaging/accurest-messaging-camel/src/main/resources/META-INF/spring.factories b/accurest-messaging/accurest-messaging-camel/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..318eec3472 --- /dev/null +++ b/accurest-messaging/accurest-messaging-camel/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.messaging.camel.AccurestCamelConfiguration diff --git a/accurest-messaging/accurest-messaging-core/build.gradle b/accurest-messaging/accurest-messaging-core/build.gradle new file mode 100644 index 0000000000..f63ffbeb9b --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/build.gradle @@ -0,0 +1,8 @@ +repositories { + jcenter() +} + +dependencies { + compile 'com.fasterxml.jackson.core:jackson-databind:[2.4.4,)' + compile 'javax.inject:javax.inject:1' +} \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessage.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessage.java new file mode 100644 index 0000000000..65710a537a --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessage.java @@ -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 { + + /** + * Returns a payload of type {@code PAYLOAD} + */ + PAYLOAD getPayload(); + + /** + * Returns a map of headers + */ + Map 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(); +} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessageBuilder.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessageBuilder.java new file mode 100644 index 0000000000..3d0a0e37e4 --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessageBuilder.java @@ -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 { + + /** + * Creates a {@link AccurestMessage} from payload and headers + */ + AccurestMessage create(PAYLOAD payload, Map headers); + + /** + * Creates a {@link AccurestMessage} from the {@code TYPE_TO_CONVERT_INTO} type + */ + AccurestMessage create(TYPE_TO_CONVERT_INTO typeToConvertInto); +} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java new file mode 100644 index 0000000000..226f800046 --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java @@ -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 extends AccurestMessageBuilder { + /** + * Sends the {@link AccurestMessage} to the given destination. + */ + void send(AccurestMessage message, String destination); + + /** + * Receives the {@link AccurestMessage} from the given destination. You can provide the timeout + * for receiving that message. + */ + AccurestMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit); + + /** + * Receives the {@link AccurestMessage} from the given destination. A default timeout will be applied. + */ + AccurestMessage receiveMessage(String destination); +} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessagingUtil.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessagingUtil.java new file mode 100644 index 0000000000..d2749c03ea --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessagingUtil.java @@ -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 { + + private final Map 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 m) { + delegate.putAll(m); + } + + @Override + public void clear() { + delegate.clear(); + } + + @Override + public Set keySet() { + return delegate.keySet(); + } + + @Override + public Collection values() { + return delegate.values(); + } + + @Override + public Set> entrySet() { + return delegate.entrySet(); + } + + @Override + public boolean equals(Object o) { + return delegate.equals(o); + } + + @Override + public int hashCode() { + return delegate.hashCode(); + } + } +} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessage.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessage.java new file mode 100644 index 0000000000..179a63d9b7 --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessage.java @@ -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 getHeaders() { + return null; + } + + @Override + public Object getHeader(String key) { + return null; + } + + @Override + public Object convert() { + return null; + } +} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java new file mode 100644 index 0000000000..50cb34fffa --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java @@ -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; + } +} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java new file mode 100644 index 0000000000..b99efe7a49 --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java @@ -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; + } +} diff --git a/accurest-messaging/accurest-messaging-integration/build.gradle b/accurest-messaging/accurest-messaging-integration/build.gradle new file mode 100644 index 0000000000..b29adf4789 --- /dev/null +++ b/accurest-messaging/accurest-messaging-integration/build.gradle @@ -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,)' +} \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationConfiguration.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationConfiguration.java new file mode 100644 index 0000000000..214161b605 --- /dev/null +++ b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationConfiguration.java @@ -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(); + } +} diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java new file mode 100644 index 0000000000..9b6b945570 --- /dev/null +++ b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java @@ -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 implements AccurestMessageBuilder> { + + @Override + public AccurestMessage> create(T payload, Map headers) { + return new IntegrationMessage<>(MessageBuilder.createMessage(payload, new MessageHeaders(headers))); + } + + @Override + public AccurestMessage> create(Message message) { + return new IntegrationMessage<>(message); + } +} diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java new file mode 100644 index 0000000000..2486080560 --- /dev/null +++ b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java @@ -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 implements AccurestMessaging> { + + 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> 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> 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> receiveMessage(String destination) { + return receiveMessage(destination, 5, TimeUnit.SECONDS); + } + + @Override + @SuppressWarnings("unchecked") + public AccurestMessage> create(T t, Map headers) { + return builder.create(t, headers); + } + + @Override + @SuppressWarnings("unchecked") + public AccurestMessage> create(Message message) { + return builder.create(message); + } +} diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/IntegrationMessage.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/IntegrationMessage.java new file mode 100644 index 0000000000..87b472f7dd --- /dev/null +++ b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/IntegrationMessage.java @@ -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 implements AccurestMessage> { + + private final Message delegate; + + public IntegrationMessage(Message 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 convert() { + return delegate; + } + +} diff --git a/accurest-messaging/accurest-messaging-integration/src/main/resources/META-INF/spring.factories b/accurest-messaging/accurest-messaging-integration/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..117d34083a --- /dev/null +++ b/accurest-messaging/accurest-messaging-integration/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.messaging.integration.AccurestIntegrationConfiguration diff --git a/accurest-messaging/accurest-messaging-stream/build.gradle b/accurest-messaging/accurest-messaging-stream/build.gradle new file mode 100644 index 0000000000..4b045bb943 --- /dev/null +++ b/accurest-messaging/accurest-messaging-stream/build.gradle @@ -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,)' +} \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamAutoConfiguration.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamAutoConfiguration.java new file mode 100644 index 0000000000..243f856acb --- /dev/null +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamAutoConfiguration.java @@ -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(); + } +} diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java new file mode 100644 index 0000000000..e6abccdd89 --- /dev/null +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java @@ -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 implements AccurestMessageBuilder> { + + @Override + public AccurestMessage> create(T payload, Map headers) { + return new StreamMessage<>(MessageBuilder.createMessage(payload, new MessageHeaders(headers))); + } + + @Override + public AccurestMessage> create(Message message) { + return new StreamMessage<>(message); + } +} diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java new file mode 100644 index 0000000000..368a7d5cd0 --- /dev/null +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java @@ -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 implements AccurestMessaging> { + + 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> 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> 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> receiveMessage(String destination) { + return receiveMessage(destination, 5, TimeUnit.SECONDS); + } + + @Override + @SuppressWarnings("unchecked") + public AccurestMessage> create(T t, Map headers) { + return builder.create(t, headers); + } + + @Override + @SuppressWarnings("unchecked") + public AccurestMessage> create(Message message) { + return builder.create(message); + } +} diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java new file mode 100644 index 0000000000..7b7faeb68a --- /dev/null +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java @@ -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 implements AccurestMessage> { + + private final Message delegate; + + public StreamMessage(Message 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 convert() { + return delegate; + } + +} diff --git a/accurest-messaging/accurest-messaging-stream/src/main/resources/META-INF/spring.factories b/accurest-messaging/accurest-messaging-stream/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..b2ba657e44 --- /dev/null +++ b/accurest-messaging/accurest-messaging-stream/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.messaging.stream.AccurestStreamAutoConfiguration diff --git a/build.gradle b/build.gradle index b679ef0101..a58ce57c62 100644 --- a/build.gradle +++ b/build.gradle @@ -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 } } diff --git a/gradle.properties b/gradle.properties index dfc935df68..00b1483625 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,4 +2,6 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.5-beta -jsonassertVersion = 0.2.2 \ No newline at end of file +jsonassertVersion = 0.2.2 + +BOM_VERSION=Brixton-1.0.0.RC1 \ No newline at end of file diff --git a/samples/messaging-camel/build.gradle b/samples/messaging-camel/build.gradle new file mode 100644 index 0000000000..bc1c2750b3 --- /dev/null +++ b/samples/messaging-camel/build.gradle @@ -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') + } +} \ No newline at end of file diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleted.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleted.groovy new file mode 100644 index 0000000000..f20d028575 --- /dev/null +++ b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleted.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 + } +} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleter.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleter.groovy new file mode 100644 index 0000000000..9184450edc --- /dev/null +++ b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleter.groovy @@ -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) +} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookReturned.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookReturned.groovy new file mode 100644 index 0000000000..19ca5837d9 --- /dev/null +++ b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookReturned.groovy @@ -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 + } +} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookRouteConfiguration.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookRouteConfiguration.groovy new file mode 100644 index 0000000000..66f5a46535 --- /dev/null +++ b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookRouteConfiguration.groovy @@ -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) + } + + }; + } +} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookService.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookService.groovy new file mode 100644 index 0000000000..edda66c9c7 --- /dev/null +++ b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookService.groovy @@ -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) + } + } +} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplication.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplication.groovy new file mode 100644 index 0000000000..26819753e5 --- /dev/null +++ b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplication.groovy @@ -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) + } +} diff --git a/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy b/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy new file mode 100644 index 0000000000..0400c9d359 --- /dev/null +++ b/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy @@ -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() + } + } + +} \ No newline at end of file diff --git a/samples/messaging-integration/build.gradle b/samples/messaging-integration/build.gradle new file mode 100644 index 0000000000..5096207045 --- /dev/null +++ b/samples/messaging-integration/build.gradle @@ -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') + } +} \ No newline at end of file diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy new file mode 100644 index 0000000000..abe8ce0959 --- /dev/null +++ b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.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 + } +} diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy new file mode 100644 index 0000000000..1ef7d26f79 --- /dev/null +++ b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy @@ -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) +} diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy new file mode 100644 index 0000000000..cca077e266 --- /dev/null +++ b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy @@ -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 + } +} diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy new file mode 100644 index 0000000000..f5acc1c1e8 --- /dev/null +++ b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy @@ -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 + ]))) + } +} diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplication.groovy b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplication.groovy new file mode 100644 index 0000000000..e1ec8da114 --- /dev/null +++ b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplication.groovy @@ -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) + } +} diff --git a/samples/messaging-integration/src/main/resources/integration-context.xml b/samples/messaging-integration/src/main/resources/integration-context.xml new file mode 100644 index 0000000000..aa5a5cc3a5 --- /dev/null +++ b/samples/messaging-integration/src/main/resources/integration-context.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy b/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy new file mode 100644 index 0000000000..6b8cfeda18 --- /dev/null +++ b/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy @@ -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() + } + +} \ No newline at end of file diff --git a/samples/messaging-spring/build.gradle b/samples/messaging-spring/build.gradle new file mode 100644 index 0000000000..a422f0a484 --- /dev/null +++ b/samples/messaging-spring/build.gradle @@ -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') + } +} \ No newline at end of file diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookDeleted.groovy b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookDeleted.groovy new file mode 100644 index 0000000000..470329b7a8 --- /dev/null +++ b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookDeleted.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 + } +} diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookListener.groovy b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookListener.groovy new file mode 100644 index 0000000000..6d56d0f594 --- /dev/null +++ b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookListener.groovy @@ -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) +} diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookReturned.groovy b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookReturned.groovy new file mode 100644 index 0000000000..bd13a4ff6b --- /dev/null +++ b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookReturned.groovy @@ -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 + } +} diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookService.groovy b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookService.groovy new file mode 100644 index 0000000000..5ba455d8c1 --- /dev/null +++ b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookService.groovy @@ -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) + } +} diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/SpringMessagingApplication.groovy b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/SpringMessagingApplication.groovy new file mode 100644 index 0000000000..287a1e2240 --- /dev/null +++ b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/SpringMessagingApplication.groovy @@ -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) + } +} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy new file mode 100644 index 0000000000..a6296a02ae --- /dev/null +++ b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy @@ -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() + } + } + +} \ No newline at end of file diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessageBuilder.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessageBuilder.groovy new file mode 100644 index 0000000000..cf3294b4e1 --- /dev/null +++ b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessageBuilder.groovy @@ -0,0 +1,35 @@ +package io.codearte.accurest.samples.spring.config + +import io.codearte.accurest.messaging.AccurestMessage +import io.codearte.accurest.messaging.AccurestMessageBuilder +import org.springframework.jms.core.MessageCreator + +import javax.jms.JMSException +import javax.jms.Message +import javax.jms.Session +/** + * @author Marcin Grzejszczak + */ +public class AccurestSpringMessageBuilder implements AccurestMessageBuilder { + + @Override + public AccurestMessage create(final T payload, final Map headers) { + MessageCreator messageCreator = new MessageCreator() { + @Override + public Message createMessage(Session session) throws JMSException { + Message message = session.createObjectMessage(payload); + headers.entrySet().each { Map.Entry entry -> + message.setObjectProperty(entry.key, entry.value) + } + return message + } + }; + + return new SpringMessage<>(messageCreator) + } + + @Override + public AccurestMessage create(Message message) { + return new SpringMessage<>(message); + } +} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy new file mode 100644 index 0000000000..8604d1e641 --- /dev/null +++ b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy @@ -0,0 +1,71 @@ +package io.codearte.accurest.samples.spring.config + +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.jms.core.JmsTemplate +import org.springframework.stereotype.Component + +import javax.jms.Message +import java.util.concurrent.TimeUnit +/** + * @author Marcin Grzejszczak + */ +@Component +public class AccurestSpringMessaging implements AccurestMessaging { + + private static final Logger log = LoggerFactory.getLogger(AccurestSpringMessaging.class); + + private final JmsTemplate jmsTemplate; + private final AccurestMessageBuilder builder; + + @Autowired + @SuppressWarnings("unchecked") + public AccurestSpringMessaging(AccurestMessageBuilder builder, JmsTemplate jmsTemplate) { + this.builder = builder + this.jmsTemplate = jmsTemplate + } + + @Override + public void send(AccurestMessage message, String destination) { + try { + jmsTemplate.send(destination, ((SpringMessage) message).messageCreator) + } 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 receiveMessage(String destination, long timeout, TimeUnit timeUnit) { + try { + return builder.create(jmsTemplate.receive(destination)); + } 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 receiveMessage(String destination) { + return receiveMessage(destination, 5, TimeUnit.SECONDS); + } + + @Override + @SuppressWarnings("unchecked") + public AccurestMessage create(T t, Map headers) { + return builder.create(t, headers); + } + + @Override + @SuppressWarnings("unchecked") + public AccurestMessage create(Message message) { + return builder.create(message); + } +} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/ManualAccurestConfiguration.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/ManualAccurestConfiguration.groovy new file mode 100644 index 0000000000..1cd05f86f0 --- /dev/null +++ b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/ManualAccurestConfiguration.groovy @@ -0,0 +1,18 @@ +package io.codearte.accurest.samples.spring.config + +import io.codearte.accurest.messaging.AccurestMessaging +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.jms.core.JmsTemplate +/** + * @author Marcin Grzejszczak + */ +@Configuration +class ManualAccurestConfiguration { + + @Bean + AccurestMessaging accurestMessaging(JmsTemplate jmsTemplate) { + return new AccurestSpringMessaging(new AccurestSpringMessageBuilder(), jmsTemplate); + } + +} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/SpringMessage.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/SpringMessage.groovy new file mode 100644 index 0000000000..1f8f7cc8b6 --- /dev/null +++ b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/SpringMessage.groovy @@ -0,0 +1,52 @@ +package io.codearte.accurest.samples.spring.config + +import io.codearte.accurest.messaging.AccurestMessage +import org.springframework.jms.core.MessageCreator + +import javax.jms.Message +import javax.jms.ObjectMessage +/** + * @author Marcin Grzejszczak + */ +public class SpringMessage implements AccurestMessage { + + private final ObjectMessage messageDelegate; + final MessageCreator messageCreator; + + public SpringMessage(Message messageDelegate) { + this.messageDelegate = (ObjectMessage) messageDelegate; + this.messageCreator = null + } + + public SpringMessage(MessageCreator messageCreator) { + this.messageDelegate = null; + this.messageCreator = messageCreator + } + + @Override + public T getPayload() { + return messageDelegate.getObject(); + } + + @Override + public Map getHeaders() { + Map headers = [:] + def enumeration = messageDelegate.propertyNames + while(enumeration.hasMoreElements()) { + String propertyName = enumeration.nextElement() + headers << [(propertyName) : messageDelegate.getObjectProperty(propertyName)] + } + return headers + } + + @Override + Object getHeader(String key) { + return getHeaders().get(key) + } + + @Override + public Message convert() { + return messageDelegate; + } + +} diff --git a/samples/messaging-stream/build.gradle b/samples/messaging-stream/build.gradle new file mode 100644 index 0000000000..69a151237c --- /dev/null +++ b/samples/messaging-stream/build.gradle @@ -0,0 +1,22 @@ +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.cloud:spring-cloud-stream-binder-rabbit:1.0.0.RC2' + + testCompile project(':accurest-messaging-root:accurest-messaging-stream') + testCompile 'org.springframework.cloud:spring-cloud-stream-test-support:1.0.0.RC2' + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy new file mode 100644 index 0000000000..abe8ce0959 --- /dev/null +++ b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.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 + } +} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy new file mode 100644 index 0000000000..fe201e4636 --- /dev/null +++ b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy @@ -0,0 +1,48 @@ +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.cloud.stream.annotation.EnableBinding +import org.springframework.cloud.stream.annotation.StreamListener +import org.springframework.cloud.stream.messaging.Sink +import org.springframework.cloud.stream.messaging.Source +import org.springframework.messaging.MessageHeaders +import org.springframework.messaging.support.MessageBuilder + +import java.util.concurrent.atomic.AtomicBoolean + +@CompileStatic +@Slf4j +@EnableBinding([DeleteSink, Sink]) +class BookListener { + + @Autowired Source source + + /** + 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 + */ + @StreamListener(Sink.INPUT) + void returnBook(BookReturned bookReturned) { + log.info("Returning book [$bookReturned]") + source.output().send(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 + */ + @StreamListener(DeleteSink.INPUT) + void bookDeleted(BookDeleted bookDeleted) { + log.info("Deleting book [$bookDeleted]") + // ... doing some work + bookSuccessfulyDeleted.set(true) + } + + AtomicBoolean bookSuccessfulyDeleted = new AtomicBoolean(false) +} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy new file mode 100644 index 0000000000..cca077e266 --- /dev/null +++ b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy @@ -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 + } +} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy new file mode 100644 index 0000000000..ae310cb836 --- /dev/null +++ b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy @@ -0,0 +1,36 @@ +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.cloud.stream.messaging.Source +import org.springframework.messaging.MessageHeaders +import org.springframework.messaging.support.MessageBuilder +import org.springframework.stereotype.Service + +@Service +@CompileStatic +@Slf4j +class BookService { + + private final Source source + + @Autowired + BookService(Source source) { + this.source = source + } + + /** + 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]") + source.output().send(MessageBuilder.createMessage(bookReturned, new MessageHeaders([ + 'BOOK-NAME': bookReturned.bookName as Object + ]))) + } +} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/DeleteSink.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/DeleteSink.groovy new file mode 100644 index 0000000000..6986da9ca8 --- /dev/null +++ b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/DeleteSink.groovy @@ -0,0 +1,16 @@ +package io.codearte.accurest.samples.messaging + +import org.springframework.cloud.stream.annotation.Input +import org.springframework.cloud.stream.messaging.Sink +import org.springframework.messaging.SubscribableChannel + +/** + * @author Marcin Grzejszczak + */ +interface DeleteSink extends Sink { + + String INPUT = "delete"; + + @Input(DeleteSink.INPUT) + SubscribableChannel delete(); +} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplication.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplication.groovy new file mode 100644 index 0000000000..c6285ea622 --- /dev/null +++ b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplication.groovy @@ -0,0 +1,16 @@ +package io.codearte.accurest.samples.messaging; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding +import org.springframework.cloud.stream.messaging.Sink; +import org.springframework.cloud.stream.messaging.Source; + +@SpringBootApplication +@EnableBinding([Source, Sink]) +class StreamMessagingApplication { + + static void main(String[] args) { + SpringApplication.run(StreamMessagingApplication.class, args) + } +} diff --git a/samples/messaging-stream/src/main/resources/application.yml b/samples/messaging-stream/src/main/resources/application.yml new file mode 100644 index 0000000000..1ff1cf7519 --- /dev/null +++ b/samples/messaging-stream/src/main/resources/application.yml @@ -0,0 +1,2 @@ +spring.cloud.stream.bindings.input.destination: inputDestination +spring.cloud.stream.bindings.output.destination: sentTo \ No newline at end of file diff --git a/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy b/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy new file mode 100644 index 0000000000..4cc5d1b2e0 --- /dev/null +++ b/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy @@ -0,0 +1,137 @@ +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 = [StreamMessagingApplication], loader = SpringApplicationContextLoader) +public class StreamMessagingApplicationSpec 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() + } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 6644eb4f03..54053949b1 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,21 @@ -include ':docs' +include 'docs' include "accurest-core", "accurest-gradle-plugin", 'accurest-converters', 'accurest-testing-utils' include ':stub-runner:stub-runner' include ':stub-runner:stub-runner-spring' include ':stub-runner:stub-runner-spring-cloud' include ':stub-runner:stub-runner-junit' +include ':accurest-messaging:accurest-messaging-core' +include ':accurest-messaging:accurest-messaging-integration' +include ':accurest-messaging:accurest-messaging-stream' +include ':accurest-messaging:accurest-messaging-camel' + +include ':samples:messaging-stream' +include ':samples:messaging-integration' +include ':samples:messaging-camel' +include ':samples:messaging-spring' + rootProject.name = "accurest" //to prevent StackOverflow in Sonar -project(":stub-runner").name = "stub-runner-root" \ No newline at end of file +project(":stub-runner").name = "stub-runner-root" +project(":accurest-messaging").name = "accurest-messaging-root" \ No newline at end of file diff --git a/stub-runner/stub-runner-junit/build.gradle b/stub-runner/stub-runner-junit/build.gradle index fa14799646..bd9a36bfe0 100644 --- a/stub-runner/stub-runner-junit/build.gradle +++ b/stub-runner/stub-runner-junit/build.gradle @@ -6,7 +6,7 @@ dependencies { compile localGroovy() compile 'junit:junit:4.12' - testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } testCompile 'cglib:cglib-nodep:2.2' diff --git a/stub-runner/stub-runner-spring-cloud/build.gradle b/stub-runner/stub-runner-spring-cloud/build.gradle index a69b8dc7fc..6b394afa9a 100644 --- a/stub-runner/stub-runner-spring-cloud/build.gradle +++ b/stub-runner/stub-runner-spring-cloud/build.gradle @@ -6,7 +6,7 @@ dependencies { compile 'org.springframework.cloud:spring-cloud-starter:1.1.0.RC2' compile 'org.springframework.cloud:spring-cloud-starter-ribbon:1.1.0.RC1' - testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } testCompile 'cglib:cglib-nodep:2.2' @@ -16,7 +16,7 @@ dependencies { testCompile 'io.reactivex:rxjava:1.1.1' testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' testCompile "org.springframework:spring-web:4.2.5.RELEASE" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.3') { + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } testCompile 'ch.qos.logback:logback-classic:1.1.3' diff --git a/stub-runner/stub-runner-spring/build.gradle b/stub-runner/stub-runner-spring/build.gradle index cf735ddc98..f05eb40a0d 100644 --- a/stub-runner/stub-runner-spring/build.gradle +++ b/stub-runner/stub-runner-spring/build.gradle @@ -6,14 +6,14 @@ dependencies { compile localGroovy() compile 'org.springframework:spring-context:[3.0.0.RELEASE,)' - testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile 'org.springframework.boot:spring-boot-starter:1.3.3.RELEASE' testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' - testCompile('org.spockframework:spock-spring:1.0-groovy-2.3') { + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } testCompile 'ch.qos.logback:logback-classic:1.1.3' diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index 3ee78c7685..d8a1265ef6 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -4,6 +4,7 @@ apply plugin: 'application' mainClassName = 'io.codearte.accurest.stubrunner.StubRunnerMain' dependencies { + compile project(':accurest-core') compile 'org.apache.ivy:ivy:2.4.0' compile localGroovy() compile "com.github.tomakehurst:wiremock:$wiremockVersion" @@ -12,7 +13,7 @@ dependencies { if (rootProject.hasProperty("fatJar")) runtime 'ch.qos.logback:logback-classic:1.1.3' - testCompile('org.spockframework:spock-core:1.0-groovy-2.3') { + testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } testCompile 'cglib:cglib-nodep:2.2' diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy new file mode 100644 index 0000000000..af9af5b155 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy @@ -0,0 +1,23 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import io.codearte.accurest.dsl.GroovyDsl + +/** + * @author Marcin Grzejszczak + */ +@PackageScope +@CompileStatic +class GroovyDslWrapper { + + @Delegate private final GroovyDsl groovyDsl + + GroovyDslWrapper(GroovyDsl groovyDsl) { + this.groovyDsl = groovyDsl + } + + boolean hasHttpPart() { + return groovyDsl.request + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy new file mode 100644 index 0000000000..93741e2f57 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy @@ -0,0 +1,13 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +/** + * @author Marcin Grzejszczak + */ +@CompileStatic +@EqualsAndHashCode +class StubData { + final Integer port + final List contracts +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy index 147b24b390..f7f43f0f2a 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy @@ -2,12 +2,16 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope +import groovy.util.logging.Slf4j +import io.codearte.accurest.dsl.GroovyDsl +import org.codehaus.groovy.control.CompilerConfiguration /** * Wraps the folder with WireMock mappings. */ @CompileStatic @PackageScope +@Slf4j class StubRepository { private final File path @@ -19,24 +23,50 @@ class StubRepository { this.path = repository } + Collection getAccurestContracts() { + List contracts = [] + contracts.addAll(accurestDescriptors()) + return contracts + } + /** - * Returns the list of WireMock JSON files wrapped in {@link MappingDescriptor} + * Returns the list of WireMock JSON files wrapped in {@link WiremockMappingDescriptor} */ - List getProjectDescriptors() { - List mappingDescriptors = [] + List getProjectDescriptors() { + List mappingDescriptors = [] mappingDescriptors.addAll(contextDescriptors()) return mappingDescriptors } - private List contextDescriptors() { + private List contextDescriptors() { return path.exists() ? collectMappingDescriptors(path) : [] } - private List collectMappingDescriptors(File descriptorsDirectory) { - List mappingDescriptors = [] + private List collectMappingDescriptors(File descriptorsDirectory) { + List mappingDescriptors = [] descriptorsDirectory.eachFileRecurse { File file -> if (isMappingDescriptor(file)) { - mappingDescriptors << new MappingDescriptor(file) + mappingDescriptors << new WiremockMappingDescriptor(file) + } + } + return mappingDescriptors + } + + private Collection accurestDescriptors() { + return path.exists() ? collectAccurestDescriptors(path) : [] + } + + private Collection collectAccurestDescriptors(File descriptorsDirectory) { + List mappingDescriptors = [] + descriptorsDirectory.eachFileRecurse { File file -> + if (isAccurestDescriptor(file)) { + try { + mappingDescriptors << new GroovyDslWrapper( + ((new GroovyShell(delegate.class.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate(file)) as GroovyDsl) + ) + } catch (Exception e) { + log.warn("Exception occurred while trying to parse file [$file]", e) + } } } return mappingDescriptors @@ -46,4 +76,9 @@ class StubRepository { return file.isFile() && file.name.endsWith('.json') } + private static boolean isAccurestDescriptor(File file) { + //TODO: Consider script injections implications... + return file.isFile() && file.name.endsWith('.groovy') + } + } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy index b28238cddc..496e1d49a3 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -2,7 +2,6 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j - /** * Represents a single instance of ready-to-run stubs. * Can run the stubs and then will return the name of the collaborator together with @@ -14,10 +13,10 @@ import groovy.util.logging.Slf4j @CompileStatic class StubRunner implements StubRunning { - private StubRunnerExecutor localStubRunner private final StubRepository stubRepository - private StubConfiguration stubsConfiguration - private StubRunnerOptions stubRunnerOptions + private final StubConfiguration stubsConfiguration + private final StubRunnerOptions stubRunnerOptions + private StubRunnerExecutor localStubRunner @Deprecated StubRunner(Arguments arguments) { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index a398a3ec4b..67a1b40fee 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -2,7 +2,6 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j - /** * Runs stubs for a particular {@link StubServer} */ @@ -57,9 +56,10 @@ class StubRunnerExecutor implements StubFinder { } private void startStubServers(StubConfiguration stubConfiguration, StubRepository repository) { - List mappings = repository.getProjectDescriptors() + List mappings = repository.getProjectDescriptors() + Collection contracts = repository.accurestContracts stubServer = portScanner.tryToExecuteWithFreePort { int availablePort -> - return new StubServer(availablePort, stubConfiguration, mappings).start() + return new StubServer(availablePort, stubConfiguration, mappings, contracts).start() } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy index 830a3a22f5..8fb22a1dd0 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy @@ -13,12 +13,15 @@ import groovy.util.logging.Slf4j class StubServer { private WireMockServer wireMockServer final StubConfiguration stubConfiguration - final Collection mappings + final Collection mappings + final Collection contracts - StubServer(int port, StubConfiguration stubConfiguration, Collection mappings) { + StubServer(int port, StubConfiguration stubConfiguration, Collection mappings, + Collection contracts) { this.stubConfiguration = stubConfiguration this.mappings = mappings this.wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(port)) + this.contracts = contracts } StubServer start() { @@ -51,8 +54,8 @@ class StubServer { registerHealthCheck(wireMock, '/health') } - private void registerStubs(Collection sortedMappings, WireMock wireMock) { - sortedMappings.each { MappingDescriptor mappingDescriptor -> + private void registerStubs(Collection sortedMappings, WireMock wireMock) { + sortedMappings.each { WiremockMappingDescriptor mappingDescriptor -> try { wireMock.register(mappingDescriptor.mapping) log.debug("Registered stub mappings from $mappingDescriptor.descriptor") diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MappingDescriptor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/WiremockMappingDescriptor.groovy similarity index 87% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MappingDescriptor.groovy rename to stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/WiremockMappingDescriptor.groovy index 18357b82a9..d8cb688f8c 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MappingDescriptor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/WiremockMappingDescriptor.groovy @@ -14,10 +14,10 @@ import groovy.transform.ToString @EqualsAndHashCode @ToString(includePackage = false) @PackageScope -class MappingDescriptor { +class WiremockMappingDescriptor { final File descriptor - MappingDescriptor(File mappingDescriptor) { + WiremockMappingDescriptor(File mappingDescriptor) { this.descriptor = mappingDescriptor } diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy index 394cabf2d8..6e04a8beef 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy @@ -9,7 +9,7 @@ class MappingDescriptorSpec extends Specification { def 'should describe stub mapping'() { given: - MappingDescriptor mappingDescriptor = new MappingDescriptor(MAPPING_DESCRIPTOR) + WiremockMappingDescriptor mappingDescriptor = new WiremockMappingDescriptor(MAPPING_DESCRIPTOR) expect: with(mappingDescriptor.mapping) { diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy index 337508fce0..8e50f75267 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy @@ -11,7 +11,7 @@ class StubRepositorySpec extends Specification { StubRepository repository = new StubRepository(REPOSITORY_LOCATION) int expectedDescriptorsSize = 8 when: - List descriptors = repository.getProjectDescriptors() + List descriptors = repository.getProjectDescriptors() then: descriptors.size() == expectedDescriptorsSize } @@ -20,7 +20,7 @@ class StubRepositorySpec extends Specification { given: StubRepository repository = new StubRepository(new File('src/test/resources/emptyrepo')) when: - List descriptors = repository.getProjectDescriptors() + List descriptors = repository.getProjectDescriptors() then: descriptors.empty } diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy index 14d71ac9e3..fad9fd82eb 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy @@ -11,8 +11,8 @@ class StubServerSpec extends Specification { def 'should register stub mappings upon server start'() { given: - List mappingDescriptors = new StubRepository(repository).getProjectDescriptors() - StubServer pingStubServer = new StubServer(STUB_SERVER_PORT, stubConfiguration, mappingDescriptors) + List mappingDescriptors = new StubRepository(repository).getProjectDescriptors() + StubServer pingStubServer = new StubServer(STUB_SERVER_PORT, stubConfiguration, mappingDescriptors, []) when: pingStubServer.start() then: @@ -23,8 +23,8 @@ class StubServerSpec extends Specification { def 'should provide stub server URL'() { given: - List mappingDescriptors = new StubRepository(repository).getProjectDescriptors() - StubServer pingStubServer = new StubServer(STUB_SERVER_PORT, stubConfiguration, mappingDescriptors) + List mappingDescriptors = new StubRepository(repository).getProjectDescriptors() + StubServer pingStubServer = new StubServer(STUB_SERVER_PORT, stubConfiguration, mappingDescriptors, []) when: pingStubServer.start() then: From bb4df7903a630a43adff3656269c49d9916659b3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 15:32:07 +0200 Subject: [PATCH 497/719] Wrapping the created ServerList in stub runner version (#241) --- .../StubRunnerRibbonAutoConfiguration.java | 6 +- .../StubRunnerRibbonBeanPostProcessor.java | 61 ++++++++++++ .../ribbon/StubRunnerRibbonConfiguration.java | 94 ++----------------- .../ribbon/StubRunnerRibbonServerList.java | 94 +++++++++++++++++++ 4 files changed, 167 insertions(+), 88 deletions(-) create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java create mode 100644 stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java index e54b825ec7..9bffb4c1ea 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java @@ -1,5 +1,7 @@ package io.codearte.accurest.stubrunner.spring.cloud.ribbon; +import com.netflix.loadbalancer.ServerList; +import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; @@ -8,10 +10,6 @@ import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration; import org.springframework.cloud.netflix.ribbon.RibbonClients; import org.springframework.context.annotation.Configuration; -import com.netflix.loadbalancer.ServerList; - -import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; - @Configuration @ConditionalOnClass(ServerList.class) @ConditionalOnBean(StubMapperProperties.class) diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java new file mode 100644 index 0000000000..fc4e801e0a --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java @@ -0,0 +1,61 @@ +package io.codearte.accurest.stubrunner.spring.cloud.ribbon; + +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.ServerList; +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.BeanFactory; +import org.springframework.beans.factory.config.BeanPostProcessor; + +/** + * Ribbon AutoConfiguration that manipulates the service id to make the service + * be picked from the list of available WireMock instance if one is available. + * + * @author Marcin Grzejszczak + */ +class StubRunnerRibbonBeanPostProcessor implements BeanPostProcessor { + + private final BeanFactory beanFactory; + private StubFinder stubFinder; + private StubMapperProperties stubMapperProperties; + private IClientConfig clientConfig; + + StubRunnerRibbonBeanPostProcessor(BeanFactory beanFactory) { + this.beanFactory = beanFactory; + } + + private StubFinder stubFinder() { + if (stubFinder == null) { + stubFinder = this.beanFactory.getBean(StubFinder.class); + } + return stubFinder; + } + + private StubMapperProperties stubMapperProperties() { + if (stubMapperProperties == null) { + stubMapperProperties = this.beanFactory.getBean(StubMapperProperties.class); + } + return stubMapperProperties; + } + + private IClientConfig clientConfig() { + if (clientConfig == null) { + clientConfig = this.beanFactory.getBean(IClientConfig.class); + } + return clientConfig; + } + + @Override + public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof ServerList && !(bean instanceof StubRunnerRibbonServerList)) { + return new StubRunnerRibbonServerList(stubFinder(), stubMapperProperties(), clientConfig(), (ServerList) bean); + } + return bean; + } + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + return bean; + } +} diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java index b55e1960a8..68aedc86ea 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java @@ -1,33 +1,21 @@ package io.codearte.accurest.stubrunner.spring.cloud.ribbon; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; - +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; +import org.springframework.beans.factory.BeanFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; +import java.util.ArrayList; +import java.util.List; -import io.codearte.accurest.stubrunner.RunningStubs; -import io.codearte.accurest.stubrunner.StubConfiguration; -import io.codearte.accurest.stubrunner.StubFinder; -import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; -import io.codearte.accurest.stubrunner.util.StringUtils; - -/** - * Ribbon AutoConfiguration that manipulates the service id to make the service - * be picked from the list of available WireMock instance if one is available. - * - * @author Marcin Grzejszczak - */ @Configuration -public class StubRunnerRibbonConfiguration { +class StubRunnerRibbonConfiguration { + @Bean + StubRunnerRibbonBeanPostProcessor stubRunnerRibbonBeanPostProcessor(BeanFactory beanFactory) { + return new StubRunnerRibbonBeanPostProcessor(beanFactory); + } @Bean @ConditionalOnMissingBean @@ -44,66 +32,4 @@ public class StubRunnerRibbonConfiguration { } }; } - - @Bean - @Primary - @SuppressWarnings("unchecked") - public ServerList stubRunnerRibbonServerList(final ServerList serverList, - StubFinder stubFinder, - final StubMapperProperties stubMapperProperties, - IClientConfig clientConfig) { - String serviceName = clientConfig.getClientName(); - String mappedServiceName = StringUtils - .hasText(stubMapperProperties.fromServiceIdToIvyNotation(serviceName)) ? - stubMapperProperties.fromServiceIdToIvyNotation(serviceName) : serviceName; - RunningStubs runningStubs = stubFinder.findAllRunningStubs(); - final Map.Entry entry = runningStubs.getEntry(mappedServiceName); - final Collection servers = new ArrayList(); - if (entry != null) { - servers.add(new Server("localhost", entry.getValue()) { - @Override - public MetaInfo getMetaInfo() { - return new MetaInfo() { - @Override - public String getAppName() { - return stubMapperProperties.fromIvyNotationToId(entry.getKey().toColonSeparatedDependencyNotation()); - } - - @Override - public String getServerGroup() { - return null; - } - - @Override - public String getServiceIdForDiscovery() { - return stubMapperProperties.fromIvyNotationToId(entry.getKey().getArtifactId()); - } - - @Override - public String getInstanceId() { - return stubMapperProperties.fromIvyNotationToId(entry.getKey().getArtifactId()); - } - }; - } - }); - } - return new ServerList() { - @Override - public List getInitialListOfServers() { - List combinedList = new ArrayList<>(); - combinedList.addAll(servers); - combinedList.addAll(serverList.getInitialListOfServers()); - return combinedList; - } - - @Override - public List getUpdatedListOfServers() { - List combinedList = new ArrayList<>(); - combinedList.addAll(servers); - combinedList.addAll(serverList.getUpdatedListOfServers()); - return combinedList; - } - }; - } - } diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java new file mode 100644 index 0000000000..2feca19e9b --- /dev/null +++ b/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java @@ -0,0 +1,94 @@ +package io.codearte.accurest.stubrunner.spring.cloud.ribbon; + +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; +import io.codearte.accurest.stubrunner.RunningStubs; +import io.codearte.accurest.stubrunner.StubConfiguration; +import io.codearte.accurest.stubrunner.StubFinder; +import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; +import io.codearte.accurest.stubrunner.util.StringUtils; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +/** + * Stub Runner representation of a server list + * + * @author Marcin Grzejszczak + */ +class StubRunnerRibbonServerList implements ServerList { + + private final ServerList serverList; + + @SuppressWarnings("unchecked") + StubRunnerRibbonServerList(final StubFinder stubFinder, + final StubMapperProperties stubMapperProperties, + final IClientConfig clientConfig, + final ServerList delegate) {; + String serviceName = clientConfig.getClientName(); + String mappedServiceName = StringUtils + .hasText(stubMapperProperties.fromServiceIdToIvyNotation(serviceName)) ? + stubMapperProperties.fromServiceIdToIvyNotation(serviceName) : serviceName; + RunningStubs runningStubs = stubFinder.findAllRunningStubs(); + final Map.Entry entry = runningStubs.getEntry(mappedServiceName); + final Collection servers = new ArrayList<>(); + if (entry != null) { + servers.add(new Server("localhost", entry.getValue()) { + @Override + public MetaInfo getMetaInfo() { + return new MetaInfo() { + @Override + public String getAppName() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().toColonSeparatedDependencyNotation()); + } + + @Override + public String getServerGroup() { + return null; + } + + @Override + public String getServiceIdForDiscovery() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().getArtifactId()); + } + + @Override + public String getInstanceId() { + return stubMapperProperties.fromIvyNotationToId(entry.getKey().getArtifactId()); + } + }; + } + }); + } + serverList = new ServerList() { + @Override + public List getInitialListOfServers() { + List combinedList = new ArrayList<>(); + combinedList.addAll(servers); + combinedList.addAll(delegate.getInitialListOfServers()); + return combinedList; + } + + @Override + public List getUpdatedListOfServers() { + List combinedList = new ArrayList<>(); + combinedList.addAll(servers); + combinedList.addAll(delegate.getUpdatedListOfServers()); + return combinedList; + } + }; + } + + @Override + public List getInitialListOfServers() { + return serverList.getInitialListOfServers(); + } + + @Override + public List getUpdatedListOfServers() { + return serverList.getUpdatedListOfServers(); + } +} From 172d8e73cd8986aaf63ffaf1ef434e5bb406f8dc Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Wed, 20 Apr 2016 19:19:32 +0200 Subject: [PATCH 498/719] Use Gradle Toolkit for testing Gradle plugin --- .../plugin/AccurestIntegrationSpec.groovy | 106 ++++++++++++++++-- .../plugin/BasicFunctionalSpec.groovy | 32 +++--- .../plugin/MessagingProjectSpec.groovy | 2 +- .../plugin/SampleJerseyProjectSpec.groovy | 5 +- .../accurest/plugin/SampleProjectSpec.groovy | 2 +- .../plugin/ScenarioProjectSpec.groovy | 2 +- build.gradle | 43 ++++++- 7 files changed, 155 insertions(+), 37 deletions(-) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy index 1bddae8b6d..1ac3521e4b 100644 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy @@ -1,7 +1,13 @@ package io.codearte.accurest.plugin -import nebula.test.IntegrationSpec -import nebula.test.functional.GradleRunner +import org.apache.commons.io.FileUtils +import org.gradle.testkit.runner.BuildResult +import org.gradle.testkit.runner.BuildTask +import org.gradle.testkit.runner.GradleRunner +import org.gradle.testkit.runner.TaskOutcome +import org.junit.Rule +import org.junit.rules.TemporaryFolder +import spock.lang.Specification import java.nio.file.Files import java.nio.file.Path @@ -9,19 +15,44 @@ import java.nio.file.Path import static java.nio.charset.StandardCharsets.UTF_8 /** - * @author Olga Maciaszek-Sharma + * @author Olga Maciaszek-Sharma + * @author Denis Stepanov * @since 23.02.16 */ -class AccurestIntegrationSpec extends IntegrationSpec { +class AccurestIntegrationSpec extends Specification { - public static final String SPOCK = "targetFramework = 'Spock'" - public static final String JUNIT = "targetFramework = 'JUnit'" - public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" - public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + @Rule + TemporaryFolder testProjectDir = new TemporaryFolder() - void setup() { - classpathFilter = GradleRunner.CLASSPATH_ALL //workaround for removing dependant modules by default filter - } + public static final String SPOCK = "targetFramework = 'Spock'" + public static final String JUNIT = "targetFramework = 'JUnit'" + public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" + public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + + protected void setupForProject(String projectRoot) { + copyResourcesToRoot(projectRoot) + + def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.txt") + if (pluginClasspathResource == null) { + throw new IllegalStateException("Did not find 'plugin-classpath.txt'") + } + + String pluginClasspath = pluginClasspathResource.readLines() + .collect { it.replace('\\', '\\\\') } // escape backslashes in Windows paths + .collect { "'$it'" } + .join(", ") + + buildFile << """ + buildscript { + dependencies { + classpath files($pluginClasspath) + } + } + """ + + // Extending buildscript is required when 'apply' is used. + // 'GradleRunner#withPluginClasspath' can be used when plugin is added using 'plugins { id...' + } protected void switchToJunitTestFramework() { switchToJunitTestFramework(MVC_SPEC, MVC_TEST) @@ -34,4 +65,57 @@ class AccurestIntegrationSpec extends IntegrationSpec { Files.write(path, content.getBytes(UTF_8)) } + protected void runTasksSuccessfully(String... tasks) { + BuildResult result = run(tasks) + result.tasks.each { + assert it.outcome == TaskOutcome.SUCCESS || it.outcome == TaskOutcome.UP_TO_DATE + } + } + + protected BuildResult validateTasksOutcome(BuildResult result, TaskOutcome expectedOutcome, String... tasks) { + tasks.each { + BuildTask task = result.task(":" + it) + assert task + assert task.outcome == expectedOutcome + } + return result + } + + protected BuildResult run(String... tasks) { + return GradleRunner.create() + .withProjectDir(testProjectDir.root) + .withArguments(tasks) + .build() + } + + protected void copyResourcesToRoot(String srcDir) { + copyResources(srcDir, testProjectDir.root) + } + + protected void copyResources(String srcDir, File destinationFile) { + ClassLoader classLoader = getClass().getClassLoader() + URL resource = classLoader.getResource(srcDir) + if (resource == null) { + throw new RuntimeException("Could not find classpath resource: $srcDir") + } + File resourceFile = new File(resource.toURI()) + if (resourceFile.file) { + FileUtils.copyFile(resourceFile, destinationFile) + } else { + FileUtils.copyDirectory(resourceFile, destinationFile) + } + } + + protected File file(String path) { + return new File(testProjectDir.getRoot(), path) + } + + protected boolean fileExists(String path) { + return file(path).exists() + } + + protected File getBuildFile() { + return new File('build.gradle', testProjectDir.root) + } + } 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 c9278e5f0b..2378342932 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 @@ -1,8 +1,11 @@ package io.codearte.accurest.plugin - import io.codearte.accurest.util.AssertionUtil +import org.gradle.testkit.runner.BuildResult import spock.lang.Stepwise +import static org.gradle.testkit.runner.TaskOutcome.SUCCESS +import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE + @Stepwise class BasicFunctionalSpec extends AccurestIntegrationSpec { @@ -12,18 +15,16 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.twitter_places_analyzer.PairIdSpec.xml" void setup() { - copyResources("functionalTest/bootSimple", "") - runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it + setupForProject("functionalTest/bootSimple") + runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } - def "should pass basic flow"() { - given: - assert fileExists('build.gradle') + def "should pass basic flxow"() { when: - def result = runTasksSuccessfully('check') + BuildResult result = run("check") then: - result.wasExecuted(":generateWireMockClientStubs") - result.wasExecuted(":generateAccurest") + result.task(":generateWireMockClientStubs").outcome == SUCCESS + result.task(":generateAccurest").outcome == SUCCESS and: "tests generated" fileExists(GENERATED_TEST) @@ -37,7 +38,7 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { def "should generate valid client json stubs for simple input"() { when: - runTasksSuccessfully('generateWireMockClientStubs') + run('generateWireMockClientStubs') then: def generatedClientJsonStub = file(GENERATED_CLIENT_JSON_STUB).text AssertionUtil.assertThatJsonsAreEqual(""" @@ -73,25 +74,24 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { fileExists(GENERATED_TEST) when: "running generation without change inputs" - def secondExecutionResult = runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest') + def secondExecutionResult = run('generateWireMockClientStubs', 'generateAccurest') then: "tasks should be up-to-date" - secondExecutionResult.wasUpToDate(":generateWireMockClientStubs") - secondExecutionResult.wasUpToDate(":generateAccurest") + validateTasksOutcome(secondExecutionResult, UP_TO_DATE, 'generateWireMockClientStubs', 'generateAccurest') when: "inputs changed" def groovyDslFile = file(GROOVY_DSL_CONTRACT) groovyDslFile.text = groovyDslFile.text.replace("200", "599") and: "tasks run" - def thirdExecutionResult = runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest') + def thirdExecutionResult = run('generateWireMockClientStubs', 'generateAccurest') then: "tasks should be reexecuted" - thirdExecutionResult.wasExecuted(":generateWireMockClientStubs") - thirdExecutionResult.wasExecuted(":generateAccurest") + validateTasksOutcome(thirdExecutionResult, SUCCESS, 'generateWireMockClientStubs', 'generateAccurest') and: "changes visible in generate files" file(GENERATED_CLIENT_JSON_STUB).text.contains("599") file(GENERATED_TEST).text.contains("599") } + } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy index df468fdfa7..0d4004ae11 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy @@ -6,7 +6,7 @@ import spock.lang.Stepwise class MessagingProjectSpec extends AccurestIntegrationSpec { void setup() { - copyResources("functionalTest/messagingProject", "") + setupForProject("functionalTest/messagingProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy index d314e6c526..82ab2a488e 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -6,9 +6,8 @@ import spock.lang.Stepwise class SampleJerseyProjectSpec extends AccurestIntegrationSpec { void setup() { - copyResources("functionalTest/sampleJerseyProject", "") - runTasksSuccessfully('clean') - //delete accidental output when previously importing SimpleBoot into Idea to tweak it + setupForProject("functionalTest/sampleJerseyProject") + runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } def "should pass basic flow for Spock"() { diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index fefe2d9869..451230ad85 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -6,7 +6,7 @@ import spock.lang.Stepwise class SampleProjectSpec extends AccurestIntegrationSpec { void setup() { - copyResources("functionalTest/sampleProject", "") + setupForProject("functionalTest/sampleProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy index 3b300a3ad7..620514dc3a 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy @@ -6,7 +6,7 @@ import spock.lang.Stepwise class ScenarioProjectSpec extends AccurestIntegrationSpec { void setup() { - copyResources("functionalTest/scenarioProject", "") + setupForProject("functionalTest/scenarioProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/build.gradle b/build.gradle index a58ce57c62..1035550b83 100644 --- a/build.gradle +++ b/build.gradle @@ -130,9 +130,7 @@ project(':accurest-gradle-plugin') { compile project(':accurest-converters') compile gradleApi() - testCompile('com.netflix.nebula:nebula-test:4.0.0') { - exclude(group: 'org.spockframework') - } + testCompile gradleTestKit() testCompile project(':accurest-testing-utils') } @@ -147,13 +145,50 @@ project(':accurest-gradle-plugin') { } } - // Hack for reusing this in the plugin test + task createClasspathManifest { + def outputDir = file("$buildDir/$name") + + inputs.files sourceSets.main.runtimeClasspath + outputs.dir outputDir + + doLast { + outputDir.mkdirs() + file("$outputDir/plugin-classpath.txt").text = sourceSets.test.runtimeClasspath.join("\n") + // Switch to 'sourceSets.main' after 'test.dependsOn's are removed + } + } + test.dependsOn(':accurest-core:install') test.dependsOn(':accurest-messaging-root:accurest-messaging-core:install') test.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install') + + funcTest.dependsOn(':accurest-core:install') + funcTest.dependsOn(':accurest-messaging-root:accurest-messaging-core:install') + funcTest.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install') + + // Add the classpath file to the test runtime classpath + dependencies { + testRuntime files(createClasspathManifest) + } + uploadArchives.dependsOn { funcTest } } task wrapper(type: Wrapper) { gradleVersion = '2.12' } + + +// REMOVE AFTER https://issues.gradle.org/browse/GRADLE-3433 IS FIXED +buildscript { + repositories { + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath "gradle.plugin.com.palantir.ideatestfix:gradle-idea-test-fix:0.1.0" + } +} + +apply plugin: "com.palantir.idea-test-fix" \ No newline at end of file From 230877f639333af17a68092373fdfaeffe8dd157 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 21:40:48 +0200 Subject: [PATCH 499/719] Removed automatic dependency adding if a user want to use messaging he has to pass a concrete dependency (either Camel, Integration, Stream or Core). We shouldn't enforce this dependency on the user. --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 1 - 1 file changed, 1 deletion(-) 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 ceb090dd99..6288fa93b4 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 @@ -31,7 +31,6 @@ class AccurestGradlePlugin implements Plugin { 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) From b3b08357c840e814b3b7397cea5a000d5b19086e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 22:24:08 +0200 Subject: [PATCH 500/719] Updated the docs --- accurest-messaging/README.adoc | 25 +++ docs/src/docs/asciidoc/index.adoc | 218 +++++++++++++------------- docs/src/docs/asciidoc/messaging.adoc | 44 ++++++ 3 files changed, 175 insertions(+), 112 deletions(-) create mode 100644 accurest-messaging/README.adoc create mode 100644 docs/src/docs/asciidoc/messaging.adoc diff --git a/accurest-messaging/README.adoc b/accurest-messaging/README.adoc new file mode 100644 index 0000000000..8bd09cb051 --- /dev/null +++ b/accurest-messaging/README.adoc @@ -0,0 +1,25 @@ += Accurest Messaging + +Accurest allows you to verify your application that uses messaging as means of communication. +All of our integrations are working with Spring but you can also set one yourself. + +== Integrations + +You can use one of the three integration configurations: + +- Apache Camel +- Spring Integration +- Spring Cloud Stream + +If you're using Spring Boot, the aforementioned test configurations will be appended automatically. + +== Manual Integration + +The `accurest-messaging-core` module contains 3 main interfaces: + +- AccurestMessage - describes a message received / sent to a channel / queue / topic etc. +- AccurestMessageBuilder - describes how to build a message +- AccurestMessaging - class that allows you to build, send and receive messages + +In the generated test the `AccurestMessaging` is injected via `@Inject` annotation thus you can + diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 8874ce9667..5b5d08e9e4 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,14 +1,8 @@ -http://:github-tag: master -:github-repo: Codearte/accurest -:github-raw: http://raw.github.com/{github-repo}/{github-tag} -:github-code: http://github.com/{github-repo}/tree/{github-tag} -:toc: left - Welcome to the AccuREST Wiki! Please follow to the Introduction page to start your journey with Consumer Driven Contracts in JVM -# 1. Introduction += 1. Introduction Just to make long story short - AccuREST is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by AccuREST to produce following resources: @@ -17,7 +11,7 @@ Just to make long story short - AccuREST is a tool that enables Consumer Driven AccuREST moves TDD to the level of software architecture. -# Why? += Why? The main purposes of AccuREST are: @@ -26,17 +20,17 @@ The main purposes of AccuREST are: - to provide a way to publish changes in contracts that are immediately visible on both sides, - to generate boilerplate test code used on the server side. -# 2. Using in your project += 2. Using in your project -## Prerequisites +== Prerequisites -# 2.1. Gradle Project += 2.1. Gradle Project -## Prerequisites +== Prerequisites In order to use Accurest with Wiremock you have to use gradle or maven plugin. -## Add gradle plugin +== Add gradle plugin [source,groovy,indent=0] ---- @@ -59,7 +53,7 @@ dependencies { } ---- -## Add maven plugin +== Add maven plugin [source,xml,indent=0] ---- @@ -81,7 +75,7 @@ dependencies { Read more: https://github.com/Codearte/accurest-maven-plugin[accurest-maven-plugin] -## Add stubs +== 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. @@ -95,11 +89,11 @@ Accurest will create test class `defaultBasePackage.MyService` with two methods - shouldCreateUser() - shouldReturnUser() -## Run plugin +== 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 +== Configure plugin To change default configuration just add `accurest` snippet to your Gradle config @@ -112,7 +106,7 @@ accurest { } ---- -### Configuration options +=== Configuration options - **testMode** - defines mode for acceptance tests. By default MockMvc which is based on Spring's MockMvc. It can also be changed to **JaxRsClient** or to **Explicit** for real HTTP calls. - **imports** - array with imports that should be included in generated tests (for example ['org.myorg.Matchers']). By default empty array [] @@ -126,7 +120,7 @@ accurest { - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework -## Base class for tests +== Base class for tests When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. @@ -147,12 +141,12 @@ class MvcSpec extends Specification { In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. -## Invoking generated tests +== Invoking generated tests To ensure that provider side is complaint with defined contracts, you need to invoke: `./gradlew generateAccurest test` -## Accurest on consumer side +== Accurest on consumer side In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/stubs and generate Wiremock json stubs using: `./gradlew generateWireMockClientStubs` command. Note that `stubsOutputDir` option has to be set for stub generation to work. @@ -185,9 +179,9 @@ class LoanApplicationServiceSpec extends Specification { Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. -# 2.2. Using in your Maven project += 2.2. Using in your Maven project -## Add maven plugin +== Add maven plugin [source,xml,indent=0] ---- @@ -208,7 +202,7 @@ Underneath LoanApplication makes a call to FraudDetection service. This request Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) -## Add stubs +== Add stubs By default Accurest is looking for stubs in `src/test/accurest` directory. Directory containing stub definitions is treated as a class name, and each stub definition is treated as a single test. @@ -225,11 +219,11 @@ Accurest will create test class `defaultBasePackage.MyService` with two methods - `shouldCreateUser()` - `shouldReturnUser()` -## Run plugin +== Run plugin Plugin goal `generateTests` is assigned to be invoked in phase `generate-test-sources`. 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 `generateTests` goal. -## Configure plugin +== Configure plugin To change default configuration just add `configuration` section to plugin definition or `execution` definition. @@ -254,7 +248,7 @@ To change default configuration just add `configuration` section to plugin defin ---- -### Configuration options +=== Configuration options - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. @@ -265,7 +259,7 @@ To change default configuration just add `configuration` section to plugin defin - **mappingsDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed. - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework -## Base class for tests +== Base class for tests When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. @@ -286,7 +280,7 @@ class MvcSpec extends Specification { In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. -## Invoking generated tests +== Invoking generated tests Accurest Maven Plugins generates verification code into directory `/generated-test-sources/accurest` and attach this directory to `testCompile` goal. @@ -326,7 +320,7 @@ For Groovy Spock code use: To ensure that provider side is complaint with defined contracts, you need to invoke `mvn generateTest test` -## Accurest on consumer side +== Accurest on consumer side In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. @@ -378,7 +372,7 @@ class LoanApplicationServiceSpec extends Specification { Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. -# 3. Contract DSL += 3. Contract DSL Contract DSL in AccuREST is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, AccuREST's DSL is designed to be programmer-readable without any knowledge of the DSL itself. @@ -414,7 +408,7 @@ Not all features of the DSL are used in example above. If you didn't find what y > You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. -## Top-Level Elements +== Top-Level Elements Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. @@ -442,7 +436,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -## Request +== Request HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of AccuREST contract. @@ -589,7 +583,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -## Response +== Response Minimal response must contain **HTTP status code**. @@ -609,7 +603,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { Besides status response may contain **headers** and **body**, which are specified the same way as in the request (see previous paragraph). -## Regular expressions +== Regular expressions You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both for your test and your server side tests. Please see the example below: @@ -645,7 +639,7 @@ io.codearte.accurest.dsl.GroovyDsl groovyDsl = GroovyDsl.make { } ---- -## Passing optional parameters +== Passing optional parameters It is possible to provide optional parameters in your contract. It's only possible to have optional parameter for the: @@ -737,10 +731,10 @@ and the following stub: } ---- -## Executing custom methods on server side +== Executing custom methods on server side It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. Please see the examples below: -### Groovy DSL +=== Groovy DSL [source,groovy,indent=0] ---- @@ -767,7 +761,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -### Base Mock Spec +=== Base Mock Spec [source,groovy,indent=0] ---- @@ -783,7 +777,7 @@ abstract class BaseMockMvcSpec extends Specification { } ---- -## JAX-RS support +== JAX-RS support Starting with release 0.8.0 we support JAX-RS 2 Client API. Base class needs to define `protected WebTarget webTarget` and server initialization, right now the only option how to test JAX-RS API is to start a web server. Request with a body needs to have a content type set otherwise `application/octet-stream` is going to be used. @@ -840,7 +834,7 @@ class FraudDetectionServiceSpec extends MvcSpec { } ---- -# 4. Client Side += 4. Client Side 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 @@ -849,7 +843,7 @@ to be valid from the Wiremock's perspective but should also be reusable on the s __Summing it up:__ On this side, in the stub definition, you can use patterns for request stubbing and you need exact values for responses. -# 5. Server Side += 5. Server Side 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 @@ -861,7 +855,7 @@ 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. -# 6. Examples += 6. Examples [source,groovy,indent=0] ---- @@ -909,7 +903,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -# 7. Scenarios += 7. Scenarios It's possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore. @@ -930,17 +924,17 @@ More details about Wiremock scenarios can be found under [http://wiremock.org/st Accurest will also generate tests with guaranteed order of execution. -# 8. Stub Runner += 8. Stub Runner One of the issues that you could have encountered while using AccuREST was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). Copying the JSON files manually is out of the question. In this article you'll see how to prepare your project to start publishing stubs as JARs and how to use Stub Runner in your tests to run WireMock servers and feed them with stub definitions. -## Publishing stubs as JARs +== Publishing stubs as JARs The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository. -### Gradle +=== Gradle Example of AccuREST Gradle setup: @@ -981,15 +975,15 @@ Example of AccuREST Gradle setup: } ---- -### Maven +=== Maven -Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/#publishing-wiremock-stubs-projectf-stubsjar) +Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) -## Using Stub Runner to automate running stubs +== Using Stub Runner to automate running stubs Stub Runner automates downloading stubs from a Maven repository (that includes also the local Maven repository) and starting the WireMock server for each of those stubs. -### Modules +=== Modules AccuREST comes with a new structure of modules @@ -1002,7 +996,7 @@ AccuREST comes with a new structure of modules └── stub-runner-spring-cloud ---- -#### Stub Runner +==== Stub Runner Contains core logic of Stub Runner. Gives you a main class to run Stub Runner from the command line or from Gradle. @@ -1041,7 +1035,7 @@ or each parameter separately with a `-P` prefix and without the hyphen (-) in th `./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h` -#### Stub Runner JUnit Rule +==== Stub Runner JUnit Rule Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id: @@ -1146,7 +1140,7 @@ Example of usage in JUnit tests: Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. -#### Stub Runner Spring +==== Stub Runner Spring If you're using Spring then you can just import the `io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration` and a bean of type `StubFinder` will get registered. @@ -1183,11 +1177,11 @@ class StubRunnerConfigurationSpec extends Specification { Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. -#### Stub Runner Spring Cloud +==== Stub Runner Spring Cloud If you're using Spring Cloud then it's enough to add `stub-runner-spring-cloud` on classpath and automatically a bean of type `StubFinder` will get registered. -#### Common properties for JUnit and Spring +==== Common properties for JUnit and Spring Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values: @@ -1202,12 +1196,12 @@ Some of the properties that are repetitive can be set using system properties or |stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| |====================== -# 9. Migration Guide += 9. Migration Guide -# Migration to 0.4.7 += Migration to 0.4.7 - in 0.4.7 we've fixed package name (coderate to codearte) so you've to do the same in your projects. This means replacing ```io.coderate.accurest.dsl.GroovyDsl``` with ```io.codearte.accurest.dsl.GroovyDsl``` -# Migration to 1.0.0-RC1 += Migration to 1.0.0-RC1 - from 1.0.0 we're distinguish ignored contracts from excluded contracts: - `excludedFiles` pattern tells Accurest to skip processing those files at all - `ignoredFiles` pattern tells Accurest to generate contracts and tests, but tests will be marked as `@Ignore` @@ -1225,7 +1219,7 @@ Welcome to the AccuREST Wiki! Please follow to the Introduction page to start your journey with Consumer Driven Contracts in JVM -# 1. Introduction += 1. Introduction Just to make long story short - AccuREST is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by AccuREST to produce following resources: * JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by AccuREST. @@ -1233,7 +1227,7 @@ Just to make long story short - AccuREST is a tool that enables Consumer Driven AccuREST moves TDD to the level of software architecture. -# Why? += Why? The main purposes of AccuREST are: @@ -1242,19 +1236,19 @@ The main purposes of AccuREST are: - to provide a way to publish changes in contracts that are immediately visible on both sides, - to generate boilerplate test code used on the server side. -# 2. Using in your project += 2. Using in your project -## Prerequisites +== Prerequisites In order to use Accurest with Wiremock you have to have Wiremock in version at least **2.0.0-beta** . Of course the higher the better :) -# 2.1. Gradle Project += 2.1. Gradle Project -## Prerequisites +== Prerequisites In order to use Accurest with Wiremock you have to have Wiremock in version at least **2.0.0-beta** . Of course the higher the better :) -## Add gradle plugin +== Add gradle plugin [source,groovy,indent=0] ---- @@ -1277,7 +1271,7 @@ dependencies { } ---- -## Add maven plugin +== Add maven plugin [source,xml,indent=0] ---- @@ -1298,7 +1292,7 @@ dependencies { Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) -## Add stubs +== 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. @@ -1312,11 +1306,11 @@ Accurest will create test class `defaultBasePackage.MyService` with two methods - shouldCreateUser() - shouldReturnUser() -## Run plugin +== 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 +== Configure plugin To change default configuration just add `accurest` snippet to your Gradle config @@ -1329,7 +1323,7 @@ accurest { } ---- -### Configuration options +=== Configuration options - **testMode** - defines mode for acceptance tests. By default MockMvc which is based on Spring's MockMvc. It can also be changed to **JaxRsClient** or to **Explicit** for real HTTP calls. - **imports** - array with imports that should be included in generated tests (for example ['org.myorg.Matchers']). By default empty array [] @@ -1343,7 +1337,7 @@ accurest { - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework -## Base class for tests +== Base class for tests When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. @@ -1364,12 +1358,12 @@ class MvcSpec extends Specification { In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. -## Invoking generated tests +== Invoking generated tests To ensure that provider side is complaint with defined contracts, you need to invoke: `./gradlew generateAccurest test` -## Accurest on consumer side +== Accurest on consumer side In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/stubs and generate Wiremock json stubs using: `./gradlew generateWireMockClientStubs` command. Note that `stubsOutputDir` option has to be set for stub generation to work. @@ -1402,9 +1396,9 @@ class LoanApplicationServiceSpec extends Specification { Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. -# 2.2. Using in your Maven project += 2.2. Using in your Maven project -## Add maven plugin +== Add maven plugin [source,xml,indent=0] ---- @@ -1425,7 +1419,7 @@ Underneath LoanApplication makes a call to FraudDetection service. This request Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) -## Add stubs +== Add stubs By default Accurest is looking for stubs in `src/test/accurest` directory. Directory containing stub definitions is treated as a class name, and each stub definition is treated as a single test. @@ -1442,11 +1436,11 @@ Accurest will create test class `defaultBasePackage.MyService` with two methods - `shouldCreateUser()` - `shouldReturnUser()` -## Run plugin +== Run plugin Plugin goal `generateTests` is assigned to be invoked in phase `generate-test-sources`. 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 `generateTests` goal. -## Configure plugin +== Configure plugin To change default configuration just add `configuration` section to plugin definition or `execution` definition. @@ -1471,7 +1465,7 @@ To change default configuration just add `configuration` section to plugin defin ---- -### Configuration options +=== Configuration options - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. @@ -1482,7 +1476,7 @@ To change default configuration just add `configuration` section to plugin defin - **mappingsDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed. - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework -## Base class for tests +== Base class for tests When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. @@ -1503,7 +1497,7 @@ class MvcSpec extends Specification { In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. -## Invoking generated tests +== Invoking generated tests Accurest Maven Plugins generates verification code into directory `/generated-test-sources/accurest` and attach this directory to `testCompile` goal. @@ -1543,7 +1537,7 @@ For Groovy Spock code use: To ensure that provider side is complaint with defined contracts, you need to invoke `mvn generateTest test` -## Accurest on consumer side +== Accurest on consumer side In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. @@ -1595,7 +1589,7 @@ class LoanApplicationServiceSpec extends Specification { Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. -# 3. Contract DSL += 3. Contract DSL Contract DSL in AccuREST is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, AccuREST's DSL is designed to be programmer-readable without any knowledge of the DSL itself. @@ -1631,7 +1625,7 @@ Not all features of the DSL are used in example above. If you didn't find what y > You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. -## Top-Level Elements +== Top-Level Elements Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. @@ -1659,7 +1653,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -## Request +== Request HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of AccuREST contract. @@ -1806,7 +1800,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -## Response +== Response Minimal response must contain **HTTP status code**. @@ -1826,7 +1820,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { Besides status response may contain **headers** and **body**, which are specified the same way as in the request (see previous paragraph). -## Regular expressions +== Regular expressions You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both for your test and your server side tests. Please see the example below: @@ -1862,7 +1856,7 @@ io.codearte.accurest.dsl.GroovyDsl groovyDsl = GroovyDsl.make { } ---- -## Passing optional parameters +== Passing optional parameters It is possible to provide optional parameters in your contract. It's only possible to have optional parameter for the: @@ -1954,10 +1948,10 @@ and the following stub: } ---- -## Executing custom methods on server side +== Executing custom methods on server side It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. Please see the examples below: -### Groovy DSL +=== Groovy DSL [source,groovy,indent=0] ---- @@ -1984,7 +1978,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -### Base Mock Spec +=== Base Mock Spec [source,groovy,indent=0] ---- @@ -2000,7 +1994,7 @@ abstract class BaseMockMvcSpec extends Specification { } ---- -## JAX-RS support +== JAX-RS support Starting with release 0.8.0 we support JAX-RS 2 Client API. Base class needs to define `protected WebTarget webTarget` and server initialization, right now the only option how to test JAX-RS API is to start a web server. Request with a body needs to have a content type set otherwise `application/octet-stream` is going to be used. @@ -2057,7 +2051,7 @@ class FraudDetectionServiceSpec extends MvcSpec { } ---- -# 4. Client Side += 4. Client Side 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 @@ -2066,7 +2060,7 @@ to be valid from the Wiremock's perspective but should also be reusable on the s __Summing it up:__ On this side, in the stub definition, you can use patterns for request stubbing and you need exact values for responses. -# 5. Server Side += 5. Server Side 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 @@ -2078,7 +2072,7 @@ 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. -# 6. Examples += 6. Examples [source,groovy,indent=0] ---- @@ -2126,7 +2120,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -# 7. Scenarios += 7. Scenarios It's possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore. @@ -2147,17 +2141,17 @@ More details about Wiremock scenarios can be found under [http://wiremock.org/st Accurest will also generate tests with guaranteed order of execution. -# 8. Stub Runner += 8. Stub Runner One of the issues that you could have encountered while using AccuREST was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). Copying the JSON files manually is out of the question. In this article you'll see how to prepare your project to start publishing stubs as JARs and how to use Stub Runner in your tests to run WireMock servers and feed them with stub definitions. -## Publishing stubs as JARs +== Publishing stubs as JARs The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository. -### Gradle +=== Gradle Example of AccuREST Gradle setup: @@ -2198,15 +2192,15 @@ Example of AccuREST Gradle setup: } ---- -### Maven +=== Maven -Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/#publishing-wiremock-stubs-projectf-stubsjar) +Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) -## Using Stub Runner to automate running stubs +== Using Stub Runner to automate running stubs Stub Runner automates downloading stubs from a Maven repository (that includes also the local Maven repository) and starting the WireMock server for each of those stubs. -### Modules +=== Modules AccuREST comes with a new structure of modules @@ -2219,7 +2213,7 @@ AccuREST comes with a new structure of modules └── stub-runner-spring-cloud ---- -#### Stub Runner +==== Stub Runner Contains core logic of Stub Runner. Gives you a main class to run Stub Runner from the command line or from Gradle. @@ -2258,7 +2252,7 @@ or each parameter separately with a `-P` prefix and without the hyphen (-) in th `./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h` -#### Stub Runner JUnit Rule +==== Stub Runner JUnit Rule Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id: @@ -2363,7 +2357,7 @@ Example of usage in JUnit tests: Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. -#### Stub Runner Spring +==== Stub Runner Spring If you're using Spring then you can just import the `io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration` and a bean of type `StubFinder` will get registered. @@ -2400,11 +2394,11 @@ class StubRunnerConfigurationSpec extends Specification { Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. -#### Stub Runner Spring Cloud +==== Stub Runner Spring Cloud If you're using Spring Cloud then it's enough to add `stub-runner-spring-cloud` on classpath and automatically a bean of type `StubFinder` will get registered. -#### Common properties for JUnit and Spring +==== Common properties for JUnit and Spring Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values: @@ -2419,12 +2413,12 @@ Some of the properties that are repetitive can be set using system properties or |stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| |====================== -# 9. Migration Guide += 9. Migration Guide -# Migration to 0.4.7 += Migration to 0.4.7 - in 0.4.7 we've fixed package name (coderate to codearte) so you've to do the same in your projects. This means replacing ```io.coderate.accurest.dsl.GroovyDsl``` with ```io.codearte.accurest.dsl.GroovyDsl``` -# Migration to 1.0.0-RC1 += Migration to 1.0.0-RC1 - from 1.0.0 we're distinguish ignored contracts from excluded contracts: - `excludedFiles` pattern tells Accurest to skip processing those files at all - `ignoredFiles` pattern tells Accurest to generate contracts and tests, but tests will be marked as `@Ignore` diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc new file mode 100644 index 0000000000..48d67d5216 --- /dev/null +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -0,0 +1,44 @@ += Accurest Messaging + +Accurest allows you to verify your application that uses messaging as means of communication. +All of our integrations are working with Spring but you can also set one yourself. + +== Integrations + +You can use one of the three integration configurations: + +- Apache Camel +- Spring Integration +- Spring Cloud Stream + +If you're using Spring Boot, the aforementioned test configurations will be appended automatically. + +You have to provide as a dependency one of the Accurest Messaging modules. Example for Gradle: + +[source,groovy,indent=0] +---- +// for Apache Camel +testCompile "io.codearte.accurest:accurest-messaging-camel:${accurestVersion}" +// for Spring Integration +testCompile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}" +// for Spring Cloud Stream +testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}" +---- + +== Manual Integration + +The `accurest-messaging-core` module contains 3 main interfaces: + +- AccurestMessage - describes a message received / sent to a channel / queue / topic etc. +- AccurestMessageBuilder - describes how to build a message +- AccurestMessaging - class that allows you to build, send and receive messages + +In the generated test the `AccurestMessaging` is injected via `@Inject` annotation thus you can use other injection +frameworks than Spring. + +You have to provide as a dependency the `accurest-messaging-core` module. Example for Gradle: + +[source,groovy,indent=0] +---- +testCompile "io.codearte.accurest:accurest-messaging-core:${accurestVersion}" +---- \ No newline at end of file From 628542f2a9c03dd75ff9d87c03189db3e9d92b36 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 22:27:02 +0200 Subject: [PATCH 501/719] Removed duplicated docs --- docs/src/docs/asciidoc/index.adoc | 1219 +---------------------------- 1 file changed, 1 insertion(+), 1218 deletions(-) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 5b5d08e9e4..42f57e8f79 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1209,1221 +1209,4 @@ Some of the properties that are repetitive can be set using system properties or - from 1.0.0 the `basePackageForTests` behaviour has changed - prior to the change all DSL files had to be under `contractsDslDir`/`basePackageForTests`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - now all DSL files have to be under `contractsDslDir`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage*[:github-tag: master -:github-repo: Codearte/accurest -:github-raw: http://raw.github.com/{github-repo}/{github-tag} -:github-code: http://github.com/{github-repo}/tree/{github-tag} -:toc: left - -Welcome to the AccuREST Wiki! - -Please follow to the Introduction page to start your journey with Consumer Driven Contracts in JVM - -= 1. Introduction - -Just to make long story short - AccuREST is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by AccuREST to produce following resources: -* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by AccuREST. -* Acceptance tests (in Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by AccuREST. - -AccuREST moves TDD to the level of software architecture. - -= Why? - -The main purposes of AccuREST are: - - - to ensure that WireMock stubs (used when developing the client) are doing exactly what actual server-side implementation will do, - - to promote ATDD method and Microservices architectural style, - - to provide a way to publish changes in contracts that are immediately visible on both sides, - - to generate boilerplate test code used on the server side. - -= 2. Using in your project - -== Prerequisites - -In order to use Accurest with Wiremock you have to have Wiremock in version at least **2.0.0-beta** . Of course the higher the better :) - -= 2.1. Gradle Project - -== Prerequisites - -In order to use Accurest with Wiremock you have to have Wiremock in version at least **2.0.0-beta** . Of course the higher the better :) - -== Add gradle plugin - -[source,groovy,indent=0] ----- -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'io.codearte.accurest:accurest-gradle-plugin:0.9.9' - } -} - -apply plugin: 'accurest' - -dependencies { - testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' - testCompile 'com.github.tomakehurst:wiremock:2.0.4-beta' // you have to use WireMock with 2.0 versions of JsonPath - testCompile 'com.jayway.restassured:rest-assured:2.4.1' - testCompile 'com.jayway.restassured:spring-mock-mvc:2.4.1' // needed if you're going to use Spring MockMvc -} ----- - -== Add maven plugin - -[source,xml,indent=0] ----- - - io.codearte.accurest - accurest-maven-plugin - - - - generateStubs - generateTests // for JUnit tests, use generateSpecs for Spock Specification - - - - ----- - - -Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) - -== 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.groovy -src/test/resources/stubs/myservice/shouldReturnUser.groovy - -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 - -[source,groovy,indent=0] ----- -accurest { - testMode = 'MockMvc' - baseClassForTests = 'org.mycompany.tests' - generatedTestSourcesDir = project.file('src/accurest') -} ----- - -=== Configuration options - - - **testMode** - defines mode for acceptance tests. By default MockMvc which is based on Spring's MockMvc. It can also be changed to **JaxRsClient** or to **Explicit** for real HTTP calls. - - **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 [] - - **basePackageForTests** - specifies base package for all generated tests. By default set to io.codearte.accurest.tests - - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` - - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - - **ignoredFiles** - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array [] - - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/accurest` - - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `$buildDir/generated-test-sources/accurest` - - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed - - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework - -== Base class for tests - - When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. - -[source,groovy,indent=0] ----- -package org.mycompany.tests - -import org.mycompany.ExampleSpringController -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new ExampleSpringController()) - } -} ----- - -In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. - -== Invoking generated tests - -To ensure that provider side is complaint with defined contracts, you need to invoke: -`./gradlew generateAccurest test` - -== Accurest on consumer side - -In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/stubs and generate Wiremock json stubs using: `./gradlew generateWireMockClientStubs` command. Note that `stubsOutputDir` option has to be set for stub generation to work. - -When present, json stubs can be used in consumer automated tests. - -[source,groovy,indent=0] ----- -@ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) -class LoanApplicationServiceSpec extends Specification { - - @ClassRule - @Shared - WireMockClassRule wireMockRule = new WireMockClassRule() - - @Autowired - LoanApplicationService sut - - def 'should successfully apply for loan'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED - loanApplication.rejectionReason == null - } -} ----- - -Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. - -= 2.2. Using in your Maven project - -== Add maven plugin - -[source,xml,indent=0] ----- - - io.codearte.accurest - accurest-maven-plugin - - - - convert - generateStubs - generateTests - - - - ----- - -Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) - -== Add stubs - -By default Accurest is looking for stubs in `src/test/accurest` 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 - -[source,groovy,indent=0] ----- -src/test/accurest/myservice/shouldCreateUser.groovy -src/test/accurest/myservice/shouldReturnUser.groovy ----- - -Accurest will create test class `defaultBasePackage.MyService` with two methods - - `shouldCreateUser()` - - `shouldReturnUser()` - -== Run plugin - -Plugin goal `generateTests` is assigned to be invoked in phase `generate-test-sources`. 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 `generateTests` goal. - -== Configure plugin - -To change default configuration just add `configuration` section to plugin definition or `execution` definition. - -[source,xml,indent=0] ----- - - io.codearte.accurest - accurest-maven-plugin - - - - convert - generateStubs - generateTests - - - - - com.ofg.twitter.place - com.ofg.twitter.place.BaseMockMvcSpec - - ----- - -=== Configuration options - - - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. - - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. - - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification`. - - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/accurest`. - - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `target/generated-test-sources/accurest`. - - **mappingsDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed. - - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework - -== Base class for tests - - When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. - -[source,groovy,indent=0] ----- -package org.mycompany.tests - -import org.mycompany.ExampleSpringController -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new ExampleSpringController()) - } -} ----- - -In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. - -== Invoking generated tests - -Accurest Maven Plugins generates verification code into directory `/generated-test-sources/accurest` and attach this directory to `testCompile` goal. - -For Groovy Spock code use: - -[source,xml,indent=0] ----- - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.5 - - - - testCompile - - - - - - - ${project.basedir}/src/test/groovy - - **/*.groovy - - - - ${project.build.directory}/generated-test-sources/accurest - - **/*.groovy - - - - - ----- - -To ensure that provider side is complaint with defined contracts, you need to invoke `mvn generateTest test` - -== Accurest on consumer side - -In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. - -Sample configuration: - -[source,xml,indent=0] ----- - - io.codearte.accurest - accurest-maven-plugin - ${accurest.version} - - - - convert - generateStubs - - - - ----- - -When present, json stubs can be used in consumer automated tests. - -[source,groovy,indent=0] ----- -@ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) -class LoanApplicationServiceSpec extends Specification { - - @ClassRule - @Shared - WireMockClassRule wireMockRule = new WireMockClassRule() - - @Autowired - LoanApplicationService sut - - def 'should successfully apply for loan'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED - loanApplication.rejectionReason == null - } -} ----- - -Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. - -= 3. Contract DSL - -Contract DSL in AccuREST is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, AccuREST's DSL is designed to be programmer-readable without any knowledge of the DSL itself. - -Let's look at full example of a contract definition. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'POST' - urlPath('/users') { - queryParameters { - parameter 'limit': 100 - parameter 'offset': containing("1") - parameter 'filter': "email" - } - } - headers { - header 'Content-Type': 'application/json' - } - body '''{ "login" : "john", "name": "John The Contract" }''' - } - response { - status 200 - headers { - header 'Location': '/users/john' - } - } -} ----- - -Not all features of the DSL are used in example above. If you didn't find what you are looking for, please check next paragraphs on this page. - -> You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. - -== Top-Level Elements - -Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - // Definition of HTTP request part of the contract - // (this can be a valid request or invalid depending - // on type of contract being specified). - request { - ... - } - - // Definition of HTTP response part of the contract - // (a service implementing this contract should respond - // with following response after receiving request - // specified in "request" part above). - response { - ... - } - - // Contract priority, which can be used for overriding - // contracts (1 is highest). Priority is optional. - priority 1 -} ----- - -== Request - -HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of AccuREST contract. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - // HTTP request method (GET/POST/PUT/DELETE). - method 'GET' - - // Path component of request URL is specified as follows. - urlPath('/users') - } - - response { - ... - } -} ----- - -It is possible to specify whole `url` instead of just path, but `urlPath` is the recommended way as it makes the tests **host-independent**. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'GET' - - // Specifying `url` and `urlPath` in one contract is illegal. - url('http://localhost:8888/users') - } - - response { - ... - } -} ----- - -Request may contain **query parameters**, which are specified in a closure nested in a call to `urlPath` or `url`. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - urlPath('/users') { - - // Each parameter is specified in form - // `'paramName' : paramValue` where parameter value - // may be a simple literal or one of matcher functions, - // all of which are used in this example. - queryParameters { - - // If a simple literal is used as value - // default matcher function is used (equalTo) - parameter 'limit': 100 - - // `equalTo` function simply compares passed value - // using identity operator (==). - parameter 'filter': equalTo("email") - - // `containing` function matches strings - // that contains passed substring. - parameter 'gender': containing("[mf]") - - // `matching` function tests parameter - // against passed regular expression. - parameter 'offset': matching("[0-9]+") - - // `notMatching` functions tests if parameter - // does not match passed regular expression. - parameter 'loginStartsWith': notMatching(".{0,2}") - } - } - - ... - } - - response { - ... - } -} ----- - -It may contain additional **request headers**... - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // Each header is added in form `'Header-Name' : 'Header-Value'`. - headers { - header 'Content-Type': 'application/json' - } - - ... - } - - response { - ... - } -} ----- - -...and a **request body**. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // JSON and XML formats of request body are supported. - // Format will be determined from a header or body's content. - body '''{ "login" : "john", "name": "John The Contract" }''' - } - - response { - ... - } -} ----- - -**Body's format** can also be specified explicitly by invoking one of format functions. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // In this case body will be formatted as XML. - body equalToXml( - '''johnJohn The Contract''' - ) - } - - response { - ... - } -} ----- - -== Response - -Minimal response must contain **HTTP status code**. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - } - response { - // Status code sent by the server - // in response to request specified above. - status 200 - } -} ----- - -Besides status response may contain **headers** and **body**, which are specified the same way as in the request (see previous paragraph). - -== Regular expressions -You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both for your test and your server side tests. - - Please see the example below: - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl groovyDsl = GroovyDsl.make { - request { - method('GET') - url $(client(~/\/[0-9]{2}/), server('/12')) - } - response { - status 200 - body( - id: value( - client('123'), - server(regex('[0-9]+')) - ), - surname: $( - client('Kowalsky'), - server('Lewandowski') - ), - name: 'Jan', - created: $(client('2014-02-02 12:23:43'), server({ currentDate(it) })) - correlationId: value(client('5d1f9fef-e0dc-4f3d-a7e4-72d2220dd827'), - server(regex('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') - ) - ) - headers { - header 'Content-Type': 'text/plain' - } - } -} ----- - -== Passing optional parameters - -It is possible to provide optional parameters in your contract. It's only possible to have optional parameter for the: - -- __STUB__ side of the Request -- __TEST__ side of the Response - -Example: - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - email: $(stub(optional(regex(email()))), test('abc@abc.com')), - callback_url: $(stub(regex(hostname())), test('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: value(stub("123123"), test(optional("123123"))), - message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" - ) - } -} ----- - -By wrapping a part of the body with the `optional()` method you are in fact creating a regular expression that should be present 0 or more times. - -That way for the example above the following test would be generated: - -[source,groovy,indent=0] ----- - given: - def request = given() - .header('Content-Type', 'application/json') - .body('{"email":"abc@abc.com","callback_url":"http://partners.com"}') - - when: - def response = given().spec(request) - .post("/users/password") - - then: - response.statusCode == 404 - response.header('Content-Type') == 'application/json' - and: - DocumentContext parsedJson = JsonPath.parse(response.body.asString()) - !parsedJson.read('''$[?(@.code =~ /(123123)?/)]''', JSONArray).empty - !parsedJson.read('''$[?(@.message =~ /User not found by email = \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]''', JSONArray).empty - ----- - -and the following stub: - -[source,javascript,indent=0] ----- -{ - "request" : { - "url" : "/users/password", - "method" : "POST", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/)]" - }, { - "matchesJsonPath" : "$[?(@.email =~ /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4})?/)]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - } - }, - "response" : { - "status" : 404, - "body" : "{\"code\":\"123123\",\"message\":\"User not found by email = [not.existing@user.com]\"}", - "headers" : { - "Content-Type" : "application/json" - } - }, - "priority" : 1 -} ----- - -== Executing custom methods on server side -It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. Please see the examples below: - -=== Groovy DSL - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - body ( - path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), - correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) - ) - status 200 - } -} ----- - -=== Base Mock Spec - -[source,groovy,indent=0] ----- -abstract class BaseMockMvcSpec extends Specification { - - def setup() { - RestAssuredMockMvc.standaloneSetup(new PairIdController()) - } - - void isProperCorrelationId(Integer correlationId) { - assert correlationId == 123456 - } -} ----- - -== JAX-RS support -Starting with release 0.8.0 we support JAX-RS 2 Client API. Base class needs to define `protected WebTarget webTarget` and server initialization, right now the only option how to test JAX-RS API is to start a web server. - -Request with a body needs to have a content type set otherwise `application/octet-stream` is going to be used. - -In order to use JAX-RS mode, use the following settings: - -[source,groovy,indent=0] ----- -testMode = 'JAXRSCLIENT' ----- - -Example of a test API generated: - -[source,groovy,indent=0] ----- -class FraudDetectionServiceSpec extends MvcSpec { - - def shouldMarkClientAsNotFraud() { - when: - def response = webTarget - .path('/fraudcheck') - .request() - .method('put', entity('{"clientPesel":"1234567890","loanAmount":123.123}', 'application/vnd.fraud.v1+json')) - - String responseAsString = response.readEntity(String) - - then: - response.status == 200 - response.getHeaderString('Content-Type') == 'application/vnd.fraud.v1+json' - and: - def responseBody = new JsonSlurper().parseText(responseAsString) - responseBody.fraudCheckStatus == "OK" - assertThatRejectionReasonIsNull(responseBody.rejectionReason) - } - - def shouldMarkClientAsFraud() { - when: - def response = webTarget - .path('/fraudcheck') - .request() - .method('put', entity('{"clientPesel":"1234567890","loanAmount":99999}', 'application/vnd.fraud.v1+json')) - - String responseAsString = response.readEntity(String) - - then: - response.status == 200 - response.getHeaderString('Content-Type') == 'application/vnd.fraud.v1+json' - and: - def responseBody = new JsonSlurper().parseText(responseAsString) - responseBody.fraudCheckStatus ==~ java.util.regex.Pattern.compile('[A-Z]{5}') - responseBody.rejectionReason == "Amount too high" - } - -} ----- - -= 4. Client Side - -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. - -= 5. Server Side - -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. - -= 6. Examples - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/api/12' - headers { - header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json' - } - body '''\ - [{ - "created_at": "Sat Jul 26 09:38:57 +0000 2014", - "id": 492967299297845248, - "id_str": "492967299297845248", - "text": "Gonna see you at Warsaw", - "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" - } - }] -''' - } - response { - status 200 - } -} ----- - -= 7. Scenarios - -It's possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore. - -[source,indent=0] ----- -my_contracts_dir\ - scenario1\ - 1_login.groovy - 2_showCart.groovy - 3_logout.groovy ----- - -Such tree will cause Accurest generating Wiremock's scenario with name `scenario1` and three steps: - - login marked as `Started` pointing to: - - showCart marked as `Step1` pointing to: - - logout marked as `Step2` which will close the scenario. -More details about Wiremock scenarios can be found under [http://wiremock.org/stateful-behaviour.html](http://wiremock.org/stateful-behaviour.html) - -Accurest will also generate tests with guaranteed order of execution. - -= 8. Stub Runner - -One of the issues that you could have encountered while using AccuREST was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). Copying the JSON files manually is out of the question. - -In this article you'll see how to prepare your project to start publishing stubs as JARs and how to use Stub Runner in your tests to run WireMock servers and feed them with stub definitions. - -== Publishing stubs as JARs - -The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository. - -=== Gradle - -Example of AccuREST Gradle setup: - -[source,groovy,indent=0] ----- - apply plugin: 'maven-publish' - - ext { - wiremockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wiremockStubsOutputDir = new File(wiremockStubsOutputDirRoot) - } - - accurest { - targetFramework = 'Spock' - testMode = 'MockMvc' - baseClassForTests = 'com.toomuchcoding.MvcSpec' - contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") - generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") - stubsOutputDir = wiremockStubsOutputDir - } - - task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs"]) { - baseName = "${project.name}-stubs" - from wiremockStubsOutputDirRoot - } - - artifacts { - archives stubsJar - } - - publishing { - publications { - stubs(MavenPublication) { - artifactId "${project.name}-stubs" - artifact stubsJar - } - } - } ----- - -=== Maven - -Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) - -== Using Stub Runner to automate running stubs - -Stub Runner automates downloading stubs from a Maven repository (that includes also the local Maven repository) and starting the WireMock server for each of those stubs. - -=== Modules - -AccuREST comes with a new structure of modules - -[source,indent=0] ----- -└── stub-runner - ├── stub-runner - ├── stub-runner-junit - ├── stub-runner-spring - └── stub-runner-spring-cloud ----- - -==== Stub Runner - -Contains core logic of Stub Runner. Gives you a main class to run Stub Runner from the command line or from Gradle. - -Here you can see a list of options with which you can run Stub Runner: - -[source,indent=0] ----- -java -jar stub-runner.jar [options...] - -maxp (--maxPort) N : Maximum port value to be assigned to the - Wiremock instance. Defaults to 15000 - (default: 15000) - -minp (--minPort) N : Minimal port value to be assigned to the - Wiremock instance. Defaults to 10000 - (default: 10000) - -s (--stubs) VAL : Comma separated list of Ivy representation of - jars with stubs. Eg. groupid:artifactid1,group - id2:artifactid2:classifier - -sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you - keep your stubs (e.g. http://nexus.net/content - /repositories/repository) - -ss (--stubsSuffix) VAL : Suffix for the jar containing stubs (e.g. - 'stubs' if the stub jar would have a 'stubs' - classifier for stubs: foobar-stubs ). - Defaults to 'stubs' (default: stubs) - -wo (--workOffline) : Switch to work offline. Defaults to 'false' - (default: false) ----- - -You can either produce a fat-jar and run the app like presented above. - -You can also configure the stub runner by either passing the full arguments list with the `-Pargs` like this: - -`./gradlew stub-runner-root:stub-runner:run -Pargs="-c pl -minp 10000 -maxp 10005 -s a:b:c,d:e,f:g:h"` - -or each parameter separately with a `-P` prefix and without the hyphen (-) in the name of the param - -`./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h` - -==== Stub Runner JUnit Rule - -Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id: - -[source,java,indent=0] ----- -@ClassRule public static AccurestRule rule = new AccurestRule() - .repoRoot("http://your.repo.com") - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") - .downloadStub("io.codearte:stub1", "io.codearte:stub2:classifier", "io.codearte:stub3"); ----- - -After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to: -* download them -* cache them locally -* unzip them to a temporary folder -* start a WireMock server for each Maven dependency on a random port from the provided range of ports -* feed the WireMock server with all JSON files that are valid WireMock definitions - -Stub Runner uses [Groovy's Grape](http://docs.groovy-lang.org/latest/html/documentation/grape.html) mechanism to download the Maven dependencies. Check their [docs](http://docs.groovy-lang.org/latest/html/documentation/grape.html) for more information. - -Since the `AccurestRule` implements the `StubFinder` it allows you to find the started stubs: - -[source,groovy,indent=0] ----- -interface StubFinder { - /** - * For the given groupId and artifactId tries to find the matching - * URL of the running stub. - * - * @param groupId - might be null. In that case a search only via artifactId takes place - * @return URL of a running stub or null if not found - */ - URL findStubUrl(String groupId, String artifactId) - - /** - * For the given Ivy notation {@code groupId:artifactId} tries to find the matching - * URL of the running stub. You can also pass only {@code artifactId}. - * - * @param ivyNotation - Ivy representation of the Maven artifact - * @return URL of a running stub or null if not found - */ - URL findStubUrl(String ivyNotation) - - /** - * Returns all running stubs - */ - RunningStubs findAllRunningStubs() -} ----- - -Example of usage in Spock tests: - -[source,groovy,indent=0] ----- -@ClassRule @Shared AccurestRule rule = new AccurestRule() - .repoRoot('http://your.repo.com') - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - rule.findStubUrl('loanIssuance') != null - rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null - and: - rule.findAllRunningStubs().isPresent('loanIssuance') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' - } ----- - -Example of usage in JUnit tests: - -[source,java,indent=0] ----- -@ClassRule public static AccurestRule rule = new AccurestRule() - .repoRoot("http://your.repo.com") - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); - - @Test - public void should_start_wiremock_servers() throws Exception { - // expect: 'WireMocks are running' - then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")); - then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull(); - // and: - then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue(); - // and: 'Stubs were registered' - then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); - then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); - } ----- - -Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. - -==== Stub Runner Spring - -If you're using Spring then you can just import the `io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration` and a bean of type `StubFinder` will get registered. - -In order to find a URL and port of a given dependency you can autowire the bean in your test and call its methods: - -[source,groovy,indent=0] ----- -@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) -class StubRunnerConfigurationSpec extends Specification { - - @Autowired StubFinder stubFinder - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null - and: - stubFinder.findAllRunningStubs().isPresent('loanIssuance') - stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' - } - - @Configuration - @Import(StubRunnerConfiguration) - @EnableAutoConfiguration - static class Config {} -} ----- - -Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. - -==== Stub Runner Spring Cloud - -If you're using Spring Cloud then it's enough to add `stub-runner-spring-cloud` on classpath and automatically a bean of type `StubFinder` will get registered. - -==== Common properties for JUnit and Spring - -Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values: - -[width="60%",frame="topbot",options="header"] -|====================== -| Property name | Default value | Description | -|stubrunner.port.range.min|10000| Minimal value of a port for a started WireMock with stubs| -|stubrunner.port.range.max|15000| Minimal value of a port for a started WireMock with stubs| -|stubrunner.stubs.repository.root|| Maven repo url. If blank then will call the local maven repo| -|stubrunner.stubs.classifier|stubs| Default classifier for the stub artifacts| -|stubrunner.work-offline|false| If true then will not contact any remote repositories to download stubs| -|stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| -|====================== - -= 9. Migration Guide - -= Migration to 0.4.7 -- in 0.4.7 we've fixed package name (coderate to codearte) so you've to do the same in your projects. This means replacing ```io.coderate.accurest.dsl.GroovyDsl``` with ```io.codearte.accurest.dsl.GroovyDsl``` - -= Migration to 1.0.0-RC1 -- from 1.0.0 we're distinguish ignored contracts from excluded contracts: - - `excludedFiles` pattern tells Accurest to skip processing those files at all - - `ignoredFiles` pattern tells Accurest to generate contracts and tests, but tests will be marked as `@Ignore` - -- from 1.0.0 the `basePackageForTests` behaviour has changed - - prior to the change all DSL files had to be under `contractsDslDir`/`basePackageForTests`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - - now all DSL files have to be under `contractsDslDir`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage*][][] \ No newline at end of file + - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage* \ No newline at end of file From 5218d4203c03579368c6bc7d459c9e6c67673017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Wed, 20 Apr 2016 22:51:58 +0200 Subject: [PATCH 502/719] add support for stubs with contracts for messaging (#12) --- pom.xml | 6 ++ .../accurest/maven/ConvertMojo.groovy | 76 +++++++++++-------- .../accurest/maven/GenerateStubsMojo.groovy | 2 +- .../io/codearte/accurest/maven/RunMojo.groovy | 29 ++----- .../accurest/maven/PluginUnitTest.java | 8 +- 5 files changed, 64 insertions(+), 57 deletions(-) diff --git a/pom.xml b/pom.xml index 69d0012cf4..6a6b099a31 100644 --- a/pom.xml +++ b/pom.xml @@ -230,6 +230,12 @@ provided + + org.apache.maven.shared + maven-filtering + 3.1.0 + + ch.qos.logback logback-core diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy index af0f7d5944..6fab4377dd 100644 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -5,44 +5,49 @@ import io.codearte.accurest.config.AccurestConfigProperties import io.codearte.accurest.wiremock.DslToWireMockClientConverter import io.codearte.accurest.wiremock.RecursiveFilesConverter import org.apache.maven.execution.MavenSession -import org.apache.maven.model.path.PathTranslator +import org.apache.maven.model.Resource import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException +import org.apache.maven.plugins.annotations.Component import org.apache.maven.plugins.annotations.LifecyclePhase import org.apache.maven.plugins.annotations.Mojo import org.apache.maven.plugins.annotations.Parameter - -import javax.inject.Inject +import org.apache.maven.project.MavenProject +import org.apache.maven.shared.filtering.MavenFilteringException +import org.apache.maven.shared.filtering.MavenResourcesExecution +import org.apache.maven.shared.filtering.MavenResourcesFiltering @Mojo(name = 'convert', requiresProject = false, defaultPhase = LifecyclePhase.PROCESS_TEST_RESOURCES) @CompileStatic class ConvertMojo extends AbstractMojo { - @Parameter(defaultValue = '${basedir}', readonly = true, required = true) - private File basedir + @Parameter(defaultValue = '${basedir}/src/test/accurest') + private File contractsDirectory - @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) - private File projectBuildDirectory + @Parameter(defaultValue = '${project.build.directory}/accurest') + private File outputDirectory - @Parameter(property = 'contractsDirectory') - private String contractsDirectory + @Parameter(property = 'contractsDirectory', defaultValue = '${basedir}') + private File source - @Parameter(property = 'stubsDirectory') - private String outputDirectory + @Parameter(property = 'stubsDirectory', defaultValue = '${basedir}') + private File destination @Parameter(property = 'accurest.skip', defaultValue = 'false') private boolean skip + @Parameter(defaultValue = 'false') + private boolean attachContracts + @Parameter(defaultValue = '${session}', readonly = true) private MavenSession mavenSession - private final PathTranslator translator + @Parameter(defaultValue = '${project}', readonly = true) + private MavenProject project - @Inject - ConvertMojo(PathTranslator translator) { - this.translator = translator - } + @Component(role = MavenResourcesFiltering.class, hint = "default") + private MavenResourcesFiltering mavenResourcesFiltering; void execute() throws MojoExecutionException, MojoFailureException { @@ -51,15 +56,15 @@ class ConvertMojo extends AbstractMojo { return } + if (attachContracts) { + log.info("Attaching accurest contracts") + copyContracts() + } + AccurestConfigProperties config = new AccurestConfigProperties() - if (insideProject) { - config.contractsDslDir = resolveFile(basedir, contractsDirectory, 'src/test/accurest') - config.stubsOutputDir = resolveFile(projectBuildDirectory, outputDirectory, 'mappings') - } else { - config.contractsDslDir = resolveFile(basedir, contractsDirectory, '') - config.stubsOutputDir = resolveFile(basedir, outputDirectory, '') - } + config.contractsDslDir = insideProject ? contractsDirectory : source + config.stubsOutputDir = insideProject ? new File(outputDirectory, 'mappings') : destination log.info('Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings') log.info(" Accurest contracts directory: ${config.contractsDslDir}") @@ -69,16 +74,27 @@ class ConvertMojo extends AbstractMojo { converter.processFiles() } + private void copyContracts() { + Resource testResource = new Resource(directory: contractsDirectory.absolutePath) + + MavenResourcesExecution mavenResourcesExecution = + new MavenResourcesExecution([testResource], + new File(outputDirectory, 'contracts'), project, 'UTF-8', + [], [], mavenSession); + mavenResourcesExecution.injectProjectBuildFilters = false + mavenResourcesExecution.overwrite = true + mavenResourcesExecution.includeEmptyDirs = false + mavenResourcesExecution.filterFilenames = false + try { + mavenResourcesFiltering.filterResources(mavenResourcesExecution); + } catch (MavenFilteringException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + private boolean isInsideProject() { return mavenSession.request.projectPresent } - private File resolveFile(File baseDir, String requestedPath, String defaultPath) { - return requestedPath ? alignToBaseDirectory(baseDir, requestedPath) : alignToBaseDirectory(baseDir, defaultPath) - } - - private File alignToBaseDirectory(File baseDir, String path) { - return new File(translator.alignToBaseDirectory(path, baseDir)) - } } diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy index ea75877350..ed88bd2b74 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy @@ -20,7 +20,7 @@ class GenerateStubsMojo extends AbstractMojo { @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) private File projectBuildDirectory - @Parameter(property = 'stubsDirectory', defaultValue = '${project.build.directory}/mappings') + @Parameter(property = 'stubsDirectory', defaultValue = '${project.build.directory}/accurest') private File outputDirectory @Parameter(property = 'accurest.skip', defaultValue = 'false') diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index ea33e18ca8..a6b67e4939 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -5,7 +5,6 @@ import io.codearte.accurest.maven.stubrunner.LocalStubRunner import io.codearte.accurest.maven.stubrunner.RemoteStubRunner import io.codearte.accurest.stubrunner.StubRunnerOptions import org.apache.maven.execution.MavenSession -import org.apache.maven.model.path.PathTranslator import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException @@ -19,17 +18,14 @@ import javax.inject.Inject @CompileStatic class RunMojo extends AbstractMojo { - @Parameter(defaultValue = '${basedir}', readonly = true, required = true) - private File basedir - - @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) - private File projectBuildDirectory - @Parameter(defaultValue = '${repositorySystemSession}', readonly = true) private RepositorySystemSession repoSession + @Parameter(defaultValue = '${project.build.directory}/accurest/mappings') + private File stubsDirectory + @Parameter(property = 'stubsDirectory', defaultValue = '${basedir}') - private String stubsDirectory + private File destination @Parameter(property = 'accurest.http.port', defaultValue = '8080') private int httpPort; @@ -53,13 +49,11 @@ class RunMojo extends AbstractMojo { private final LocalStubRunner localStubRunner private final RemoteStubRunner remoteStubRunner - private final PathTranslator translator @Inject - RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner, PathTranslator translator) { + RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner) { this.localStubRunner = localStubRunner this.remoteStubRunner = remoteStubRunner - this.translator = translator } void execute() throws MojoExecutionException, MojoFailureException { @@ -84,9 +78,9 @@ class RunMojo extends AbstractMojo { private File resolveStubsDirectory() { if (insideProject) { - return resolveFile(projectBuildDirectory, stubsDirectory, 'mappings') + stubsDirectory } else { - return resolveFile(basedir, stubsDirectory, '') + destination } } @@ -102,13 +96,4 @@ class RunMojo extends AbstractMojo { return mavenSession.request.projectPresent } - private File resolveFile(File baseDir, String requestedPath, String defaultPath) { - return requestedPath ? alignToBaseDirectory(baseDir, requestedPath) : alignToBaseDirectory(baseDir, defaultPath) - } - - private File alignToBaseDirectory(File baseDir, String path) { - return new File(translator.alignToBaseDirectory(path, baseDir)) - } - - } diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 5b7e11f812..d008614a00 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -23,21 +23,21 @@ public class PluginUnitTest { public void shouldGenerateWireMockStubsInDefaultLocation() throws Exception { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "convert"); - assertFilesPresent(basedir, "target/mappings/Sample.json"); + assertFilesPresent(basedir, "target/accurest/mappings/Sample.json"); } @Test public void shouldGenerateWireMockFromStubsDirectory() throws Exception { File basedir = resources.getBasedir("withStubs"); maven.executeMojo(basedir, "convert", newParameter("contractsDirectory", "src/test/resources/stubs")); - assertFilesPresent(basedir, "target/mappings/Sample.json"); + assertFilesPresent(basedir, "target/accurest/mappings/Sample.json"); } @Test public void shouldGenerateWireMockStubsInSelectedLocation() throws Exception { File basedir = resources.getBasedir("basic"); - maven.executeMojo(basedir, "convert", newParameter("outputDirectory", "foo")); - assertFilesPresent(basedir, "target/foo/Sample.json"); + maven.executeMojo(basedir, "convert", newParameter("outputDirectory", "target/foo")); + assertFilesPresent(basedir, "target/foo/mappings/Sample.json"); } @Test From 69d227839a70c49b7001593e803da3697ee6472c Mon Sep 17 00:00:00 2001 From: Travis CI Date: Wed, 20 Apr 2016 20:56:46 +0000 Subject: [PATCH 503/719] Sets project version to 0.5.9-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 6a6b099a31..a8797b64ec 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.8-SNAPSHOT + 0.5.9-SNAPSHOT Accurate Maven Plugin Project Accurate REST Maven Plugin From 1306f740aaa7fa0ba7ef4f195ada5e74758024a5 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 23:05:34 +0200 Subject: [PATCH 504/719] Changed the dependant task to check Fixes #236 --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 6288fa93b4..bf0edc316e 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 @@ -22,7 +22,7 @@ class AccurestGradlePlugin implements Plugin { this.project = project AccurestConfigProperties extension = project.extensions.create('accurest', AccurestConfigProperties) - project.compileTestGroovy.dependsOn(GENERATE_SERVER_TESTS_TASK_NAME) + project.check.dependsOn(GENERATE_SERVER_TESTS_TASK_NAME) setConfigurationDefaults(extension) createGenerateTestsTask(extension) From 509ae6eedf3c32fb8b12077949221280c2cf7070 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 23:06:29 +0200 Subject: [PATCH 505/719] Storing results of tests in build folder When storing in temporary folder we can't analyze the results of gradle task execution --- .../plugin/AccurestIntegrationSpec.groovy | 140 +++++++++--------- .../plugin/BasicFunctionalSpec.groovy | 4 +- .../plugin/MessagingProjectSpec.groovy | 2 +- .../plugin/SampleJerseyProjectSpec.groovy | 2 +- .../accurest/plugin/SampleProjectSpec.groovy | 2 +- .../plugin/ScenarioProjectSpec.groovy | 2 +- 6 files changed, 78 insertions(+), 74 deletions(-) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy index 1ac3521e4b..f5b5ac98bb 100644 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy @@ -5,8 +5,6 @@ import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.BuildTask import org.gradle.testkit.runner.GradleRunner import org.gradle.testkit.runner.TaskOutcome -import org.junit.Rule -import org.junit.rules.TemporaryFolder import spock.lang.Specification import java.nio.file.Files @@ -19,30 +17,36 @@ import static java.nio.charset.StandardCharsets.UTF_8 * @author Denis Stepanov * @since 23.02.16 */ -class AccurestIntegrationSpec extends Specification { +abstract class AccurestIntegrationSpec extends Specification { - @Rule - TemporaryFolder testProjectDir = new TemporaryFolder() + File testProjectDir - public static final String SPOCK = "targetFramework = 'Spock'" - public static final String JUNIT = "targetFramework = 'JUnit'" - public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" - public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + def setup() { + def dateString = new Date().format("yyyy-MM-dd_HH-mm-ss") + def testFolder = new File("build/generated-tests/${getClass().simpleName}/${dateString}") + testFolder.mkdirs() + testProjectDir = testFolder + } - protected void setupForProject(String projectRoot) { - copyResourcesToRoot(projectRoot) + public static final String SPOCK = "targetFramework = 'Spock'" + public static final String JUNIT = "targetFramework = 'JUnit'" + public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" + public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" - def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.txt") - if (pluginClasspathResource == null) { - throw new IllegalStateException("Did not find 'plugin-classpath.txt'") - } + protected void setupForProject(String projectRoot) { + copyResourcesToRoot(projectRoot) - String pluginClasspath = pluginClasspathResource.readLines() - .collect { it.replace('\\', '\\\\') } // escape backslashes in Windows paths - .collect { "'$it'" } - .join(", ") + def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.txt") + if (pluginClasspathResource == null) { + throw new IllegalStateException("Did not find 'plugin-classpath.txt'") + } - buildFile << """ + String pluginClasspath = pluginClasspathResource.readLines() + .collect { it.replace('\\', '\\\\') } // escape backslashes in Windows paths + .collect { "'$it'" } + .join(", ") + + buildFile << """ buildscript { dependencies { classpath files($pluginClasspath) @@ -50,9 +54,9 @@ class AccurestIntegrationSpec extends Specification { } """ - // Extending buildscript is required when 'apply' is used. - // 'GradleRunner#withPluginClasspath' can be used when plugin is added using 'plugins { id...' - } + // Extending buildscript is required when 'apply' is used. + // 'GradleRunner#withPluginClasspath' can be used when plugin is added using 'plugins { id...' + } protected void switchToJunitTestFramework() { switchToJunitTestFramework(MVC_SPEC, MVC_TEST) @@ -65,57 +69,57 @@ class AccurestIntegrationSpec extends Specification { Files.write(path, content.getBytes(UTF_8)) } - protected void runTasksSuccessfully(String... tasks) { - BuildResult result = run(tasks) - result.tasks.each { - assert it.outcome == TaskOutcome.SUCCESS || it.outcome == TaskOutcome.UP_TO_DATE - } - } + protected void runTasksSuccessfully(String... tasks) { + BuildResult result = run(tasks) + result.tasks.each { + assert it.outcome == TaskOutcome.SUCCESS || it.outcome == TaskOutcome.UP_TO_DATE + } + } - protected BuildResult validateTasksOutcome(BuildResult result, TaskOutcome expectedOutcome, String... tasks) { - tasks.each { - BuildTask task = result.task(":" + it) - assert task - assert task.outcome == expectedOutcome - } - return result - } + protected BuildResult validateTasksOutcome(BuildResult result, TaskOutcome expectedOutcome, String... tasks) { + tasks.each { + BuildTask task = result.task(":" + it) + assert task + assert task.outcome == expectedOutcome + } + return result + } - protected BuildResult run(String... tasks) { - return GradleRunner.create() - .withProjectDir(testProjectDir.root) - .withArguments(tasks) - .build() - } + protected BuildResult run(String... tasks) { + return GradleRunner.create() + .withProjectDir(testProjectDir) + .withArguments(tasks) + .build() + } - protected void copyResourcesToRoot(String srcDir) { - copyResources(srcDir, testProjectDir.root) - } + protected void copyResourcesToRoot(String srcDir) { + copyResources(srcDir, testProjectDir) + } - protected void copyResources(String srcDir, File destinationFile) { - ClassLoader classLoader = getClass().getClassLoader() - URL resource = classLoader.getResource(srcDir) - if (resource == null) { - throw new RuntimeException("Could not find classpath resource: $srcDir") - } - File resourceFile = new File(resource.toURI()) - if (resourceFile.file) { - FileUtils.copyFile(resourceFile, destinationFile) - } else { - FileUtils.copyDirectory(resourceFile, destinationFile) - } - } + protected void copyResources(String srcDir, File destinationFile) { + ClassLoader classLoader = getClass().getClassLoader() + URL resource = classLoader.getResource(srcDir) + if (resource == null) { + throw new RuntimeException("Could not find classpath resource: $srcDir") + } + File resourceFile = new File(resource.toURI()) + if (resourceFile.file) { + FileUtils.copyFile(resourceFile, destinationFile) + } else { + FileUtils.copyDirectory(resourceFile, destinationFile) + } + } - protected File file(String path) { - return new File(testProjectDir.getRoot(), path) - } + protected File file(String path) { + return new File(testProjectDir, path) + } - protected boolean fileExists(String path) { - return file(path).exists() - } + protected boolean fileExists(String path) { + return file(path).exists() + } - protected File getBuildFile() { - return new File('build.gradle', testProjectDir.root) - } + protected File getBuildFile() { + return new File('build.gradle', testProjectDir) + } } 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 2378342932..7589689b4b 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 @@ -14,12 +14,12 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { private static final String GROOVY_DSL_CONTRACT = "repository//mappings//com//ofg//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.groovy" private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.twitter_places_analyzer.PairIdSpec.xml" - void setup() { + def setup() { setupForProject("functionalTest/bootSimple") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } - def "should pass basic flxow"() { + def "should pass basic flow"() { when: BuildResult result = run("check") then: diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy index 0d4004ae11..502d3cfda2 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy @@ -5,7 +5,7 @@ import spock.lang.Stepwise @Stepwise class MessagingProjectSpec extends AccurestIntegrationSpec { - void setup() { + def setup() { setupForProject("functionalTest/messagingProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy index 82ab2a488e..f1b429d627 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -5,7 +5,7 @@ import spock.lang.Stepwise @Stepwise class SampleJerseyProjectSpec extends AccurestIntegrationSpec { - void setup() { + def setup() { setupForProject("functionalTest/sampleJerseyProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index 451230ad85..e27e948003 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -5,7 +5,7 @@ import spock.lang.Stepwise @Stepwise class SampleProjectSpec extends AccurestIntegrationSpec { - void setup() { + def setup() { setupForProject("functionalTest/sampleProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy index 620514dc3a..260d82c1c9 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy @@ -5,7 +5,7 @@ import spock.lang.Stepwise @Stepwise class ScenarioProjectSpec extends AccurestIntegrationSpec { - void setup() { + def setup() { setupForProject("functionalTest/scenarioProject") runTasksSuccessfully('clean') //delete accidental output when previously importing SimpleBoot into Idea to tweak it } From 67358e226e1e1512f97be90631bc6f6ae135dbf4 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 23:07:02 +0200 Subject: [PATCH 506/719] Fixing the build setup of samples We want them to be real samples so I've added proper stub generation tasks --- .../plugin/BasicFunctionalSpec.groovy | 6 +-- .../functionalTest/bootSimple/build.gradle | 37 ++++++++++++++++-- .../messagingProject/build.gradle | 6 +++ .../sampleJerseyProject/build.gradle | 38 +++++++++++++++++-- .../functionalTest/sampleProject/build.gradle | 37 ++++++++++++++++-- .../scenarioProject/build.gradle | 37 ++++++++++++++++-- 6 files changed, 146 insertions(+), 15 deletions(-) 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 7589689b4b..cb6839cba1 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 @@ -9,10 +9,10 @@ import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE @Stepwise class BasicFunctionalSpec extends AccurestIntegrationSpec { - private static final String GENERATED_TEST = "build//generated-test-sources//accurest//accurest//twitter_places_analyzer//PairIdSpec.groovy" - private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.json" + private static final String GENERATED_TEST = "build//generated-test-sources//accurest//accurest//com//ofg//twitter_places_analyzer//PairIdSpec.groovy" + private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//com//ofg//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.json" private static final String GROOVY_DSL_CONTRACT = "repository//mappings//com//ofg//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.groovy" - private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.twitter_places_analyzer.PairIdSpec.xml" + private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.com.ofg.twitter_places_analyzer.PairIdSpec.xml" def setup() { setupForProject("functionalTest/bootSimple") diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 4c0f8a029f..a2463e423e 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -6,11 +6,13 @@ buildscript { apply plugin: 'groovy' apply plugin: 'accurest' +apply plugin: 'maven-publish' ext { - contractsDir = file("${project.rootDir}/repository/mappings/com/ofg") - wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'repository/mappings/') + 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 { @@ -65,3 +67,32 @@ generateAccurest.dependsOn generateWireMockClientStubs wrapper { gradleVersion '2.2.1' } + +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 + } + } +} + +test { + testLogging { + exceptionFormat = 'full' + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle index 824eb68f2f..d658a7c0d8 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle @@ -103,3 +103,9 @@ publishing { } } } + +test { + testLogging { + exceptionFormat = 'full' + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index c4013e84a4..7bcf25e20f 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -35,10 +35,13 @@ subprojects { configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { apply plugin: 'spring-boot' apply plugin: 'accurest' + apply plugin: 'maven-publish' ext { - wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'mappings/') + 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/') } accurest { @@ -75,6 +78,35 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') clean.dependsOn('cleanup') + 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 + } + } + } + + test { + testLogging { + exceptionFormat = 'full' + } + } + } configure(project(':fraudDetectionService')) { @@ -85,7 +117,7 @@ configure(project(':loanApplicationService')) { task copyCollaboratorStubs(type: Copy) { File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/repository/")) into "src/test/resources/" } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 418de70103..166d4dc91e 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -35,10 +35,13 @@ subprojects { configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { apply plugin: 'spring-boot' apply plugin: 'accurest' + apply plugin: 'maven-publish' ext { - wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'mappings/') + 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/') } accurest { @@ -73,6 +76,34 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') clean.dependsOn('cleanup') + 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 + } + } + } + + test { + testLogging { + exceptionFormat = 'full' + } + } } configure(project(':fraudDetectionService')) { @@ -83,7 +114,7 @@ configure(project(':loanApplicationService')) { task copyCollaboratorStubs(type: Copy) { File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/repository/")) into "src/test/resources/" } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index 418de70103..d111afa126 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -18,6 +18,7 @@ ext { subprojects { apply plugin: 'groovy' + apply plugin: 'maven-publish' repositories { mavenCentral() @@ -37,8 +38,10 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') apply plugin: 'accurest' ext { - wireMockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(wireMockStubsOutputDirRoot, 'mappings/') + 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/') } accurest { @@ -73,6 +76,34 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') clean.dependsOn('cleanup') + 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 + } + } + } + + test { + testLogging { + exceptionFormat = 'full' + } + } } configure(project(':fraudDetectionService')) { @@ -83,7 +114,7 @@ configure(project(':loanApplicationService')) { task copyCollaboratorStubs(type: Copy) { File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/repository/")) into "src/test/resources/" } From b461ae4410bece0cab2dbc8d20079bbfd2f78150 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 23:27:58 +0200 Subject: [PATCH 507/719] Making JUnit default test tool fixes #237 --- .../config/AccurestConfigProperties.groovy | 2 +- .../accurest/GeneratorScannerSpec.groovy | 3 +- .../functionalTest/bootSimple/build.gradle | 1 + .../messagingProject/build.gradle | 1 + .../scenarioProject/build.gradle | 2 + docs/src/docs/asciidoc/index.adoc | 59 +++++++++++-------- 6 files changed, 40 insertions(+), 28 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy index ae160a69d4..253887ae7b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy @@ -7,7 +7,7 @@ class AccurestConfigProperties { /** * For which unit test library tests should be generated */ - TestFramework targetFramework = TestFramework.SPOCK + TestFramework targetFramework = TestFramework.JUNIT /** * Which mechanism should be used to invoke REST calls during tests diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy index e95eeb1fe9..77e2804805 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest import io.codearte.accurest.config.AccurestConfigProperties +import io.codearte.accurest.config.TestFramework import spock.lang.Specification class GeneratorScannerSpec extends Specification { @@ -21,7 +22,7 @@ class GeneratorScannerSpec extends Specification { def "should create class with full package"() { given: - AccurestConfigProperties properties = new AccurestConfigProperties() + AccurestConfigProperties properties = new AccurestConfigProperties(targetFramework: TestFramework.SPOCK) properties.contractsDslDir = new File(this.getClass().getResource("/directory/with/stubs/package").toURI()) TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) when: diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index a2463e423e..4db3e39f58 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -54,6 +54,7 @@ accurest { contractsDslDir = contractsDir // generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/") stubsOutputDir = wireMockStubsOutputDir + targetFramework = 'Spock' } //TODO: Put it into the plugin diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle index d658a7c0d8..f48bbe9c4f 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle @@ -18,6 +18,7 @@ ext { stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/') contractsOutputDir = new File(stubsOutputDirRoot, 'repository/accurest/') + targetFramework = 'Spock' } configurations { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index d111afa126..e5b1dfb4db 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -45,7 +45,9 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') } accurest { + // tag::target_framework[] targetFramework = 'Spock' + // end::target_framework[] testMode = 'MockMvc' baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 42f57e8f79..75828b5440 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -11,7 +11,7 @@ Just to make long story short - AccuREST is a tool that enables Consumer Driven AccuREST moves TDD to the level of software architecture. -= Why? +== Why? The main purposes of AccuREST are: @@ -22,15 +22,13 @@ The main purposes of AccuREST are: = 2. Using in your project -== Prerequisites +== 2.1. Gradle Project -= 2.1. Gradle Project - -== Prerequisites +=== Prerequisites In order to use Accurest with Wiremock you have to use gradle or maven plugin. -== Add gradle plugin +==== Add gradle plugin [source,groovy,indent=0] ---- @@ -53,7 +51,7 @@ dependencies { } ---- -== Add maven plugin +==== Add maven plugin [source,xml,indent=0] ---- @@ -75,7 +73,7 @@ dependencies { Read more: https://github.com/Codearte/accurest-maven-plugin[accurest-maven-plugin] -== Add stubs +==== 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. @@ -89,11 +87,11 @@ Accurest will create test class `defaultBasePackage.MyService` with two methods - shouldCreateUser() - shouldReturnUser() -== Run plugin +=== 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 +=== Configure plugin To change default configuration just add `accurest` snippet to your Gradle config @@ -106,7 +104,7 @@ accurest { } ---- -=== Configuration options +==== Configuration options - **testMode** - defines mode for acceptance tests. By default MockMvc which is based on Spring's MockMvc. It can also be changed to **JaxRsClient** or to **Explicit** for real HTTP calls. - **imports** - array with imports that should be included in generated tests (for example ['org.myorg.Matchers']). By default empty array [] @@ -120,7 +118,7 @@ accurest { - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework -== Base class for tests +==== Base class for tests When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. @@ -141,12 +139,12 @@ class MvcSpec extends Specification { In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. -== Invoking generated tests +=== Invoking generated tests To ensure that provider side is complaint with defined contracts, you need to invoke: `./gradlew generateAccurest test` -== Accurest on consumer side +=== Accurest on consumer side In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/stubs and generate Wiremock json stubs using: `./gradlew generateWireMockClientStubs` command. Note that `stubsOutputDir` option has to be set for stub generation to work. @@ -179,9 +177,9 @@ class LoanApplicationServiceSpec extends Specification { Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. -= 2.2. Using in your Maven project +== 2.2. Using in your Maven project -== Add maven plugin +=== Add maven plugin [source,xml,indent=0] ---- @@ -202,7 +200,7 @@ Underneath LoanApplication makes a call to FraudDetection service. This request Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) -== Add stubs +=== Add stubs By default Accurest is looking for stubs in `src/test/accurest` directory. Directory containing stub definitions is treated as a class name, and each stub definition is treated as a single test. @@ -219,11 +217,11 @@ Accurest will create test class `defaultBasePackage.MyService` with two methods - `shouldCreateUser()` - `shouldReturnUser()` -== Run plugin +=== Run plugin Plugin goal `generateTests` is assigned to be invoked in phase `generate-test-sources`. 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 `generateTests` goal. -== Configure plugin +=== Configure plugin To change default configuration just add `configuration` section to plugin definition or `execution` definition. @@ -248,7 +246,7 @@ To change default configuration just add `configuration` section to plugin defin ---- -=== Configuration options +==== Configuration options - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. @@ -259,7 +257,7 @@ To change default configuration just add `configuration` section to plugin defin - **mappingsDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed. - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework -== Base class for tests +==== Base class for tests When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. @@ -280,7 +278,7 @@ class MvcSpec extends Specification { In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. -== Invoking generated tests +=== Invoking generated tests Accurest Maven Plugins generates verification code into directory `/generated-test-sources/accurest` and attach this directory to `testCompile` goal. @@ -320,7 +318,7 @@ For Groovy Spock code use: To ensure that provider side is complaint with defined contracts, you need to invoke `mvn generateTest test` -== Accurest on consumer side +=== Accurest on consumer side In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. @@ -1198,10 +1196,10 @@ Some of the properties that are repetitive can be set using system properties or = 9. Migration Guide -= Migration to 0.4.7 +== Migration to 0.4.7 - in 0.4.7 we've fixed package name (coderate to codearte) so you've to do the same in your projects. This means replacing ```io.coderate.accurest.dsl.GroovyDsl``` with ```io.codearte.accurest.dsl.GroovyDsl``` -= Migration to 1.0.0-RC1 +== Migration to 1.0.0-RC1 - from 1.0.0 we're distinguish ignored contracts from excluded contracts: - `excludedFiles` pattern tells Accurest to skip processing those files at all - `ignoredFiles` pattern tells Accurest to generate contracts and tests, but tests will be marked as `@Ignore` @@ -1209,4 +1207,13 @@ Some of the properties that are repetitive can be set using system properties or - from 1.0.0 the `basePackageForTests` behaviour has changed - prior to the change all DSL files had to be under `contractsDslDir`/`basePackageForTests`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - now all DSL files have to be under `contractsDslDir`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage* \ No newline at end of file + - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage* + +== Migration to 1.0.7 +- from 1.0.7 we're setting JUnit as a default testing utility. You have to pass the following option to keep Spock +as your first choice: + +[source,groovy] +---- +include::../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=target_framework,indent=0] +---- \ No newline at end of file From 082ad0d0083411c98892d55d8d893accdcba6aae Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 23:28:52 +0200 Subject: [PATCH 508/719] Updated docs --- docs/src/docs/asciidoc/index.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 75828b5440..40a91e2d6c 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1215,5 +1215,5 @@ as your first choice: [source,groovy] ---- -include::../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=target_framework,indent=0] +include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=target_framework,indent=0] ---- \ No newline at end of file From b1d25eb6268927d3183d0c62f1181c303e92868c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 23:29:23 +0200 Subject: [PATCH 509/719] Updated docs script --- docs.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs.sh b/docs.sh index e7354d1bc7..17ed699b55 100755 --- a/docs.sh +++ b/docs.sh @@ -1,3 +1,3 @@ #!/usr/bin/env bash -./gradlew :docs:clean publishGhPages \ No newline at end of file +./gradlew :docs:clean :docs:publishGhPages --configure-on-demand \ No newline at end of file From 01c646b629953f0571fb176084d830859e5ce925 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 20 Apr 2016 23:37:13 +0200 Subject: [PATCH 510/719] Fixed the docs --- docs/src/docs/asciidoc/index.adoc | 508 ++++---------------------- docs/src/docs/asciidoc/messaging.adoc | 8 +- docs/src/docs/asciidoc/rest.adoc | 349 ++++++++++++++++++ 3 files changed, 435 insertions(+), 430 deletions(-) create mode 100644 docs/src/docs/asciidoc/rest.adoc diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 40a91e2d6c..653bc221bc 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -2,7 +2,7 @@ Welcome to the AccuREST Wiki! Please follow to the Introduction page to start your journey with Consumer Driven Contracts in JVM -= 1. Introduction +== Introduction Just to make long story short - AccuREST is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by AccuREST to produce following resources: @@ -11,7 +11,7 @@ Just to make long story short - AccuREST is a tool that enables Consumer Driven AccuREST moves TDD to the level of software architecture. -== Why? +=== Why? The main purposes of AccuREST are: @@ -20,357 +20,11 @@ The main purposes of AccuREST are: - to provide a way to publish changes in contracts that are immediately visible on both sides, - to generate boilerplate test code used on the server side. -= 2. Using in your project +include::rest.adoc[] -== 2.1. Gradle Project +include::messaging.adoc[] -=== Prerequisites - -In order to use Accurest with Wiremock you have to use gradle or maven plugin. - -==== Add gradle plugin - -[source,groovy,indent=0] ----- -buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath 'io.codearte.accurest:accurest-gradle-plugin:1.0.6' - } -} - -apply plugin: 'groovy' -apply plugin: 'accurest' - -dependencies { - testCompile('org.codehaus.groovy:groovy-all:2.4.6') - testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' - testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' // needed if you're going to use Spring MockMvc -} ----- - -==== Add maven plugin - -[source,xml,indent=0] ----- - - io.codearte.accurest - accurest-maven-plugin - - - - convert - generateStubs - generateTests - - - - ----- - - -Read more: https://github.com/Codearte/accurest-maven-plugin[accurest-maven-plugin] - -==== 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.groovy -src/test/resources/stubs/myservice/shouldReturnUser.groovy - -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 - -[source,groovy,indent=0] ----- -accurest { - testMode = 'MockMvc' - baseClassForTests = 'org.mycompany.tests' - generatedTestSourcesDir = project.file('src/accurest') -} ----- - -==== Configuration options - - - **testMode** - defines mode for acceptance tests. By default MockMvc which is based on Spring's MockMvc. It can also be changed to **JaxRsClient** or to **Explicit** for real HTTP calls. - - **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 [] - - **basePackageForTests** - specifies base package for all generated tests. By default set to io.codearte.accurest.tests - - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` - - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - - **ignoredFiles** - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array [] - - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/accurest` - - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `$buildDir/generated-test-sources/accurest` - - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed - - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework - -==== Base class for tests - - When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. - -[source,groovy,indent=0] ----- -package org.mycompany.tests - -import org.mycompany.ExampleSpringController -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new ExampleSpringController()) - } -} ----- - -In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. - -=== Invoking generated tests - -To ensure that provider side is complaint with defined contracts, you need to invoke: -`./gradlew generateAccurest test` - -=== Accurest on consumer side - -In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/stubs and generate Wiremock json stubs using: `./gradlew generateWireMockClientStubs` command. Note that `stubsOutputDir` option has to be set for stub generation to work. - -When present, json stubs can be used in consumer automated tests. - -[source,groovy,indent=0] ----- -@ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) -class LoanApplicationServiceSpec extends Specification { - - @ClassRule - @Shared - WireMockClassRule wireMockRule = new WireMockClassRule() - - @Autowired - LoanApplicationService sut - - def 'should successfully apply for loan'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED - loanApplication.rejectionReason == null - } -} ----- - -Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. - -== 2.2. Using in your Maven project - -=== Add maven plugin - -[source,xml,indent=0] ----- - - io.codearte.accurest - accurest-maven-plugin - - - - convert - generateStubs - generateTests - - - - ----- - -Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) - -=== Add stubs - -By default Accurest is looking for stubs in `src/test/accurest` 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 - -[source,groovy,indent=0] ----- -src/test/accurest/myservice/shouldCreateUser.groovy -src/test/accurest/myservice/shouldReturnUser.groovy ----- - -Accurest will create test class `defaultBasePackage.MyService` with two methods - - `shouldCreateUser()` - - `shouldReturnUser()` - -=== Run plugin - -Plugin goal `generateTests` is assigned to be invoked in phase `generate-test-sources`. 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 `generateTests` goal. - -=== Configure plugin - -To change default configuration just add `configuration` section to plugin definition or `execution` definition. - -[source,xml,indent=0] ----- - - io.codearte.accurest - accurest-maven-plugin - - - - convert - generateStubs - generateTests - - - - - com.ofg.twitter.place - com.ofg.twitter.place.BaseMockMvcSpec - - ----- - -==== Configuration options - - - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. - - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. - - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification`. - - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/accurest`. - - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `target/generated-test-sources/accurest`. - - **mappingsDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed. - - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework - -==== Base class for tests - - When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. - -[source,groovy,indent=0] ----- -package org.mycompany.tests - -import org.mycompany.ExampleSpringController -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new ExampleSpringController()) - } -} ----- - -In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. - -=== Invoking generated tests - -Accurest Maven Plugins generates verification code into directory `/generated-test-sources/accurest` and attach this directory to `testCompile` goal. - -For Groovy Spock code use: - -[source,xml,indent=0] ----- - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.5 - - - - testCompile - - - - - - - ${project.basedir}/src/test/groovy - - **/*.groovy - - - - ${project.build.directory}/generated-test-sources/accurest - - **/*.groovy - - - - - ----- - -To ensure that provider side is complaint with defined contracts, you need to invoke `mvn generateTest test` - -=== Accurest on consumer side - -In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. - -Sample configuration: - -[source,xml,indent=0] ----- - - io.codearte.accurest - accurest-maven-plugin - ${accurest.version} - - - - convert - generateStubs - - - - ----- - -When present, json stubs can be used in consumer automated tests. - -[source,groovy,indent=0] ----- -@ContextConfiguration(loader = SpringApplicationContextLoader, classes = Application) -class LoanApplicationServiceSpec extends Specification { - - @ClassRule - @Shared - WireMockClassRule wireMockRule = new WireMockClassRule() - - @Autowired - LoanApplicationService sut - - def 'should successfully apply for loan'() { - given: - LoanApplication application = - new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123) - when: - LoanApplicationResult loanApplication = sut.loanApplication(application) - then: - loanApplication.loanApplicationStatus == LoanApplicationStatus.LOAN_APPLIED - loanApplication.rejectionReason == null - } -} ----- - -Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. - -= 3. Contract DSL +== Contract DSL Contract DSL in AccuREST is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, AccuREST's DSL is designed to be programmer-readable without any knowledge of the DSL itself. @@ -406,7 +60,7 @@ Not all features of the DSL are used in example above. If you didn't find what y > You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. -== Top-Level Elements +=== Top-Level Elements Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. @@ -434,7 +88,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -== Request +=== Request HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of AccuREST contract. @@ -581,7 +235,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -== Response +=== Response Minimal response must contain **HTTP status code**. @@ -601,14 +255,14 @@ io.codearte.accurest.dsl.GroovyDsl.make { Besides status response may contain **headers** and **body**, which are specified the same way as in the request (see previous paragraph). -== Regular expressions +=== Regular expressions You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both for your test and your server side tests. Please see the example below: [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl groovyDsl = GroovyDsl.make { +io.codearte.accurest.dsl.GroovyDsl groovyDsl == GroovyDsl.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -637,7 +291,7 @@ io.codearte.accurest.dsl.GroovyDsl groovyDsl = GroovyDsl.make { } ---- -== Passing optional parameters +=== Passing optional parameters It is possible to provide optional parameters in your contract. It's only possible to have optional parameter for the: @@ -668,7 +322,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } body( code: value(stub("123123"), test(optional("123123"))), - message: "User not found by email = [${value(test(regex(email())), stub('not.existing@user.com'))}]" + message: "User not found by email == [${value(test(regex(email())), stub('not.existing@user.com'))}]" ) } } @@ -681,21 +335,21 @@ That way for the example above the following test would be generated: [source,groovy,indent=0] ---- given: - def request = given() + def request == given() .header('Content-Type', 'application/json') .body('{"email":"abc@abc.com","callback_url":"http://partners.com"}') when: - def response = given().spec(request) + def response == given().spec(request) .post("/users/password") then: - response.statusCode == 404 - response.header('Content-Type') == 'application/json' + response.statusCode === 404 + response.header('Content-Type') === 'application/json' and: - DocumentContext parsedJson = JsonPath.parse(response.body.asString()) + DocumentContext parsedJson == JsonPath.parse(response.body.asString()) !parsedJson.read('''$[?(@.code =~ /(123123)?/)]''', JSONArray).empty - !parsedJson.read('''$[?(@.message =~ /User not found by email = \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]''', JSONArray).empty + !parsedJson.read('''$[?(@.message =~ /User not found by email == \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]''', JSONArray).empty ---- @@ -720,7 +374,7 @@ and the following stub: }, "response" : { "status" : 404, - "body" : "{\"code\":\"123123\",\"message\":\"User not found by email = [not.existing@user.com]\"}", + "body" : "{\"code\":\"123123\",\"message\":\"User not found by email == [not.existing@user.com]\"}", "headers" : { "Content-Type" : "application/json" } @@ -729,10 +383,10 @@ and the following stub: } ---- -== Executing custom methods on server side +=== Executing custom methods on server side It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. Please see the examples below: -=== Groovy DSL +==== Groovy DSL [source,groovy,indent=0] ---- @@ -759,7 +413,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -=== Base Mock Spec +==== Base Mock Spec [source,groovy,indent=0] ---- @@ -770,12 +424,12 @@ abstract class BaseMockMvcSpec extends Specification { } void isProperCorrelationId(Integer correlationId) { - assert correlationId == 123456 + assert correlationId === 123456 } } ---- -== JAX-RS support +=== JAX-RS support Starting with release 0.8.0 we support JAX-RS 2 Client API. Base class needs to define `protected WebTarget webTarget` and server initialization, right now the only option how to test JAX-RS API is to start a web server. Request with a body needs to have a content type set otherwise `application/octet-stream` is going to be used. @@ -784,7 +438,7 @@ In order to use JAX-RS mode, use the following settings: [source,groovy,indent=0] ---- -testMode = 'JAXRSCLIENT' +testMode == 'JAXRSCLIENT' ---- Example of a test API generated: @@ -795,44 +449,44 @@ class FraudDetectionServiceSpec extends MvcSpec { def shouldMarkClientAsNotFraud() { when: - def response = webTarget + def response == webTarget .path('/fraudcheck') .request() .method('put', entity('{"clientPesel":"1234567890","loanAmount":123.123}', 'application/vnd.fraud.v1+json')) - String responseAsString = response.readEntity(String) + String responseAsString == response.readEntity(String) then: - response.status == 200 - response.getHeaderString('Content-Type') == 'application/vnd.fraud.v1+json' + response.status === 200 + response.getHeaderString('Content-Type') === 'application/vnd.fraud.v1+json' and: - def responseBody = new JsonSlurper().parseText(responseAsString) - responseBody.fraudCheckStatus == "OK" + def responseBody == new JsonSlurper().parseText(responseAsString) + responseBody.fraudCheckStatus === "OK" assertThatRejectionReasonIsNull(responseBody.rejectionReason) } def shouldMarkClientAsFraud() { when: - def response = webTarget + def response == webTarget .path('/fraudcheck') .request() .method('put', entity('{"clientPesel":"1234567890","loanAmount":99999}', 'application/vnd.fraud.v1+json')) - String responseAsString = response.readEntity(String) + String responseAsString == response.readEntity(String) then: - response.status == 200 - response.getHeaderString('Content-Type') == 'application/vnd.fraud.v1+json' + response.status === 200 + response.getHeaderString('Content-Type') === 'application/vnd.fraud.v1+json' and: - def responseBody = new JsonSlurper().parseText(responseAsString) + def responseBody == new JsonSlurper().parseText(responseAsString) responseBody.fraudCheckStatus ==~ java.util.regex.Pattern.compile('[A-Z]{5}') - responseBody.rejectionReason == "Amount too high" + responseBody.rejectionReason === "Amount too high" } } ---- -= 4. Client Side +== Client Side 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 @@ -841,7 +495,7 @@ to be valid from the Wiremock's perspective but should also be reusable on the s __Summing it up:__ On this side, in the stub definition, you can use patterns for request stubbing and you need exact values for responses. -= 5. Server Side +== Server Side 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 @@ -853,7 +507,7 @@ 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. -= 6. Examples +== Examples [source,groovy,indent=0] ---- @@ -901,7 +555,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { } ---- -= 7. Scenarios +== Scenarios It's possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore. @@ -922,17 +576,17 @@ More details about Wiremock scenarios can be found under [http://wiremock.org/st Accurest will also generate tests with guaranteed order of execution. -= 8. Stub Runner +== Stub Runner One of the issues that you could have encountered while using AccuREST was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). Copying the JSON files manually is out of the question. In this article you'll see how to prepare your project to start publishing stubs as JARs and how to use Stub Runner in your tests to run WireMock servers and feed them with stub definitions. -== Publishing stubs as JARs +=== Publishing stubs as JARs The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository. -=== Gradle +==== Gradle Example of AccuREST Gradle setup: @@ -941,21 +595,21 @@ Example of AccuREST Gradle setup: apply plugin: 'maven-publish' ext { - wiremockStubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wiremockStubsOutputDir = new File(wiremockStubsOutputDirRoot) + wiremockStubsOutputDirRoot == file("${project.buildDir}/production/${project.name}-stubs/") + wiremockStubsOutputDir == new File(wiremockStubsOutputDirRoot) } accurest { - targetFramework = 'Spock' - testMode = 'MockMvc' - baseClassForTests = 'com.toomuchcoding.MvcSpec' - contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") - generatedTestSourcesDir = file("${project.buildDir}/generated-sources/") - stubsOutputDir = wiremockStubsOutputDir + targetFramework == 'Spock' + testMode == 'MockMvc' + baseClassForTests == 'com.toomuchcoding.MvcSpec' + contractsDslDir == file("${project.projectDir.absolutePath}/mappings/") + generatedTestSourcesDir == file("${project.buildDir}/generated-sources/") + stubsOutputDir == wiremockStubsOutputDir } task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs"]) { - baseName = "${project.name}-stubs" + baseName == "${project.name}-stubs" from wiremockStubsOutputDirRoot } @@ -973,15 +627,15 @@ Example of AccuREST Gradle setup: } ---- -=== Maven +==== Maven Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) -== Using Stub Runner to automate running stubs +=== Using Stub Runner to automate running stubs Stub Runner automates downloading stubs from a Maven repository (that includes also the local Maven repository) and starting the WireMock server for each of those stubs. -=== Modules +==== Modules AccuREST comes with a new structure of modules @@ -994,7 +648,7 @@ AccuREST comes with a new structure of modules └── stub-runner-spring-cloud ---- -==== Stub Runner +===== Stub Runner Contains core logic of Stub Runner. Gives you a main class to run Stub Runner from the command line or from Gradle. @@ -1033,13 +687,13 @@ or each parameter separately with a `-P` prefix and without the hyphen (-) in th `./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h` -==== Stub Runner JUnit Rule +===== Stub Runner JUnit Rule Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id: [source,java,indent=0] ---- -@ClassRule public static AccurestRule rule = new AccurestRule() +@ClassRule public static AccurestRule rule == new AccurestRule() .repoRoot("http://your.repo.com") .downloadStub("io.codearte.accurest.stubs", "loanIssuance") .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") @@ -1089,24 +743,24 @@ Example of usage in Spock tests: [source,groovy,indent=0] ---- -@ClassRule @Shared AccurestRule rule = new AccurestRule() +@ClassRule @Shared AccurestRule rule == new AccurestRule() .repoRoot('http://your.repo.com') .downloadStub("io.codearte.accurest.stubs", "loanIssuance") .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") def 'should start WireMock servers'() { expect: 'WireMocks are running' - rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - rule.findStubUrl('loanIssuance') != null - rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') !== null + rule.findStubUrl('loanIssuance') !== null + rule.findStubUrl('loanIssuance') === rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') !== null and: rule.findAllRunningStubs().isPresent('loanIssuance') rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') and: 'Stubs were registered' - "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text === 'loanIssuance' + "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text === 'fraudDetectionServer' } ---- @@ -1114,7 +768,7 @@ Example of usage in JUnit tests: [source,java,indent=0] ---- -@ClassRule public static AccurestRule rule = new AccurestRule() +@ClassRule public static AccurestRule rule == new AccurestRule() .repoRoot("http://your.repo.com") .downloadStub("io.codearte.accurest.stubs", "loanIssuance") .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); @@ -1138,7 +792,7 @@ Example of usage in JUnit tests: Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. -==== Stub Runner Spring +===== Stub Runner Spring If you're using Spring then you can just import the `io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration` and a bean of type `StubFinder` will get registered. @@ -1146,24 +800,24 @@ In order to find a URL and port of a given dependency you can autowire the bean [source,groovy,indent=0] ---- -@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) +@ContextConfiguration(classes == Config, loader == SpringApplicationContextLoader) class StubRunnerConfigurationSpec extends Specification { @Autowired StubFinder stubFinder def 'should start WireMock servers'() { expect: 'WireMocks are running' - stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') !== null + stubFinder.findStubUrl('loanIssuance') !== null + stubFinder.findStubUrl('loanIssuance') === stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') !== null and: stubFinder.findAllRunningStubs().isPresent('loanIssuance') stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') and: 'Stubs were registered' - "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text === 'loanIssuance' + "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text === 'fraudDetectionServer' } @Configuration @@ -1175,11 +829,11 @@ class StubRunnerConfigurationSpec extends Specification { Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. -==== Stub Runner Spring Cloud +===== Stub Runner Spring Cloud If you're using Spring Cloud then it's enough to add `stub-runner-spring-cloud` on classpath and automatically a bean of type `StubFinder` will get registered. -==== Common properties for JUnit and Spring +===== Common properties for JUnit and Spring Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values: @@ -1194,12 +848,12 @@ Some of the properties that are repetitive can be set using system properties or |stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| |====================== -= 9. Migration Guide +== Migration Guide -== Migration to 0.4.7 +=== Migration to 0.4.7 - in 0.4.7 we've fixed package name (coderate to codearte) so you've to do the same in your projects. This means replacing ```io.coderate.accurest.dsl.GroovyDsl``` with ```io.codearte.accurest.dsl.GroovyDsl``` -== Migration to 1.0.0-RC1 +=== Migration to 1.0.0-RC1 - from 1.0.0 we're distinguish ignored contracts from excluded contracts: - `excludedFiles` pattern tells Accurest to skip processing those files at all - `ignoredFiles` pattern tells Accurest to generate contracts and tests, but tests will be marked as `@Ignore` @@ -1209,7 +863,7 @@ Some of the properties that are repetitive can be set using system properties or - now all DSL files have to be under `contractsDslDir`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage* -== Migration to 1.0.7 +=== Migration to 1.0.7 - from 1.0.7 we're setting JUnit as a default testing utility. You have to pass the following option to keep Spock as your first choice: diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc index 48d67d5216..e808abad5d 100644 --- a/docs/src/docs/asciidoc/messaging.adoc +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -1,9 +1,11 @@ -= Accurest Messaging +== Accurest Messaging + +WARNING: Feature available since 1.0.7 Accurest allows you to verify your application that uses messaging as means of communication. All of our integrations are working with Spring but you can also set one yourself. -== Integrations +=== Integrations You can use one of the three integration configurations: @@ -25,7 +27,7 @@ testCompile "io.codearte.accurest:accurest-messaging-integration:${accurestVersi testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}" ---- -== Manual Integration +=== Manual Integration The `accurest-messaging-core` module contains 3 main interfaces: diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc new file mode 100644 index 0000000000..c11fc37f88 --- /dev/null +++ b/docs/src/docs/asciidoc/rest.adoc @@ -0,0 +1,349 @@ +== Accurest REST + +=== Gradle Project + +==== Prerequisites + +In order to use Accurest with Wiremock you have to use gradle or maven plugin. + +===== Add gradle plugin + +[source,groovy,indent=0] +---- +buildscript { + repositories { + mavenCentral() + } + dependencies { + classpath 'io.codearte.accurest:accurest-gradle-plugin:1.0.6' + } +} + +apply plugin: 'groovy' +apply plugin: 'accurest' + +dependencies { + testCompile('org.codehaus.groovy:groovy-all:2.4.6') + testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' + testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' // needed if you're going to use Spring MockMvc +} +---- + +===== Add maven plugin + +[source,xml,indent=0] +---- + + io.codearte.accurest + accurest-maven-plugin + + + + convert + generateStubs + generateTests + + + + +---- + + +Read more: https://github.com/Codearte/accurest-maven-plugin[accurest-maven-plugin] + +===== 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.groovy +src/test/resources/stubs/myservice/shouldReturnUser.groovy + +Accurest will create test class `defaultBasePackage.MyService` with two methods + - shouldCreateUser() + - shouldReturnUser() + +==== Run plugin + +Plugin registers itself to be invoked before `check` 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 + +[source,groovy,indent=0] +---- +accurest { + testMode == 'MockMvc' + baseClassForTests == 'org.mycompany.tests' + generatedTestSourcesDir == project.file('src/accurest') +} +---- + +===== Configuration options + + - **testMode** - defines mode for acceptance tests. By default MockMvc which is based on Spring's MockMvc. It can also be changed to **JaxRsClient** or to **Explicit** for real HTTP calls. + - **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 [] + - **basePackageForTests** - specifies base package for all generated tests. By default set to io.codearte.accurest.tests + - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` + - **ruleClassForTests** - specifies Rule which should be added to generated test classes. + - **ignoredFiles** - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array [] + - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/accurest` + - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `$buildDir/generated-test-sources/accurest` + - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed + - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework + +===== Base class for tests + + When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. + +[source,groovy,indent=0] +---- +package org.mycompany.tests + +import org.mycompany.ExampleSpringController +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import spock.lang.Specification + +class MvcSpec extends Specification { + def setup() { + RestAssuredMockMvc.standaloneSetup(new ExampleSpringController()) + } +} +---- + +In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. + +==== Invoking generated tests + +To ensure that provider side is complaint with defined contracts, you need to invoke: +`./gradlew generateAccurest test` + +==== Accurest on consumer side + +In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/stubs and generate Wiremock json stubs using: `./gradlew generateWireMockClientStubs` command. Note that `stubsOutputDir` option has to be set for stub generation to work. + +When present, json stubs can be used in consumer automated tests. + +[source,groovy,indent=0] +---- +@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application) +class LoanApplicationServiceSpec extends Specification { + + @ClassRule + @Shared + WireMockClassRule wireMockRule == new WireMockClassRule() + + @Autowired + LoanApplicationService sut + + def 'should successfully apply for loan'() { + given: + LoanApplication application = + new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123) + when: + LoanApplicationResult loanApplication == sut.loanApplication(application) + then: + loanApplication.loanApplicationStatus === LoanApplicationStatus.LOAN_APPLIED + loanApplication.rejectionReason === null + } +} +---- + +Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. + +=== Using in your Maven project + +==== Add maven plugin + +[source,xml,indent=0] +---- + + io.codearte.accurest + accurest-maven-plugin + + + + convert + generateStubs + generateTests + + + + +---- + +Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) + +==== Add stubs + +By default Accurest is looking for stubs in `src/test/accurest` 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 + +[source,groovy,indent=0] +---- +src/test/accurest/myservice/shouldCreateUser.groovy +src/test/accurest/myservice/shouldReturnUser.groovy +---- + +Accurest will create test class `defaultBasePackage.MyService` with two methods + - `shouldCreateUser()` + - `shouldReturnUser()` + +==== Run plugin + +Plugin goal `generateTests` is assigned to be invoked in phase `generate-test-sources`. 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 `generateTests` goal. + +==== Configure plugin + +To change default configuration just add `configuration` section to plugin definition or `execution` definition. + +[source,xml,indent=0] +---- + + io.codearte.accurest + accurest-maven-plugin + + + + convert + generateStubs + generateTests + + + + + com.ofg.twitter.place + com.ofg.twitter.place.BaseMockMvcSpec + + +---- + +===== Configuration options + + - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. + - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. + - **ruleClassForTests** - specifies Rule which should be added to generated test classes. + - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification`. + - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/accurest`. + - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `target/generated-test-sources/accurest`. + - **mappingsDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed. + - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework + +===== Base class for tests + + When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. + +[source,groovy,indent=0] +---- +package org.mycompany.tests + +import org.mycompany.ExampleSpringController +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import spock.lang.Specification + +class MvcSpec extends Specification { + def setup() { + RestAssuredMockMvc.standaloneSetup(new ExampleSpringController()) + } +} +---- + +In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. + +==== Invoking generated tests + +Accurest Maven Plugins generates verification code into directory `/generated-test-sources/accurest` and attach this directory to `testCompile` goal. + +For Groovy Spock code use: + +[source,xml,indent=0] +---- + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.5 + + + + testCompile + + + + + + + ${project.basedir}/src/test/groovy + + **/*.groovy + + + + ${project.build.directory}/generated-test-sources/accurest + + **/*.groovy + + + + + +---- + +To ensure that provider side is complaint with defined contracts, you need to invoke `mvn generateTest test` + +==== Accurest on consumer side + +In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. + +Sample configuration: + +[source,xml,indent=0] +---- + + io.codearte.accurest + accurest-maven-plugin + ${accurest.version} + + + + convert + generateStubs + + + + +---- + +When present, json stubs can be used in consumer automated tests. + +[source,groovy,indent=0] +---- +@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application) +class LoanApplicationServiceSpec extends Specification { + + @ClassRule + @Shared + WireMockClassRule wireMockRule == new WireMockClassRule() + + @Autowired + LoanApplicationService sut + + def 'should successfully apply for loan'() { + given: + LoanApplication application = + new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123) + when: + LoanApplicationResult loanApplication == sut.loanApplication(application) + then: + loanApplication.loanApplicationStatus === LoanApplicationStatus.LOAN_APPLIED + loanApplication.rejectionReason === null + } +} +---- + +Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. \ No newline at end of file From d9954503ec0c57e204d3bebea1c509b3674a85da Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 21 Apr 2016 01:07:43 +0200 Subject: [PATCH 511/719] Fixed the way contracts are copied --- .../accurest/plugin/AccurestIntegrationSpec.groovy | 4 ---- .../accurest/plugin/BasicFunctionalSpec.groovy | 2 +- .../accurest/plugin/MessagingProjectSpec.groovy | 4 ++-- .../accurest/plugin/SampleJerseyProjectSpec.groovy | 4 ++-- .../accurest/plugin/SampleProjectSpec.groovy | 4 ++-- .../accurest/plugin/ScenarioProjectSpec.groovy | 4 ++-- .../resources/functionalTest/bootSimple/build.gradle | 12 ++++++++---- .../functionalTest/messagingProject/build.gradle | 8 ++++++-- .../functionalTest/sampleJerseyProject/build.gradle | 12 ++++++++---- .../functionalTest/sampleProject/build.gradle | 12 ++++++++---- .../functionalTest/scenarioProject/build.gradle | 12 ++++++++---- 11 files changed, 47 insertions(+), 31 deletions(-) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy index f5b5ac98bb..19abff5588 100644 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy @@ -35,17 +35,14 @@ abstract class AccurestIntegrationSpec extends Specification { protected void setupForProject(String projectRoot) { copyResourcesToRoot(projectRoot) - def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.txt") if (pluginClasspathResource == null) { throw new IllegalStateException("Did not find 'plugin-classpath.txt'") } - String pluginClasspath = pluginClasspathResource.readLines() .collect { it.replace('\\', '\\\\') } // escape backslashes in Windows paths .collect { "'$it'" } .join(", ") - buildFile << """ buildscript { dependencies { @@ -53,7 +50,6 @@ abstract class AccurestIntegrationSpec extends Specification { } } """ - // Extending buildscript is required when 'apply' is used. // 'GradleRunner#withPluginClasspath' can be used when plugin is added using 'plugins { id...' } 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 cb6839cba1..015825ccf1 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 @@ -21,7 +21,7 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { def "should pass basic flow"() { when: - BuildResult result = run("check") + BuildResult result = run("check", "publishToMavenLocal") then: result.task(":generateWireMockClientStubs").outcome == SUCCESS result.task(":generateAccurest").outcome == SUCCESS diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy index 502d3cfda2..0a57265380 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy @@ -14,7 +14,7 @@ class MessagingProjectSpec extends AccurestIntegrationSpec { given: assert fileExists('build.gradle') expect: - runTasksSuccessfully('check') + runTasksSuccessfully('check', "publishToMavenLocal") } def "should pass basic flow for JUnit"() { @@ -23,7 +23,7 @@ class MessagingProjectSpec extends AccurestIntegrationSpec { assert fileExists('build.gradle') expect: switchToJunitTestFramework('io.codearte.accurest.samples.book.MessagingBaseSpec', 'io.codearte.accurest.samples.book.MessagingBaseTest') - runTasksSuccessfully('check') + runTasksSuccessfully('check', "publishToMavenLocal") } } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy index f1b429d627..fe970626ab 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -14,7 +14,7 @@ class SampleJerseyProjectSpec extends AccurestIntegrationSpec { given: assert fileExists('build.gradle') expect: - runTasksSuccessfully('check') + runTasksSuccessfully('check', "publishToMavenLocal") } def "should pass basic flow for JUnit"() { @@ -22,7 +22,7 @@ class SampleJerseyProjectSpec extends AccurestIntegrationSpec { switchToJunitTestFramework() assert fileExists('build.gradle') expect: - runTasksSuccessfully('check') + runTasksSuccessfully('check', "publishToMavenLocal") } } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index e27e948003..f14c277106 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -14,7 +14,7 @@ class SampleProjectSpec extends AccurestIntegrationSpec { given: assert fileExists('build.gradle') expect: - runTasksSuccessfully('check') + runTasksSuccessfully('check', "publishToMavenLocal") } def "should pass basic flow for JUnit"() { @@ -22,7 +22,7 @@ class SampleProjectSpec extends AccurestIntegrationSpec { switchToJunitTestFramework() assert fileExists('build.gradle') expect: - runTasksSuccessfully('check') + runTasksSuccessfully('check', "publishToMavenLocal") } } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy index 260d82c1c9..ce4db6e798 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy @@ -14,7 +14,7 @@ class ScenarioProjectSpec extends AccurestIntegrationSpec { given: assert fileExists('build.gradle') expect: - runTasksSuccessfully('check') + runTasksSuccessfully('check', "publishToMavenLocal") } def "should pass basic flow for JUnit"() { @@ -22,7 +22,7 @@ class ScenarioProjectSpec extends AccurestIntegrationSpec { assert fileExists('build.gradle') expect: switchToJunitTestFramework() - runTasksSuccessfully('check') + runTasksSuccessfully('check', "publishToMavenLocal") } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 4db3e39f58..b20f2a69eb 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -8,11 +8,13 @@ apply plugin: 'groovy' apply plugin: 'accurest' apply plugin: 'maven-publish' +group = 'io.codearte.accurest.testprojects' + ext { - contractsDir = file("${project.rootDir}/repository/mappings/") + contractsDir = file("repository/mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/') - contractsOutputDir = new File(stubsOutputDirRoot, 'repository/accurest/') + wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) + contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) } configurations { @@ -71,11 +73,13 @@ wrapper { task copyContracts(type: Copy) { from contractsDir + include '**/*.groovy' into contractsOutputDir } task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}-stubs" + baseName = "${project.name}" + classifier = "stubs" from stubsOutputDirRoot } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle index f48bbe9c4f..cb15b57e01 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle @@ -13,8 +13,10 @@ apply plugin: 'groovy' apply plugin: 'accurest' apply plugin: 'maven-publish' +group = 'io.codearte.accurest.testprojects' + ext { - contractsDir = file("${project.rootDir}/repository/mappings/") + contractsDir = file("repository/mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/') contractsOutputDir = new File(stubsOutputDirRoot, 'repository/accurest/') @@ -84,11 +86,13 @@ wrapper { task copyContracts(type: Copy) { from contractsDir + include '**/*.groovy' into contractsOutputDir } task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}-stubs" + baseName = "${project.name}" + classifier = "stubs" from stubsOutputDirRoot } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index 7bcf25e20f..8cf1b6941e 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -8,6 +8,8 @@ buildscript { } } +group = 'io.codearte.accurest.testprojects' + ext { restAssuredVersion = '2.5.0' spockVersion = '1.0-groovy-2.4' @@ -38,10 +40,10 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') apply plugin: 'maven-publish' ext { - contractsDir = file("${project.rootDir}/repository/mappings/") + contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/') - contractsOutputDir = new File(stubsOutputDirRoot, 'repository/accurest/') + wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) + contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) } accurest { @@ -80,11 +82,13 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') task copyContracts(type: Copy) { from contractsDir + include '**/*.groovy' into contractsOutputDir } task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}-stubs" + baseName = "${project.name}" + classifier = "stubs" from stubsOutputDirRoot } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 166d4dc91e..c2fb66a1f6 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -16,6 +16,8 @@ ext { accurestStubsBaseDirectory = 'src/test/resources/stubs' } +group = 'io.codearte.accurest.testprojects' + subprojects { apply plugin: 'groovy' @@ -38,10 +40,10 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') apply plugin: 'maven-publish' ext { - contractsDir = file("${project.rootDir}/repository/mappings/") + contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/') - contractsOutputDir = new File(stubsOutputDirRoot, 'repository/accurest/') + wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) + contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) } accurest { @@ -79,10 +81,12 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') task copyContracts(type: Copy) { from contractsDir into contractsOutputDir + includeEmptyDirs = true } task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}-stubs" + baseName = "${project.name}" + classifier = "stubs" from stubsOutputDirRoot } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index e5b1dfb4db..da7b0be424 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -16,6 +16,8 @@ ext { accurestStubsBaseDirectory = 'src/test/resources/stubs' } +group = 'io.codearte.accurest.testprojects' + subprojects { apply plugin: 'groovy' apply plugin: 'maven-publish' @@ -38,10 +40,10 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') apply plugin: 'accurest' ext { - contractsDir = file("${project.rootDir}/repository/mappings/") + contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/') - contractsOutputDir = new File(stubsOutputDirRoot, 'repository/accurest/') + wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) + contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) } accurest { @@ -80,11 +82,13 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') task copyContracts(type: Copy) { from contractsDir + include '**/*.groovy' into contractsOutputDir } task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}-stubs" + baseName = "${project.name}" + classifier = "stubs" from stubsOutputDirRoot } From fb94585b89078476c1a391b97022844c430bb840 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 21 Apr 2016 09:27:17 +0200 Subject: [PATCH 512/719] Reusing adocs of modules --- docs/src/docs/asciidoc/index.adoc | 197 +----------------- docs/src/docs/asciidoc/stubrunner.adoc | 37 ++++ stub-runner/stub-runner-junit/README.adoc | 106 ++++++++++ stub-runner/stub-runner-junit/README.md | 49 ----- .../{README.md => README.adoc} | 8 +- .../{README.md => README.adoc} | 34 +-- .../stub-runner/{README.md => README.adoc} | 52 ++--- 7 files changed, 198 insertions(+), 285 deletions(-) create mode 100644 docs/src/docs/asciidoc/stubrunner.adoc create mode 100644 stub-runner/stub-runner-junit/README.adoc delete mode 100644 stub-runner/stub-runner-junit/README.md rename stub-runner/stub-runner-spring-cloud/{README.md => README.adoc} (88%) rename stub-runner/stub-runner-spring/{README.md => README.adoc} (66%) rename stub-runner/stub-runner/{README.md => README.adoc} (83%) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 653bc221bc..306aa0d6b0 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -631,203 +631,8 @@ Example of AccuREST Gradle setup: Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) -=== Using Stub Runner to automate running stubs +include::stubrunner.adoc[] -Stub Runner automates downloading stubs from a Maven repository (that includes also the local Maven repository) and starting the WireMock server for each of those stubs. - -==== Modules - -AccuREST comes with a new structure of modules - -[source,indent=0] ----- -└── stub-runner - ├── stub-runner - ├── stub-runner-junit - ├── stub-runner-spring - └── stub-runner-spring-cloud ----- - -===== Stub Runner - -Contains core logic of Stub Runner. Gives you a main class to run Stub Runner from the command line or from Gradle. - -Here you can see a list of options with which you can run Stub Runner: - -[source,indent=0] ----- -java -jar stub-runner.jar [options...] - -maxp (--maxPort) N : Maximum port value to be assigned to the - Wiremock instance. Defaults to 15000 - (default: 15000) - -minp (--minPort) N : Minimal port value to be assigned to the - Wiremock instance. Defaults to 10000 - (default: 10000) - -s (--stubs) VAL : Comma separated list of Ivy representation of - jars with stubs. Eg. groupid:artifactid1,group - id2:artifactid2:classifier - -sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you - keep your stubs (e.g. http://nexus.net/content - /repositories/repository) - -ss (--stubsSuffix) VAL : Suffix for the jar containing stubs (e.g. - 'stubs' if the stub jar would have a 'stubs' - classifier for stubs: foobar-stubs ). - Defaults to 'stubs' (default: stubs) - -wo (--workOffline) : Switch to work offline. Defaults to 'false' - (default: false) ----- - -You can either produce a fat-jar and run the app like presented above. - -You can also configure the stub runner by either passing the full arguments list with the `-Pargs` like this: - -`./gradlew stub-runner-root:stub-runner:run -Pargs="-c pl -minp 10000 -maxp 10005 -s a:b:c,d:e,f:g:h"` - -or each parameter separately with a `-P` prefix and without the hyphen (-) in the name of the param - -`./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h` - -===== Stub Runner JUnit Rule - -Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id: - -[source,java,indent=0] ----- -@ClassRule public static AccurestRule rule == new AccurestRule() - .repoRoot("http://your.repo.com") - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") - .downloadStub("io.codearte:stub1", "io.codearte:stub2:classifier", "io.codearte:stub3"); ----- - -After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to: -* download them -* cache them locally -* unzip them to a temporary folder -* start a WireMock server for each Maven dependency on a random port from the provided range of ports -* feed the WireMock server with all JSON files that are valid WireMock definitions - -Stub Runner uses [Groovy's Grape](http://docs.groovy-lang.org/latest/html/documentation/grape.html) mechanism to download the Maven dependencies. Check their [docs](http://docs.groovy-lang.org/latest/html/documentation/grape.html) for more information. - -Since the `AccurestRule` implements the `StubFinder` it allows you to find the started stubs: - -[source,groovy,indent=0] ----- -interface StubFinder { - /** - * For the given groupId and artifactId tries to find the matching - * URL of the running stub. - * - * @param groupId - might be null. In that case a search only via artifactId takes place - * @return URL of a running stub or null if not found - */ - URL findStubUrl(String groupId, String artifactId) - - /** - * For the given Ivy notation {@code groupId:artifactId} tries to find the matching - * URL of the running stub. You can also pass only {@code artifactId}. - * - * @param ivyNotation - Ivy representation of the Maven artifact - * @return URL of a running stub or null if not found - */ - URL findStubUrl(String ivyNotation) - - /** - * Returns all running stubs - */ - RunningStubs findAllRunningStubs() -} ----- - -Example of usage in Spock tests: - -[source,groovy,indent=0] ----- -@ClassRule @Shared AccurestRule rule == new AccurestRule() - .repoRoot('http://your.repo.com') - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') !== null - rule.findStubUrl('loanIssuance') !== null - rule.findStubUrl('loanIssuance') === rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') !== null - and: - rule.findAllRunningStubs().isPresent('loanIssuance') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text === 'loanIssuance' - "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text === 'fraudDetectionServer' - } ----- - -Example of usage in JUnit tests: - -[source,java,indent=0] ----- -@ClassRule public static AccurestRule rule == new AccurestRule() - .repoRoot("http://your.repo.com") - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); - - @Test - public void should_start_wiremock_servers() throws Exception { - // expect: 'WireMocks are running' - then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")); - then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull(); - // and: - then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue(); - // and: 'Stubs were registered' - then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); - then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); - } ----- - -Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. - -===== Stub Runner Spring - -If you're using Spring then you can just import the `io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration` and a bean of type `StubFinder` will get registered. - -In order to find a URL and port of a given dependency you can autowire the bean in your test and call its methods: - -[source,groovy,indent=0] ----- -@ContextConfiguration(classes == Config, loader == SpringApplicationContextLoader) -class StubRunnerConfigurationSpec extends Specification { - - @Autowired StubFinder stubFinder - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') !== null - stubFinder.findStubUrl('loanIssuance') !== null - stubFinder.findStubUrl('loanIssuance') === stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') !== null - and: - stubFinder.findAllRunningStubs().isPresent('loanIssuance') - stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text === 'loanIssuance' - "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text === 'fraudDetectionServer' - } - - @Configuration - @Import(StubRunnerConfiguration) - @EnableAutoConfiguration - static class Config {} -} ----- - -Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. ===== Stub Runner Spring Cloud diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc new file mode 100644 index 0000000000..71c9711bc1 --- /dev/null +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -0,0 +1,37 @@ +== Using Stub Runner to automate running stubs + +Stub Runner automates downloading stubs from a Maven repository (that includes also the local Maven repository) and starting the WireMock server for each of those stubs. + +=== Modules + +AccuREST comes with a new structure of modules + +[source,indent=0] +---- +└── stub-runner + ├── stub-runner + ├── stub-runner-junit + ├── stub-runner-spring + └── stub-runner-spring-cloud +---- + +include::../../../../stub-runner/stub-runner/README.adoc[] +include::../../../../stub-runner/stub-runner-junit/README.adoc[] +include::../../../../stub-runner/stub-runner-spring/README.adoc[] +include::../../../../stub-runner/stub-runner-spring-cloud/README.adoc[] + + +===== Common properties for JUnit and Spring + +Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values: + +[width="60%",frame="topbot",options="header"] +|====================== +| Property name | Default value | Description | +|stubrunner.port.range.min|10000| Minimal value of a port for a started WireMock with stubs| +|stubrunner.port.range.max|15000| Minimal value of a port for a started WireMock with stubs| +|stubrunner.stubs.repository.root|| Maven repo url. If blank then will call the local maven repo| +|stubrunner.stubs.classifier|stubs| Default classifier for the stub artifacts| +|stubrunner.work-offline|false| If true then will not contact any remote repositories to download stubs| +|stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| +|====================== \ No newline at end of file diff --git a/stub-runner/stub-runner-junit/README.adoc b/stub-runner/stub-runner-junit/README.adoc new file mode 100644 index 0000000000..23b995c55f --- /dev/null +++ b/stub-runner/stub-runner-junit/README.adoc @@ -0,0 +1,106 @@ +=== Stub Runner JUnit Rule + +Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id: + +[source,java,indent=0] +---- +@ClassRule public static AccurestRule rule == new AccurestRule() + .repoRoot("http://your.repo.com") + .downloadStub("io.codearte.accurest.stubs", "loanIssuance") + .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") + .downloadStub("io.codearte:stub1", "io.codearte:stub2:classifier", "io.codearte:stub3"); +---- + +After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to: +* download them +* cache them locally +* unzip them to a temporary folder +* start a WireMock server for each Maven dependency on a random port from the provided range of ports +* feed the WireMock server with all JSON files that are valid WireMock definitions + +Stub Runner uses http://docs.groovy-lang.org/latest/html/documentation/grape.html[Groovy's Grape] mechanism to download the Maven dependencies. +Check their http://docs.groovy-lang.org/latest/html/documentation/grape.html[docs] for more information. + +Since the `AccurestRule` implements the `StubFinder` it allows you to find the started stubs: + +[source,groovy,indent=0] +---- +interface StubFinder { + /** + * For the given groupId and artifactId tries to find the matching + * URL of the running stub. + * + * @param groupId - might be null. In that case a search only via artifactId takes place + * @return URL of a running stub or null if not found + */ + URL findStubUrl(String groupId, String artifactId) + + /** + * For the given Ivy notation {@code groupId:artifactId} tries to find the matching + * URL of the running stub. You can also pass only {@code artifactId}. + * + * @param ivyNotation - Ivy representation of the Maven artifact + * @return URL of a running stub or null if not found + */ + URL findStubUrl(String ivyNotation) + + /** + * Returns all running stubs + */ + RunningStubs findAllRunningStubs() +} +---- + +Example of usage in Spock tests: + +[source,groovy,indent=0] +---- +@ClassRule @Shared AccurestRule rule == new AccurestRule() + .repoRoot('http://your.repo.com') + .downloadStub("io.codearte.accurest.stubs", "loanIssuance") + .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") + + def 'should start WireMock servers'() { + expect: 'WireMocks are running' + rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') !== null + rule.findStubUrl('loanIssuance') !== null + rule.findStubUrl('loanIssuance') === rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') !== null + and: + rule.findAllRunningStubs().isPresent('loanIssuance') + rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') + rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') + and: 'Stubs were registered' + "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text === 'loanIssuance' + "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text === 'fraudDetectionServer' + } +---- + +Example of usage in JUnit tests: + +[source,java,indent=0] +---- +@ClassRule public static AccurestRule rule == new AccurestRule() + .repoRoot("http://your.repo.com") + .downloadStub("io.codearte.accurest.stubs", "loanIssuance") + .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); + + @Test + public void should_start_wiremock_servers() throws Exception { + // expect: 'WireMocks are running' + then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")); + then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull(); + // and: + then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); + then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue(); + then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue(); + // and: 'Stubs were registered' + then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); + then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); + } +---- + +Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. + diff --git a/stub-runner/stub-runner-junit/README.md b/stub-runner/stub-runner-junit/README.md deleted file mode 100644 index 83a6a51adf..0000000000 --- a/stub-runner/stub-runner-junit/README.md +++ /dev/null @@ -1,49 +0,0 @@ -stub-runner-junit -================= - -Contains a JUnit Rule for Stub Runner. - -Example of usage: - -``` -class AccurestRuleSpec extends Specification { - - @ClassRule @Shared AccurestRule rule = new AccurestRule() - .repoRoot(AccurestRuleSpec.getResource("/m2repo").path) - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - rule.findStubUrl('loanIssuance') != null - rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null - and: - rule.findAllRunningStubs().isPresent('loanIssuance') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' - } -} -``` - -You can set the default value of the Maven repository by means of a system property: - -``` --Dstubrunner.stubs.repository.root=http://your.maven.repo.com -``` - -The list of configurable properties contains: - -| Name | Default value | Description | -|------|---------------|-------------| -| stubrunner.port.range.min | 10000 | Minimal value of a port for a WireMock server | -| stubrunner.port.range.max | 15000 | Maximum value of a port for a WireMock server | -| stubrunner.stubs.repository.root | | Address to your M2 repo (will point to local M2 repo if none is provided) | -| stubrunner.stubs.classifier | stubs | Default classifier for the JARs containing stubs | -| stubrunner.work-offline | false | Should try to connect to any repo to download stubs (useful if there's no internet) | -| stubrunner.stubs | | Default comma separated list of stubs to download | - diff --git a/stub-runner/stub-runner-spring-cloud/README.md b/stub-runner/stub-runner-spring-cloud/README.adoc similarity index 88% rename from stub-runner/stub-runner-spring-cloud/README.md rename to stub-runner/stub-runner-spring-cloud/README.adoc index 0d7b496245..003b94422f 100644 --- a/stub-runner/stub-runner-spring-cloud/README.md +++ b/stub-runner/stub-runner-spring-cloud/README.adoc @@ -1,11 +1,11 @@ -stub-runner-spring-cloud -======================== +=== Stub Runner Spring Cloud Registers the stubs in the provided Service Discovery. It's enough to add the jar -``` +[source,groovy,indent=0] +---- io.codearte.accurest:stub-runner-spring-cloud -``` +---- and the Stub Runner autoconfiguration should be picked up. diff --git a/stub-runner/stub-runner-spring/README.md b/stub-runner/stub-runner-spring/README.adoc similarity index 66% rename from stub-runner/stub-runner-spring/README.md rename to stub-runner/stub-runner-spring/README.adoc index 5fbe827657..0d87fe9146 100644 --- a/stub-runner/stub-runner-spring/README.md +++ b/stub-runner/stub-runner-spring/README.adoc @@ -1,5 +1,4 @@ -stub-runner-spring -======================= +=== Stub Runner Spring Sets up Spring configuration of the Stub Runner project. @@ -9,28 +8,39 @@ and registers in WireMock the selected stubs. If you want to find the URL of your stubbed dependency you can autowire the `StubFinder` interface and use its methods as presented below: -``` +[source,groovy,indent=0] +---- +@ContextConfiguration(classes == Config, loader == SpringApplicationContextLoader) +class StubRunnerConfigurationSpec extends Specification { + @Autowired StubFinder stubFinder def 'should start WireMock servers'() { expect: 'WireMocks are running' - stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null + stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') !== null + stubFinder.findStubUrl('loanIssuance') !== null + stubFinder.findStubUrl('loanIssuance') === stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') + stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') !== null and: stubFinder.findAllRunningStubs().isPresent('loanIssuance') stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') and: 'Stubs were registered' - "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text === 'loanIssuance' + "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text === 'fraudDetectionServer' } -``` + + @Configuration + @Import(StubRunnerConfiguration) + @EnableAutoConfiguration + static class Config {} +} +---- for the following configuration file: -``` +[source,groovy,indent=0] +---- stubrunner.stubs.repository.root: classpath:m2repo stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer -``` \ No newline at end of file +---- \ No newline at end of file diff --git a/stub-runner/stub-runner/README.md b/stub-runner/stub-runner/README.adoc similarity index 83% rename from stub-runner/stub-runner/README.md rename to stub-runner/stub-runner/README.adoc index 2a749ebb39..102a4225cf 100644 --- a/stub-runner/stub-runner/README.md +++ b/stub-runner/stub-runner/README.adoc @@ -1,16 +1,16 @@ -Stub-runner -=========== +=== Stub Runner core Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of -[Consumer Driven Contracts](http://martinfowler.com/articles/consumerDrivenContracts.html). +http://martinfowler.com/articles/consumerDrivenContracts.html[Consumer Driven Contracts]. -### Running stubs +==== Running stubs -#### Running using main app +===== Running using main app You can set the following options to the main class: -``` +[source,groovy,indent=0] +---- -maxp (--maxPort) N : Maximum port value to be assigned to the Wiremock instance. Defaults to 15000 (default: 15000) @@ -29,45 +29,49 @@ You can set the following options to the main class: Defaults to 'stubs' (default: stubs) -wo (--workOffline) : Switch to work offline. Defaults to 'false' (default: false) - -``` +---- -#### Building a Fat Jar +===== Building a Fat Jar Just call the following command: -``` +[source,groovy,indent=0] +---- ./gradlew stub-runner-root:stub-runner:shadowJar -PfatJar -``` +---- and inside the `build/lib` there will be a Fat Jar with classifier `fatJar` waiting for you to execute. E.g. -``` +[source,groovy,indent=0] +---- java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h -``` +---- -### Stub runner configuration +==== Stub runner configuration You can configure the stub runner by either passing the full arguments list with the `-Pargs` like this: -``` +[source,groovy,indent=0] +---- ./gradlew stub-runner-root:stub-runner:run -Pargs="-c pl -minp 10000 -maxp 10005 -s a:b:c,d:e,f:g:h" -``` +---- or each parameter separately with a `-P` prefix and without the hyphen `-` in the name of the param -``` +[source,groovy,indent=0] +---- ./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h -``` +---- +===== Stubs -#### Stubs - -Stubs are defined in JSON documents, whose syntax is defined in [WireMock documentation](http://wiremock.org/stubbing.html) +Stubs are defined in JSON documents, whose syntax is defined in http://wiremock.org/stubbing.html[WireMock documentation] Example: -```json + +[source,javascript,indent=0] +---- { "request": { "method": "GET", @@ -81,10 +85,10 @@ Example: } } } -``` +---- In the provided JAR file we're harvesting all JSON files and try to put them inside running WireMock instance. -#### Viewing registered mappings +===== Viewing registered mappings Every stubbed collaborator exposes list of defined mappings under `__/admin/` endpoint. \ No newline at end of file From 1385d7001cb81094af35140475fc773e56f1ec6b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 21 Apr 2016 09:28:44 +0200 Subject: [PATCH 513/719] Fixed wrong indents --- docs/src/docs/asciidoc/index.adoc | 20 -------------------- docs/src/docs/asciidoc/stubrunner.adoc | 2 +- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 306aa0d6b0..4058bc66bb 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -633,26 +633,6 @@ Example of Maven can be found in the [AccuREST Maven Plugin README](https://gith include::stubrunner.adoc[] - -===== Stub Runner Spring Cloud - -If you're using Spring Cloud then it's enough to add `stub-runner-spring-cloud` on classpath and automatically a bean of type `StubFinder` will get registered. - -===== Common properties for JUnit and Spring - -Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values: - -[width="60%",frame="topbot",options="header"] -|====================== -| Property name | Default value | Description | -|stubrunner.port.range.min|10000| Minimal value of a port for a started WireMock with stubs| -|stubrunner.port.range.max|15000| Minimal value of a port for a started WireMock with stubs| -|stubrunner.stubs.repository.root|| Maven repo url. If blank then will call the local maven repo| -|stubrunner.stubs.classifier|stubs| Default classifier for the stub artifacts| -|stubrunner.work-offline|false| If true then will not contact any remote repositories to download stubs| -|stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| -|====================== - == Migration Guide === Migration to 0.4.7 diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index 71c9711bc1..6141313185 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -21,7 +21,7 @@ include::../../../../stub-runner/stub-runner-spring/README.adoc[] include::../../../../stub-runner/stub-runner-spring-cloud/README.adoc[] -===== Common properties for JUnit and Spring +=== Common properties for JUnit and Spring Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values: From 928e2b9422b686b562bba2dcaee2be85d4fcc880 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 21 Apr 2016 09:48:59 +0200 Subject: [PATCH 514/719] Updated docs --- README.md | 13 ++-- .../scenarioProject/build.gradle | 52 +++++++------- docs/src/docs/asciidoc/index.adoc | 71 +++---------------- docs/src/docs/asciidoc/stubrunner.adoc | 24 ++++++- 4 files changed, 65 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index 541dfbd5ce..e74e3047a0 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,18 @@ -Accurate REST -============= +Accurest +======== [![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) [![Join the chat at https://gitter.im/Codearte/accurest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Codearte/accurest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) Consumer Driven Contracts verifier for Java -To make a long story short - AccuREST is a tool for Consumer Driven Contract (CDC) development. AccuREST ships an easy DSL for describing REST contracts for JVM-based applications. The contract DSL is used by AccuREST for two things: +To make a long story short - Accurest is a tool for Consumer Driven Contract (CDC) development. Accurest ships an easy DSL for describing REST contracts for JVM-based applications. + Since version 1.0.7 it also supports messaging. + +The contract DSL is used by Accurest for two things: -1. 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. +1. generating WireMock's JSON stub definitions / stubbed messaging endpoints, allowing rapid development of the consumer side, +generating JUnit / Spock's acceptance tests for the server - to verify if your API implementation is compliant with the contract. 2. moving TDD to an architecture level. For more information please go to the [Documentation](http://codearte.github.io/accurest/) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index da7b0be424..4d4edb4965 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -39,6 +39,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') apply plugin: 'spring-boot' apply plugin: 'accurest' + // tag::jar_setup[] ext { contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") @@ -46,6 +47,32 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) } + task copyContracts(type: Copy) { + from contractsDir + include '**/*.groovy' + into contractsOutputDir + } + + task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { + baseName = "${project.name}" + classifier = "stubs" + from stubsOutputDirRoot + } + + artifacts { + archives stubsJar + } + + publishing { + publications { + stubs(MavenPublication) { + artifactId "${project.name}-stubs" + artifact stubsJar + } + } + } + // end::jar_setup[] + accurest { // tag::target_framework[] targetFramework = 'Spock' @@ -80,31 +107,6 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') clean.dependsOn('cleanup') - task copyContracts(type: Copy) { - from contractsDir - include '**/*.groovy' - into contractsOutputDir - } - - task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}" - classifier = "stubs" - from stubsOutputDirRoot - } - - artifacts { - archives stubsJar - } - - publishing { - publications { - stubs(MavenPublication) { - artifactId "${project.name}-stubs" - artifact stubsJar - } - } - } - test { testLogging { exceptionFormat = 'full' diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 4058bc66bb..29acda015d 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,19 +1,19 @@ -Welcome to the AccuREST Wiki! +Welcome to the Accurest Wiki! Please follow to the Introduction page to start your journey with Consumer Driven Contracts in JVM == Introduction -Just to make long story short - AccuREST is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by AccuREST to produce following resources: +Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: -* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by AccuREST. -* Acceptance tests (in Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by AccuREST. +* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by Accurest. +* Acceptance tests (in Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by Accurest. -AccuREST moves TDD to the level of software architecture. +Accurest moves TDD to the level of software architecture. === Why? -The main purposes of AccuREST are: +The main purposes of Accurest are: - to ensure that WireMock stubs (used when developing the client) are doing exactly what actual server-side implementation will do, - to promote ATDD method and Microservices architectural style, @@ -26,7 +26,7 @@ include::messaging.adoc[] == Contract DSL -Contract DSL in AccuREST is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, AccuREST's DSL is designed to be programmer-readable without any knowledge of the DSL itself. +Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself. Let's look at full example of a contract definition. @@ -90,7 +90,7 @@ io.codearte.accurest.dsl.GroovyDsl.make { === Request -HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of AccuREST contract. +HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of Accurest contract. [source,groovy,indent=0] ---- @@ -576,61 +576,6 @@ More details about Wiremock scenarios can be found under [http://wiremock.org/st Accurest will also generate tests with guaranteed order of execution. -== Stub Runner - -One of the issues that you could have encountered while using AccuREST was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). Copying the JSON files manually is out of the question. - -In this article you'll see how to prepare your project to start publishing stubs as JARs and how to use Stub Runner in your tests to run WireMock servers and feed them with stub definitions. - -=== Publishing stubs as JARs - -The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository. - -==== Gradle - -Example of AccuREST Gradle setup: - -[source,groovy,indent=0] ----- - apply plugin: 'maven-publish' - - ext { - wiremockStubsOutputDirRoot == file("${project.buildDir}/production/${project.name}-stubs/") - wiremockStubsOutputDir == new File(wiremockStubsOutputDirRoot) - } - - accurest { - targetFramework == 'Spock' - testMode == 'MockMvc' - baseClassForTests == 'com.toomuchcoding.MvcSpec' - contractsDslDir == file("${project.projectDir.absolutePath}/mappings/") - generatedTestSourcesDir == file("${project.buildDir}/generated-sources/") - stubsOutputDir == wiremockStubsOutputDir - } - - task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs"]) { - baseName == "${project.name}-stubs" - from wiremockStubsOutputDirRoot - } - - artifacts { - archives stubsJar - } - - publishing { - publications { - stubs(MavenPublication) { - artifactId "${project.name}-stubs" - artifact stubsJar - } - } - } ----- - -==== Maven - -Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) - include::stubrunner.adoc[] == Migration Guide diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index 6141313185..bd12682eea 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -1,6 +1,26 @@ -== Using Stub Runner to automate running stubs +== Stub Runner -Stub Runner automates downloading stubs from a Maven repository (that includes also the local Maven repository) and starting the WireMock server for each of those stubs. +One of the issues that you could have encountered while using Accurest was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). + The same takes place in terms of client side generation for messaging. + +Copying the JSON files / setting the client side for messaging manually is out of the question. + +=== Publishing stubs as JARs + +The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository. + +==== Gradle + +Example of Accurest Gradle setup: + +[source,groovy,indent=0] +---- +include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=jar_setup,indent=0] +---- + +==== Maven + +Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) === Modules From 493754653219088ec59262035043f69473665882 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Zaj=C4=85czkowski?= Date: Thu, 21 Apr 2016 13:39:45 +0200 Subject: [PATCH 515/719] Simplify parametrized tests with spock-global-unroll (#239) --- .../accurest/SingleTestGeneratorSpec.groovy | 3 -- .../JaxRsClientMethodBuilderSpec.groovy | 18 ----------- .../MockMvcMethodBodyBuilderSpec.groovy | 32 ------------------- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 3 -- .../dsl/internal/RegexPatternsSpec.groovy | 6 ---- .../util/JsonToJsonPathsConverterSpec.groovy | 2 -- build.gradle | 1 + 7 files changed, 1 insertion(+), 64 deletions(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy index 222ab44ba4..853ec184cf 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -6,7 +6,6 @@ import io.codearte.accurest.file.Contract import org.junit.Rule import org.junit.rules.TemporaryFolder import spock.lang.Specification -import spock.lang.Unroll import static io.codearte.accurest.config.TestFramework.JUNIT import static io.codearte.accurest.config.TestFramework.SPOCK @@ -43,7 +42,6 @@ class SingleTestGeneratorSpec extends Specification { """) } - @Unroll def "should build MockMvc test class for #testFramework"() { given: AccurestConfigProperties properties = new AccurestConfigProperties(); @@ -65,7 +63,6 @@ class SingleTestGeneratorSpec extends Specification { SPOCK | spockClassStrings } - @Unroll def "should build JaxRs test class for #testFramework"() { given: AccurestConfigProperties properties = new AccurestConfigProperties(); diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy index 0b07ec4759..0485a38d4d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy @@ -6,11 +6,9 @@ import io.codearte.accurest.dsl.WireMockStubVerifier import io.codearte.accurest.file.Contract import spock.lang.Issue import spock.lang.Specification -import spock.lang.Unroll class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStubVerifier { - @Unroll def "should generate assertions for simple response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -42,7 +40,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub } @Issue("#187") - @Unroll def "should generate assertions for null and boolean values with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -76,7 +73,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub } @Issue("#79") - @Unroll def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -112,7 +108,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub } @Issue("#82") - @Unroll def "should generate proper request when body constructed from map with a list with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -142,7 +137,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub } @Issue("#88") - @Unroll def "should generate proper request when body constructed from GString with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -171,7 +165,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"property1=VAL1\\"", "application/octet-stream")' } - @Unroll def "should generate assertions for array in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -205,7 +198,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate assertions for array inside response body element with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -238,7 +230,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate assertions for nested objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -271,7 +262,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate regex assertions for map objects in response body with #methodBodyName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -310,7 +300,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate regex assertions for string objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -343,7 +332,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should ignore 'Accept' header and use 'request' method with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -372,7 +360,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")' } - @Unroll def "should ignore 'Content-Type' header and use 'entity' method with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -406,7 +393,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")'] } - @Unroll def "should generate a call with an url path and query parameters with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -462,7 +448,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub } @Issue('#169') - @Unroll def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -517,7 +502,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } } - @Unroll def "should generate test for empty body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -546,7 +530,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"\\"", "application/octet-stream"' } - @Unroll def "should generate test for String in response body with #methodBodyName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -576,7 +559,6 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub } @Issue('#171') - @Unroll def "should generate test with uppercase method name with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index ed6ee0dd1f..03d70d99ba 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -5,7 +5,6 @@ import io.codearte.accurest.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Shared import spock.lang.Specification -import spock.lang.Unroll import java.util.regex.Pattern /** @@ -73,7 +72,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } } - @Unroll def "should generate assertions for simple response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -105,7 +103,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue("#187") - @Unroll def "should generate assertions for null and boolean values with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -139,7 +136,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue("#79") - @Unroll def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -175,7 +171,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue("#82") - @Unroll def "should generate proper request when body constructed from map with a list #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -205,7 +200,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue("#88") - @Unroll def "should generate proper request when body constructed from GString with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -235,7 +229,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue("185") - @Unroll def "should generate assertions for a response body containing map with integers as keys with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -268,7 +261,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate assertions for array in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -302,7 +294,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate assertions for array inside response body element with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -335,7 +326,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate assertions for nested objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -368,7 +358,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate regex assertions for map objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -405,7 +394,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate regex assertions for string objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -437,7 +425,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue(["#126", "#143"]) - @Unroll def "should generate escaped regex assertions for string objects in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -467,7 +454,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate a call with an url path and query parameters with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -516,7 +502,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue('#169') - @Unroll def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -564,7 +549,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should generate test for empty body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -592,7 +576,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")" } - @Unroll def "should generate test for String in response body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -622,7 +605,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue('113') - @Unroll def "should generate regex test for String in response header with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -662,7 +644,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue('115') - @Unroll def "should generate regex with helper method with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -701,7 +682,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "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 def "should work with more complex stuff and jsonpaths with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -743,7 +723,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should work properly with GString url with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -777,7 +756,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should resolve properties in GString with regular expression with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -818,7 +796,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue('42') - @Unroll def "should not omit the optional field in the test creation with MockMvcSpockMethodBodyBuilder"() { given: MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) @@ -837,7 +814,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue('42') - @Unroll def "should not omit the optional field in the test creation with MockMvcJUnitMethodBodyBuilder"() { given: MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) @@ -856,7 +832,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue('72') - @Unroll def "should make the execute method work with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -905,7 +880,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] } - @Unroll def "should support inner map and list definitions with #methodBuilderName"() { given: @@ -974,7 +948,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } - @Unroll def "shouldn't generate unicode escape characters with #methodBuilderName"() { given: Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) @@ -1014,7 +987,6 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Issue('177') - @Unroll def "should generate proper test code when having multiline body with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -1043,7 +1015,6 @@ World.'''""" } @Issue('180') - @Unroll def "should generate proper test code when having multipart parameters with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -1085,7 +1056,6 @@ World.'''""" } @Issue('180') - @Unroll def "should generate proper test code when having multipart parameters with named as map with #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -1118,7 +1088,6 @@ World.'''""" } @Issue('#216') - @Unroll def "should parse JSON with arrays using #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { @@ -1156,7 +1125,6 @@ World.'''""" "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - @Unroll def "should work with execution property"() { given: GroovyDsl contractDsl = GroovyDsl.make { 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 df097affe8..78ddfc8ca3 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 @@ -6,7 +6,6 @@ import io.codearte.accurest.file.Contract import io.codearte.accurest.util.AssertionUtil import spock.lang.Issue import spock.lang.Specification -import spock.lang.Unroll class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifier { @@ -1337,7 +1336,6 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } @Issue('42') - @Unroll def 'should generate stub without optional parameters'() { when: String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub() @@ -1442,7 +1440,6 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } @Issue('180') - @Unroll def 'should generate stub with multipart parameters'() { given: GroovyDsl contractDsl = GroovyDsl.make { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy index bc217f336e..3dca400003 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy @@ -1,7 +1,6 @@ package io.codearte.accurest.dsl.internal import spock.lang.Specification -import spock.lang.Unroll import java.util.regex.Pattern @@ -9,7 +8,6 @@ class RegexPatternsSpec extends Specification { RegexPatterns regexPatterns = new RegexPatterns() - @Unroll def "should generate a regex for ip address [#textToMatch] that is a match [#shouldMatch]"() { expect: shouldMatch == Pattern.compile(regexPatterns.ipAddress()).matcher(textToMatch).matches() @@ -19,7 +17,6 @@ class RegexPatternsSpec extends Specification { 'a.b.' || false } - @Unroll def "should generate a regex for hostname [#textToMatch] that is a match [#shouldMatch]"() { expect: shouldMatch == Pattern.compile(regexPatterns.hostname()).matcher(textToMatch).matches() @@ -33,7 +30,6 @@ class RegexPatternsSpec extends Specification { 'asd.com' || false } - @Unroll def "should generate a regex for email [#textToMatch] that is a match [#shouldMatch]"() { expect: shouldMatch == Pattern.compile(regexPatterns.email()).matcher(textToMatch).matches() @@ -43,7 +39,6 @@ class RegexPatternsSpec extends Specification { 'a.b.' || false } - @Unroll def "should generate a regex for url [#textToMatch] that is a match [#shouldMatch]"() { expect: shouldMatch == Pattern.compile(regexPatterns.url()).matcher(textToMatch).matches() @@ -53,7 +48,6 @@ class RegexPatternsSpec extends Specification { 'a.b.' || false } - @Unroll def "should generate a regex for a number [#textToMatch] that is a match [#shouldMatch]"() { expect: shouldMatch == Pattern.compile(regexPatterns.number()).matcher(textToMatch).matches() diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index 980fb5fcef..f25f7bc5b4 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -8,13 +8,11 @@ import groovy.json.JsonOutput import groovy.json.JsonSlurper import net.minidev.json.JSONArray import spock.lang.Specification -import spock.lang.Unroll import java.util.regex.Pattern class JsonToJsonPathsConverterSpec extends Specification { - @Unroll def 'should convert a json with list as root to a map of path to value'() { when: JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) diff --git a/build.gradle b/build.gradle index 1035550b83..27162e754c 100644 --- a/build.gradle +++ b/build.gradle @@ -63,6 +63,7 @@ subprojects { testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } + testCompile 'info.solidsoft.spock:spock-global-unroll:0.5.0' } test { From 2525c65167f46d9ddbb923168eaee9598cb1fd3c Mon Sep 17 00:00:00 2001 From: Denis Stepanov Date: Thu, 21 Apr 2016 13:42:55 +0200 Subject: [PATCH 516/719] Gradle tests cleanup (#242) --- .../plugin/AccurestIntegrationSpec.groovy | 20 +++--- .../messagingProject/build.gradle | 8 +-- build.gradle | 66 +++++++++++-------- 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy index 19abff5588..e673f79976 100644 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy @@ -35,21 +35,19 @@ abstract class AccurestIntegrationSpec extends Specification { protected void setupForProject(String projectRoot) { copyResourcesToRoot(projectRoot) - def pluginClasspathResource = getClass().classLoader.findResource("plugin-classpath.txt") - if (pluginClasspathResource == null) { - throw new IllegalStateException("Did not find 'plugin-classpath.txt'") - } - String pluginClasspath = pluginClasspathResource.readLines() - .collect { it.replace('\\', '\\\\') } // escape backslashes in Windows paths - .collect { "'$it'" } - .join(", ") - buildFile << """ + String accurestGradlePluginLibsDir = System.getProperty("accurest-gradle-plugin-libs-dir").replace('\\', '\\\\') + String messagingLibDir = System.getProperty("messaging-libs-dir").replace('\\', '\\\\') + + buildFile.write """ + ext.messagingLibsDir = '$messagingLibDir' + buildscript { dependencies { - classpath files($pluginClasspath) + classpath fileTree(dir: '$accurestGradlePluginLibsDir', include: '*.jar') } } - """ + + """ + buildFile.text // Extending buildscript is required when 'apply' is used. // 'GradleRunner#withPluginClasspath' can be used when plugin is added using 'plugins { id...' } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle index cb15b57e01..a4a2ae6524 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle @@ -3,10 +3,6 @@ buildscript { mavenLocal() mavenCentral() } - dependencies { - // will be passed via classpath - // classpath "io.codearte.accurest:accurest-gradle-plugin:+" - } } apply plugin: 'groovy' @@ -53,8 +49,8 @@ dependencies { 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:+' + + compile fileTree(dir: messagingLibsDir, include: '*.jar') testCompile "org.spockframework:spock-spring:1.0-groovy-2.4" testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' diff --git a/build.gradle b/build.gradle index 27162e754c..0b99857e57 100644 --- a/build.gradle +++ b/build.gradle @@ -126,6 +126,15 @@ project(':accurest-converters') { } project(':accurest-gradle-plugin') { + + ext.messagingLibsDir ="$buildDir/messaging-libs" + ext.accurestGradlePluginLibsDir ="$buildDir/accurest-gradle-plugin-libs" + + ext.testSystemProperties = [ + 'accurest-gradle-plugin-libs-dir': accurestGradlePluginLibsDir, + 'messaging-libs-dir': messagingLibsDir + ] + dependencies { compile project(':accurest-core') compile project(':accurest-converters') @@ -135,51 +144,52 @@ project(':accurest-gradle-plugin') { testCompile project(':accurest-testing-utils') } + configurations { + messagingLibs + accurestGradlePluginLibs + } + + dependencies { + messagingLibs project(':accurest-messaging-root:accurest-messaging-integration') + messagingLibs project(':accurest-messaging-root:accurest-messaging-core') + messagingLibs project(':accurest-testing-utils') + messagingLibs 'org.codehaus.groovy:groovy-all:2.4.5' + + accurestGradlePluginLibs project(':accurest-gradle-plugin') + } + test { exclude '**/*FunctionalSpec.*' + systemProperties = testSystemProperties } task funcTest(type: Test) { include '**/*FunctionalSpec.*' - + systemProperties = testSystemProperties reports.html { destination = file("${reporting.baseDir}/funcTests") } } - task createClasspathManifest { - def outputDir = file("$buildDir/$name") - - inputs.files sourceSets.main.runtimeClasspath - outputs.dir outputDir - - doLast { - outputDir.mkdirs() - file("$outputDir/plugin-classpath.txt").text = sourceSets.test.runtimeClasspath.join("\n") - // Switch to 'sourceSets.main' after 'test.dependsOn's are removed - } + task archiveMessagingLibsDependencies(type: Sync) { + from configurations.messagingLibs.resolvedConfiguration.resolvedArtifacts.collect { it.file } + into messagingLibsDir } - test.dependsOn(':accurest-core:install') - test.dependsOn(':accurest-messaging-root:accurest-messaging-core:install') - test.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install') - - funcTest.dependsOn(':accurest-core:install') - funcTest.dependsOn(':accurest-messaging-root:accurest-messaging-core:install') - funcTest.dependsOn(':accurest-messaging-root:accurest-messaging-integration:install') - - // Add the classpath file to the test runtime classpath - dependencies { - testRuntime files(createClasspathManifest) + task archiveAccurestGradlePluginLibsDependencies(type: Sync) { + from configurations.accurestGradlePluginLibs.resolvedConfiguration.resolvedArtifacts.collect { it.file } + into accurestGradlePluginLibsDir } + // archive task needs to have jars ready + archiveMessagingLibsDependencies.dependsOn project(':accurest-messaging-root:accurest-messaging-integration').tasks.jar + archiveAccurestGradlePluginLibsDependencies.dependsOn project(':accurest-gradle-plugin').tasks.jar + + test.dependsOn archiveMessagingLibsDependencies, archiveAccurestGradlePluginLibsDependencies + funcTest.dependsOn archiveMessagingLibsDependencies, archiveAccurestGradlePluginLibsDependencies + uploadArchives.dependsOn { funcTest } } -task wrapper(type: Wrapper) { - gradleVersion = '2.12' -} - - // REMOVE AFTER https://issues.gradle.org/browse/GRADLE-3433 IS FIXED buildscript { repositories { From 3e1bccf128f255ff2a801e93d0e4af093015b6f7 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 21 Apr 2016 13:44:03 +0200 Subject: [PATCH 517/719] Added checks for presence of groovy contracts in the produced jars --- .../plugin/AccurestIntegrationSpec.groovy | 23 ++++++++++++++++++- .../plugin/MessagingProjectSpec.groovy | 2 ++ .../plugin/SampleJerseyProjectSpec.groovy | 2 ++ .../accurest/plugin/SampleProjectSpec.groovy | 2 ++ .../plugin/ScenarioProjectSpec.groovy | 2 ++ 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy index e673f79976..779d156be3 100644 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy @@ -9,9 +9,10 @@ import spock.lang.Specification import java.nio.file.Files import java.nio.file.Path +import java.util.zip.ZipException +import java.util.zip.ZipFile import static java.nio.charset.StandardCharsets.UTF_8 - /** * @author Olga Maciaszek-Sharma * @author Denis Stepanov @@ -116,4 +117,24 @@ abstract class AccurestIntegrationSpec extends Specification { return new File('build.gradle', testProjectDir) } + protected boolean jarContainsAccurestContracts(String path) { + assert fileExists(path) + File rootFile = file(path) + boolean containsGroovyFiles = false + rootFile.eachFileRecurse { File file -> + try { + if (file.isFile() && file.name.endsWith('jar')) { + new ZipFile(file).entries().each { + if (it.name.endsWith('.groovy')) { + containsGroovyFiles = true + } + } + } + }catch (ZipException zipEx) { + println "Unable to open file ${file.name}" + } + } + return containsGroovyFiles + } + } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy index 0a57265380..0bb8b9697b 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy @@ -15,6 +15,7 @@ class MessagingProjectSpec extends AccurestIntegrationSpec { assert fileExists('build.gradle') expect: runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsAccurestContracts('build/libs') } def "should pass basic flow for JUnit"() { @@ -24,6 +25,7 @@ class MessagingProjectSpec extends AccurestIntegrationSpec { expect: switchToJunitTestFramework('io.codearte.accurest.samples.book.MessagingBaseSpec', 'io.codearte.accurest.samples.book.MessagingBaseTest') runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsAccurestContracts('build/libs') } } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy index fe970626ab..6a44c37fa1 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy @@ -15,6 +15,7 @@ class SampleJerseyProjectSpec extends AccurestIntegrationSpec { assert fileExists('build.gradle') expect: runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsAccurestContracts('fraudDetectionService/build/libs') } def "should pass basic flow for JUnit"() { @@ -23,6 +24,7 @@ class SampleJerseyProjectSpec extends AccurestIntegrationSpec { assert fileExists('build.gradle') expect: runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsAccurestContracts('fraudDetectionService/build/libs') } } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy index f14c277106..140a9d898a 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy @@ -15,6 +15,7 @@ class SampleProjectSpec extends AccurestIntegrationSpec { assert fileExists('build.gradle') expect: runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsAccurestContracts('fraudDetectionService/build/libs') } def "should pass basic flow for JUnit"() { @@ -23,6 +24,7 @@ class SampleProjectSpec extends AccurestIntegrationSpec { assert fileExists('build.gradle') expect: runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsAccurestContracts('fraudDetectionService/build/libs') } } diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy index ce4db6e798..939b71db70 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy +++ b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy @@ -15,6 +15,7 @@ class ScenarioProjectSpec extends AccurestIntegrationSpec { assert fileExists('build.gradle') expect: runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsAccurestContracts('fraudDetectionService/build/libs') } def "should pass basic flow for JUnit"() { @@ -23,6 +24,7 @@ class ScenarioProjectSpec extends AccurestIntegrationSpec { expect: switchToJunitTestFramework() runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsAccurestContracts('fraudDetectionService/build/libs') } } From 577619cb2c1079d618ce32db6de4548510cca32b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 21 Apr 2016 13:44:41 +0200 Subject: [PATCH 518/719] Added a description field can be useful to provide some extensive descriptions of a scenario --- .../main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy index 97b023b34e..b3b5a1e4e2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy @@ -17,6 +17,7 @@ class GroovyDsl { Request request Response response String label + String description Input inputMessage OutputMessage outputMessage @@ -35,6 +36,10 @@ class GroovyDsl { this.label = label } + void description(String description) { + this.description = description + } + void request(@DelegatesTo(Request) Closure closure) { this.request = new Request() closure.delegate = request From 3689fdffd59f1f220cd88b33df0c57b3bfc4aaa3 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 21 Apr 2016 18:19:25 +0200 Subject: [PATCH 519/719] Reporting [ci skip] --- pom.xml | 82 +++++++++++++++++++++++++++++++++++- src/site/asciidoc/index.adoc | 10 +++++ src/site/site.xml | 35 +++++++++++++++ 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 src/site/asciidoc/index.adoc create mode 100644 src/site/site.xml diff --git a/pom.xml b/pom.xml index a8797b64ec..09e1f1a307 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ maven-plugin 0.5.9-SNAPSHOT - Accurate Maven Plugin Project + Accurest Maven Plugin Accurate REST Maven Plugin https://github.com/Codearte/accurest-maven-plugin @@ -29,6 +29,7 @@ 3.4 UTF-8 + UTF-8 1.0.6 1.1.0 @@ -64,8 +65,22 @@ Nexus Release Repository http://oss.sonatype.org/service/local/staging/deploy/maven2/ + + github + scm:git:ssh://git@github.com:Codearte/accurest-maven-plugin.git + + + GitHub Issues + https://github.com/Codearte/accurest/labels/maven + + + + Travis + https://travis-ci.org/Codearte/accurest-maven-plugin + + @@ -175,6 +190,39 @@ v@{project.version} + + org.apache.maven.plugins + maven-scm-publish-plugin + 1.1 + + ${project.scm.developerConnection} + gh-pages + ${project.reporting.outputDirectory} + + + + scm-publish + site-deploy + + publish-scm + + + + + + org.apache.maven.plugins + maven-site-plugin + + true + + + + org.asciidoctor + asciidoctor-maven-plugin + 1.5.3 + + + @@ -326,6 +374,38 @@ + + + + maven-plugin-plugin + ${mavenPluginPluginVersion} + + + org.apache.maven.plugins + maven-jxr-plugin + + + org.apache.maven.plugins + maven-project-info-reports-plugin + + false + false + + + + org.apache.maven.plugins + maven-javadoc-plugin + + true + + + + org.apache.maven.plugins + maven-surefire-report-plugin + + + + release diff --git a/src/site/asciidoc/index.adoc b/src/site/asciidoc/index.adoc new file mode 100644 index 0000000000..4f25a82574 --- /dev/null +++ b/src/site/asciidoc/index.adoc @@ -0,0 +1,10 @@ += Accurest Maven Plugin + +Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. + + * Stubs mappings to be used by WireMock when doing integration testing on the client code (client tests). + + * Acceptance tests used to verify if server-side implementation of the API is compliant with the contract (server tests). + +Accurest moves TDD to the level of software architecture. + diff --git a/src/site/site.xml b/src/site/site.xml new file mode 100644 index 0000000000..a26f77c089 --- /dev/null +++ b/src/site/site.xml @@ -0,0 +1,35 @@ + + + ${project.name} + + + + + + org.apache.maven.skins + maven-fluido-skin + 1.4 + + + + true + true + + + + + codearte/accurest-maven-plugin + right + orange + + » + + + + + + + + + + \ No newline at end of file From f660250bcff5c5d7b2a551000e7c1718818139cb Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 21 Apr 2016 18:58:19 +0200 Subject: [PATCH 520/719] fix docs [ci skip] --- pom.xml | 5 +++++ src/site/asciidoc/usage.adoc | 24 ++++++++++++++++++++++++ src/site/site.xml | 10 ++++++---- 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 src/site/asciidoc/usage.adoc diff --git a/pom.xml b/pom.xml index 09e1f1a307..e2c246c1e6 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,11 @@ [3.2.1,) + + Codearte + http://codearte.io/ + + mariuszs diff --git a/src/site/asciidoc/usage.adoc b/src/site/asciidoc/usage.adoc new file mode 100644 index 0000000000..9cdbcc2140 --- /dev/null +++ b/src/site/asciidoc/usage.adoc @@ -0,0 +1,24 @@ +== Usage + +Sample minimal configuration for project with Java source code. + +---- + + io.codearte.accurest + accurest-maven-plugin + 0.5.8 + + + + convert + generateStubs + generateTests + + + + + foobar.AccurestBaseTest + + +---- + diff --git a/src/site/site.xml b/src/site/site.xml index a26f77c089..99c060eba2 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -8,15 +8,12 @@ org.apache.maven.skins maven-fluido-skin - 1.4 + 1.5 true true - - - codearte/accurest-maven-plugin right @@ -29,6 +26,11 @@ + + + + + From f6cfd90d3d251e9aa52235790cd0d2f338bc76e2 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 22 Apr 2016 23:01:48 +0200 Subject: [PATCH 521/719] Added support for Camel messaging --- .../accurest/SingleTestGenerator.groovy | 2 +- .../accurest/builder/BodyAsString.groovy | 52 +++++++++ .../builder/MessagingMethodBodyBuilder.groovy | 2 +- .../accurest/builder/MethodBuilder.groovy | 2 +- .../io/codearte/accurest/dsl/GroovyDsl.groovy | 6 +- .../accurest/dsl/internal/Headers.groovy | 8 ++ .../accurest/messaging/AccurestFilter.java | 14 +++ settings.gradle | 17 ++- .../stubrunner/junit/AccurestRule.java | 22 ++++ .../stub-runner-messaging-camel/build.gradle | 25 ++++ .../camel/StubRunnerCamelConfiguration.groovy | 35 ++++++ .../camel/StubRunnerCamelPredicate.groovy | 58 ++++++++++ .../camel/StubRunnerCamelProcessor.groovy | 36 ++++++ .../main/resources/META-INF/spring.factories | 3 + .../messaging/camel/BookReturned.groovy | 16 +++ .../camel/CamelStubRunnerSpec.groovy | 108 ++++++++++++++++++ .../src/test/resources/application.yml | 2 + .../camelService-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1754 bytes .../camelService-0.0.1-SNAPSHOT.pom | 9 ++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++ .../camelService/maven-metadata-local.xml | 12 ++ .../spring/StubRunnerConfiguration.java | 8 +- .../main/resources/META-INF/spring.factories | 3 + stub-runner/stub-runner/build.gradle | 1 + .../stubrunner/BatchStubRunner.groovy | 25 +++- .../stubrunner/BatchStubRunnerFactory.groovy | 16 ++- .../stubrunner/GroovyDslWrapper.groovy | 2 +- .../stubrunner/StubConfiguration.groovy | 20 +++- .../accurest/stubrunner/StubData.groovy | 4 +- .../accurest/stubrunner/StubFinder.groovy | 9 +- .../accurest/stubrunner/StubRepository.groovy | 24 ++-- .../accurest/stubrunner/StubRunner.groovy | 49 ++++++-- .../stubrunner/StubRunnerExecutor.groovy | 56 ++++++++- .../stubrunner/StubRunnerFactory.groovy | 9 +- .../StubRunnerMessagingTrigger.groovy | 18 +++ .../accurest/stubrunner/StubServer.groovy | 5 +- .../accurest/stubrunner/StubTriggerer.groovy | 25 ++++ .../stubrunner/StubRunnerFactorySpec.groovy | 3 +- 38 files changed, 671 insertions(+), 47 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/builder/BodyAsString.groovy create mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestFilter.java create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/resources/META-INF/spring.factories create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/BookReturned.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/application.yml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-spring/src/main/resources/META-INF/spring.factories create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMessagingTrigger.groovy create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index f2ff1a7617..8cb84a57dc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -58,7 +58,7 @@ class SingleTestGenerator { 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 + TestType testType = (stubContent.input || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP return [(new ParsedDsl(it, stubContent, stubsFile)) : testType] } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BodyAsString.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/BodyAsString.groovy new file mode 100644 index 0000000000..7b03c5d126 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/BodyAsString.groovy @@ -0,0 +1,52 @@ +package io.codearte.accurest.builder + +import groovy.json.JsonOutput +import groovy.json.StringEscapeUtils +import io.codearte.accurest.dsl.internal.DslProperty +import io.codearte.accurest.util.MapConverter + +import static io.codearte.accurest.util.ContentUtils.extractValue + +/** + * Class that constructs a String from Body + * + * @author Marcin Grzejszczak + */ +class BodyAsString { + + static String extractServerValueFrom(Object body) { + Object bodyValue = extractServerValueFromBody(body) + String json = new JsonOutput().toJson(bodyValue) + json = StringEscapeUtils.unescapeJavaScript(json) + return trimRepeatedQuotes(json) + } + + static String extractClientValueFrom(Object body) { + Object bodyValue = extractClientValueFromBody(body); + String json = new JsonOutput().toJson(bodyValue) + json = StringEscapeUtils.unescapeJavaScript(json) + return trimRepeatedQuotes(json) + } + + private static String trimRepeatedQuotes(String toTrim) { + return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim + } + + private static Object extractServerValueFromBody(bodyValue) { + if (bodyValue instanceof GString) { + bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) + } else { + bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.serverValue : it }) + } + return bodyValue + } + + private static Object extractClientValueFromBody(bodyValue) { + if (bodyValue instanceof GString) { + bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.clientValue }) + } else { + bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.clientValue : it }) + } + return bodyValue + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy index e5a523e894..51d899e48b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy @@ -22,7 +22,7 @@ abstract class MessagingMethodBodyBuilder extends MethodBodyBuilder { protected final OutputMessage outputMessage MessagingMethodBodyBuilder(GroovyDsl stubDefinition) { - this.inputMessage = stubDefinition.inputMessage + this.inputMessage = stubDefinition.input this.outputMessage = stubDefinition.outputMessage } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy index b53e72db3e..71c76b7f86 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy @@ -44,7 +44,7 @@ class MethodBuilder { } private MethodBodyBuilder getMethodBodyBuilder() { - if (stubContent.inputMessage || stubContent.outputMessage) { + if (stubContent.input || stubContent.outputMessage) { if (configProperties.targetFramework == TestFramework.JUNIT){ return new JUnitMessagingMethodBodyBuilder(stubContent) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy index b3b5a1e4e2..3cd0e993ed 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy @@ -18,7 +18,7 @@ class GroovyDsl { Response response String label String description - Input inputMessage + Input input OutputMessage outputMessage static GroovyDsl make(Closure closure) { @@ -53,8 +53,8 @@ class GroovyDsl { } void input(@DelegatesTo(Input) Closure closure) { - this.inputMessage = new Input() - closure.delegate = inputMessage + this.input = new Input() + closure.delegate = input closure() } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy index 27dd9bf192..98e7bed9bc 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy @@ -26,6 +26,14 @@ class Headers { } } + Map asStubSideMap() { + def acc = [:].withDefault { [] as Collection } + return entries.inject(acc as Map) { Map map, Header header -> + map[header.name] = header.clientValue + return map + } as Map + } + boolean equals(o) { if (this.is(o)) return true if (getClass() != o.class) return false diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestFilter.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestFilter.java new file mode 100644 index 0000000000..f41e544df0 --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestFilter.java @@ -0,0 +1,14 @@ +package io.codearte.accurest.messaging; + +/** + * Contract for filtering out messages that do not match the structure in the Accurest DSL + * + * @author Marcin Grzejszczak + */ +public interface AccurestFilter { + + /** + * @return @{code true} if the message should be passed through, @{code false} if the message should be filtered out, + */ + boolean matches(AccurestMessage message); +} diff --git a/settings.gradle b/settings.gradle index 54053949b1..da50942a1e 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,14 +1,20 @@ include 'docs' include "accurest-core", "accurest-gradle-plugin", 'accurest-converters', 'accurest-testing-utils' -include ':stub-runner:stub-runner' -include ':stub-runner:stub-runner-spring' -include ':stub-runner:stub-runner-spring-cloud' -include ':stub-runner:stub-runner-junit' + include ':accurest-messaging:accurest-messaging-core' include ':accurest-messaging:accurest-messaging-integration' include ':accurest-messaging:accurest-messaging-stream' include ':accurest-messaging:accurest-messaging-camel' +include ':stub-runner:stub-runner' +include ':stub-runner:stub-runner-spring' +include ':stub-runner:stub-runner-spring-cloud' +include ':stub-runner:stub-runner-junit' + +include ':stub-runner:stub-runner-messaging:stub-runner-messaging-integration' +include ':stub-runner:stub-runner-messaging:stub-runner-messaging-stream' +include ':stub-runner:stub-runner-messaging:stub-runner-messaging-camel' + include ':samples:messaging-stream' include ':samples:messaging-integration' include ':samples:messaging-camel' @@ -18,4 +24,5 @@ rootProject.name = "accurest" //to prevent StackOverflow in Sonar project(":stub-runner").name = "stub-runner-root" -project(":accurest-messaging").name = "accurest-messaging-root" \ No newline at end of file +project(":accurest-messaging").name = "accurest-messaging-root" +project(":stub-runner:stub-runner-messaging").name = "stub-runner-messaging-root" diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index a47e4e9e8d..c4ecac01bf 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -6,12 +6,14 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.junit.rules.TestRule; import org.junit.runner.Description; import org.junit.runners.model.Statement; +import io.codearte.accurest.dsl.GroovyDsl; import io.codearte.accurest.stubrunner.BatchStubRunner; import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; import io.codearte.accurest.stubrunner.RunningStubs; @@ -161,4 +163,24 @@ public class AccurestRule implements TestRule, StubFinder { public RunningStubs findAllRunningStubs() { return stubFinder.findAllRunningStubs(); } + + @Override + public Map> getAccurestContracts() { + return stubFinder.getAccurestContracts(); + } + + @Override + public void trigger(String ivyNotation, String labelName) { + throw new UnsupportedOperationException("Feature not yet supported"); + } + + @Override + public void trigger(String labelName) { + throw new UnsupportedOperationException("Feature not yet supported"); + } + + @Override + public void trigger() { + throw new UnsupportedOperationException("Feature not yet supported"); + } } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle new file mode 100644 index 0000000000..31a1bf7460 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle @@ -0,0 +1,25 @@ +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +dependencies { + compile project(':stub-runner-root:stub-runner-spring') + compile project(':accurest-messaging-root:accurest-messaging-camel') + compile 'org.apache.camel:camel-spring-boot-starter:2.17.0' + compile 'org.apache.camel:camel-jackson:2.17.0' + + testCompile 'org.apache.camel:camel-jms:2.17.0' + testCompile 'org.apache.activemq:activemq-camel:5.12.1' + testCompile 'org.apache.activemq:activemq-pool:5.12.1' + 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') + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy new file mode 100644 index 0000000000..8941d4984e --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy @@ -0,0 +1,35 @@ +package io.codearte.accurest.stubrunner.messaging.camel + +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.stubrunner.BatchStubRunner +import io.codearte.accurest.stubrunner.StubConfiguration +import org.apache.camel.RoutesBuilder +import org.apache.camel.spring.SpringRouteBuilder +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +/** + * Camel configuration that iterates over the downloaded Groovy DSLs + * and registers a route for each DSL. + * + * @author Marcin Grzejszczak + */ +@Configuration +class StubRunnerCamelConfiguration { + + @Bean + RoutesBuilder myRouter(BatchStubRunner batchStubRunner) { + return new SpringRouteBuilder() { + @Override + public void configure() throws Exception { + Map> accurestContracts = batchStubRunner.accurestContracts + (accurestContracts.values().flatten() as Collection).findAll { it?.input?.messageFrom && it?.outputMessage?.sentTo }.each { + from(it.input.messageFrom) + .filter(new StubRunnerCamelPredicate(it)) + .process(new StubRunnerCamelProcessor(it)) + .to(it.outputMessage.sentTo) + } + } + }; + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy new file mode 100644 index 0000000000..5c5834807f --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy @@ -0,0 +1,58 @@ +package io.codearte.accurest.stubrunner.messaging.camel + +import com.fasterxml.jackson.databind.ObjectMapper +import com.jayway.jsonpath.DocumentContext +import com.jayway.jsonpath.JsonPath +import com.toomuchcoding.jsonassert.JsonAssertion +import com.toomuchcoding.jsonassert.JsonVerifiable +import groovy.transform.PackageScope +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.util.JsonPaths +import io.codearte.accurest.util.JsonToJsonPathsConverter +import org.apache.camel.Exchange +import org.apache.camel.Predicate + +/** + * Passes through a message that matches the one defined in the DSL + * + * @author Marcin Grzejszczak + */ +@PackageScope +class StubRunnerCamelPredicate implements Predicate { + + private final GroovyDsl groovyDsl + private final ObjectMapper objectMapper = new ObjectMapper() + + StubRunnerCamelPredicate(GroovyDsl groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + boolean matches(Exchange exchange) { + if(!headersMatch(exchange)){ + return false + } + Object inputMessage = exchange.in.body + JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValues(groovyDsl.input.messageBody) + DocumentContext parsedJson = JsonPath.parse(objectMapper.writeValueAsString(inputMessage)) + return jsonPaths.every { matchesJsonPath(parsedJson, it) } + } + + private boolean matchesJsonPath(DocumentContext parsedJson, JsonVerifiable jsonVerifiable) { + try { + JsonAssertion.assertThat(parsedJson).matchesJsonPath(jsonVerifiable.jsonPath()) + return true + } catch (Exception e) { + return false + } + } + + private boolean headersMatch(Exchange exchange) { + Map headers = exchange.getIn().getHeaders() + return groovyDsl.input.messageHeaders.entries.every { + String name = it.name + Object value = it.clientValue + return headers.get(name) == value + } + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy new file mode 100644 index 0000000000..87b2f8590e --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy @@ -0,0 +1,36 @@ +package io.codearte.accurest.stubrunner.messaging.camel + +import groovy.transform.PackageScope +import io.codearte.accurest.builder.BodyAsString +import io.codearte.accurest.dsl.GroovyDsl +import org.apache.camel.Exchange +import org.apache.camel.Message +import org.apache.camel.Processor + +/** + * Sends forward a message defined in the DSL. Also removes headers from the + * input message and provides the headers from the DSL. + * + * @author Marcin Grzejszczak + */ +@PackageScope +class StubRunnerCamelProcessor implements Processor { + + private final GroovyDsl groovyDsl + + StubRunnerCamelProcessor(GroovyDsl groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + void process(Exchange exchange) throws Exception { + Message input = exchange.in + input.body = BodyAsString.extractClientValueFrom(groovyDsl.outputMessage.body) + groovyDsl.input.messageHeaders.entries.each { + input.removeHeader(it.name) + } + groovyDsl.outputMessage.headers.entries.each { + input.setHeader(it.name, it.clientValue) + } + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..bb95d2a818 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.stubrunner.messaging.camel.StubRunnerCamelConfiguration diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/BookReturned.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/BookReturned.groovy new file mode 100644 index 0000000000..b6523d2e5c --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/BookReturned.groovy @@ -0,0 +1,16 @@ +package io.codearte.accurest.stubrunner.messaging.camel + +import com.fasterxml.jackson.annotation.JsonCreator +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode + +@CompileStatic +@EqualsAndHashCode +class BookReturned implements Serializable { + final String bookName + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + BookReturned(String bookName) { + this.bookName = bookName + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy new file mode 100644 index 0000000000..63102256f1 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -0,0 +1,108 @@ +package io.codearte.accurest.stubrunner.messaging.camel + +import com.fasterxml.jackson.databind.ObjectMapper +import io.codearte.accurest.stubrunner.StubFinder +import org.apache.activemq.camel.component.ActiveMQComponent +import org.apache.camel.CamelContext +import org.apache.camel.Exchange +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification +/** + * @author Marcin Grzejszczak + */ +@Configuration +@ComponentScan +@EnableAutoConfiguration +@ContextConfiguration(classes = CamelStubRunnerSpec, loader = SpringApplicationContextLoader) +class CamelStubRunnerSpec extends Specification { + + @Autowired StubFinder stubFinder + @Autowired CamelContext camelContext + + def 'should download the stub and register a route for it'() { + when: + camelContext.createProducerTemplate().sendBodyAndHeaders('jms:input', new BookReturned('foo'), [sample: 'header']) + then: + Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) + and: + receivedMessage != null + receivedMessage.in.body == '{"bookName":"foo"}' + receivedMessage.in.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a message by label'() { + when: + stubFinder.trigger('return_book_1') + then: + Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) + and: + receivedMessage != null + receivedMessage.in.body == '{ "bookName" : "foo" }' + receivedMessage.in.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a label for the existing groupId:artifactId'() { + when: + stubFinder.trigger('io.codearte.accurest.stubs:camelService', 'return_book_1') + then: + Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) + and: + receivedMessage != null + receivedMessage.in.body == '{ "bookName" : "foo" }' + receivedMessage.in.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a label for the existing artifactId'() { + when: + stubFinder.trigger('camelService', 'return_book_1') + then: + Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) + and: + receivedMessage != null + receivedMessage.in.body == '{ "bookName" : "foo" }' + receivedMessage.in.headers.get('BOOK-NAME') == 'foo' + } + + def 'should not run any wrong trigger when missing label is passed'() { + when: + stubFinder.trigger('missing label') + then: + Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 100) + and: + receivedMessage == null + } + + def 'should not run any wrong trigger when missing label and artifactid is passed'() { + when: + stubFinder.trigger('some:service', 'return_book_1') + then: + Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 100) + and: + receivedMessage == null + } + + def 'should trigger messages by running all triggers'() { + given: + ObjectMapper objectMapper = new ObjectMapper() + when: + stubFinder.trigger() + then: + Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) + and: + receivedMessage != null + objectMapper.writeValueAsString(receivedMessage.in.body) == '{"bookName":"foo"}' + receivedMessage.in.headers.get('BOOK-NAME') == 'foo' + } + + @Bean + ActiveMQComponent activeMQComponent(@Value('${activemq.url:vm://localhost?broker.persistent=false}') String url) { + return new ActiveMQComponent(brokerURL: url) + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/application.yml b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/application.yml new file mode 100644 index 0000000000..6fadb526ec --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo/repository/ +stubrunner.stubs.ids: io.codearte.accurest.stubs:camelService \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..17df8f09aba8807877246768aa758e8d3b85ff94 GIT binary patch literal 1754 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJwREYr;41Xc~mea@@)mG{R+ey3^G{tB<1I4 z2c?#j7UiX;80w`L<>!}GhK6u5Fh?Ab3_lPm8D3h!&A`a=f|-Ef1c;&(5BzWANxS;> zx?b4Me`C_Y_w&)lxR4vg0U2th(?kQqax-B)Oz3*OEoWQH4(JgDNmcF#w)bDWU|GjryR~0#)85rN+d~Cx3 zp&0=Jn-*PQTEgXhv#q-EhlE+$<28)`UrwC%^un)@hD(c17adWH4(h)WyMF3XPIk?k zyk$(44)0^!_!e#E-*T*oc~Bd>&yDSmn>dhy4E)8Zc)*03nf)m?cC)53mji?6IS{MiNi{C1IjJS7Dae823k;kcn1SQldzR~v0nhRCcZ1(d<6FYNVKL9w zC!QY^lx|AhjmdVq%<25?-MhyN+8zGM|6H0Fyit{BB2QSTyvL%AkIvW`>~BxHWwUKc zozT+_D$|=(-6!U$7ISxI#l^}$52+M7$o`h8n%7_dXH?6Z>A5%gei>yhefC+o>QwL! zV}FIxzuIyfx~!2qR>ifjIo`Ky^5t5+dBX9`fEFj4s}iPX?ihP*{Ikt!ws*2o9U~&6 zYoV10Xc;ayv7jI`FTEI?;TV}jm~odQz%T>?0fx7ZAR1n(1bCxrLoZc8ia}sWqb87q zYeOny&`kiTh819-q67j282&nz0hvgp1wM@+e?kCA<3b=4Nh7?N0hu7jjH{TD02=_z zS_}=1S8-0|Nlz(iyk_ literal 0 HcmV?d00001 diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..4e8bab7de0 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom @@ -0,0 +1,9 @@ + + + 4.0.0 + io.codearte.accurest.stubs + camelService + 0.0.1-SNAPSHOT + pom + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..f8f49e32bb --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + camelService + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata-local.xml new file mode 100644 index 0000000000..e71db595a7 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + camelService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java index 0e803b4284..a375442b2c 100644 --- a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java +++ b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java @@ -3,11 +3,14 @@ package io.codearte.accurest.stubrunner.spring; import java.io.IOException; import java.util.Set; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; +import io.codearte.accurest.messaging.AccurestMessaging; +import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging; import io.codearte.accurest.stubrunner.BatchStubRunner; import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; import io.codearte.accurest.stubrunner.StubConfiguration; @@ -22,6 +25,8 @@ import io.codearte.accurest.stubrunner.util.StubsParser; @Configuration public class StubRunnerConfiguration { + @Autowired(required = false) AccurestMessaging accurestMessaging; + /** * Bean that initializes stub runners, runs them and on shutdown closes them. Upon its instantiation * JAR with stubs is downloaded and unpacked to a temporary folder and WireMock server are started @@ -45,7 +50,8 @@ public class StubRunnerConfiguration { StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue, maxPortValue, uriStringOrEmpty(stubRepositoryRoot), stubRepositoryRoot == null || workOffline, stubsSuffix); Set dependencies = StubsParser.fromString(stubs, stubsSuffix); - BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, dependencies).buildBatchStubRunner(); + BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, dependencies, + accurestMessaging != null ? accurestMessaging : new NoOpAccurestMessaging()).buildBatchStubRunner(); // TODO: Consider running it in a separate thread batchStubRunner.runStubs(); return batchStubRunner; diff --git a/stub-runner/stub-runner-spring/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-spring/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..24ddd934bf --- /dev/null +++ b/stub-runner/stub-runner-spring/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration \ No newline at end of file diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index d8a1265ef6..c6e992b79a 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -5,6 +5,7 @@ mainClassName = 'io.codearte.accurest.stubrunner.StubRunnerMain' dependencies { compile project(':accurest-core') + compile project(':accurest-messaging-root:accurest-messaging-core') compile 'org.apache.ivy:ivy:2.4.0' compile localGroovy() compile "com.github.tomakehurst:wiremock:$wiremockVersion" diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy index a29a799eaf..7aff5d3a3d 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy @@ -1,7 +1,7 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic - +import io.codearte.accurest.dsl.GroovyDsl /** * Manages lifecycle of multiple {@link StubRunner} instances. * @@ -48,6 +48,29 @@ class BatchStubRunner implements StubRunning { return new RunningStubs(stubRunners.collect { StubRunner runner -> runner.findAllRunningStubs() }) } + @Override + Map> getAccurestContracts() { + return stubRunners.inject([:]) { Map> map, StubRunner stubRunner -> + map.putAll(stubRunner.accurestContracts) + return map + } as Map> + } + + @Override + void trigger(String ivyNotation, String labelName) { + stubRunners.each { it.trigger(ivyNotation, labelName) } + } + + @Override + void trigger(String labelName) { + stubRunners.each { it.trigger(labelName) } + } + + @Override + void trigger() { + stubRunners.each { it.trigger() } + } + @Override void close() throws IOException { stubRunners.each { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy index 99b01dcfc0..b57b1c37ad 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy @@ -1,6 +1,8 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic +import io.codearte.accurest.messaging.AccurestMessaging +import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging /** * Manages lifecycle of multiple {@link StubRunner} instances. @@ -14,21 +16,29 @@ class BatchStubRunnerFactory { private final StubRunnerOptions stubRunnerOptions private final Collection dependencies private final StubDownloader stubDownloader + private final AccurestMessaging accurestMessaging BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies) { - this(stubRunnerOptions, dependencies, new GrapeStubDownloader()) + this(stubRunnerOptions, dependencies, new GrapeStubDownloader(), new NoOpAccurestMessaging()) + } + + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies, + AccurestMessaging accurestMessaging) { + this(stubRunnerOptions, dependencies, new GrapeStubDownloader(), accurestMessaging) } BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies, - StubDownloader stubDownloader) { + StubDownloader stubDownloader, + AccurestMessaging accurestMessaging) { this.stubRunnerOptions = stubRunnerOptions this.dependencies = dependencies this.stubDownloader = stubDownloader + this.accurestMessaging = accurestMessaging } BatchStubRunner buildBatchStubRunner() { - StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, dependencies, stubDownloader) + StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, dependencies, stubDownloader, accurestMessaging) return new BatchStubRunner(stubRunnerFactory.createStubsFromServiceConfiguration()) } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy index af9af5b155..dbd73859b9 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy @@ -11,7 +11,7 @@ import io.codearte.accurest.dsl.GroovyDsl @CompileStatic class GroovyDslWrapper { - @Delegate private final GroovyDsl groovyDsl + @Delegate final GroovyDsl groovyDsl GroovyDslWrapper(GroovyDsl groovyDsl) { this.groovyDsl = groovyDsl diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy index 1ab0c82e0c..a4eea495dd 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.stubrunner +import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import io.codearte.accurest.stubrunner.util.StringUtils @@ -51,11 +52,28 @@ public class StubConfiguration { return StringUtils.hasText(classifier) } - public String toColonSeparatedDependencyNotation() { + String toColonSeparatedDependencyNotation() { if(!isDefined()) { return "" } return [groupId, artifactId, classifier].join(STUB_COLON_DELIMITER) } + @CompileDynamic + boolean matches(String ivyNotationAsString) { + def (String groupId, String artifactId) = ivyNotationFrom(ivyNotationAsString) + if (!groupId) { + return this.artifactId == artifactId + } + return this.groupId == groupId && this.artifactId == artifactId + } + + private String[] ivyNotationFrom(String ivyNotation) { + String[] splitString = ivyNotation.split(":") + if (splitString.length == 1) { + // assuming that ivy notation represents artifactId only + return [null, splitString[0]] as String[] + } + return [splitString[0], splitString[1]] as String[] + } } \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy index 93741e2f57..dbbe08c4c6 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy @@ -2,6 +2,8 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode +import io.codearte.accurest.dsl.GroovyDsl + /** * @author Marcin Grzejszczak */ @@ -9,5 +11,5 @@ import groovy.transform.EqualsAndHashCode @EqualsAndHashCode class StubData { final Integer port - final List contracts + final List contracts } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy index f67825bcef..9c14c75735 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy @@ -1,6 +1,8 @@ package io.codearte.accurest.stubrunner -interface StubFinder { +import io.codearte.accurest.dsl.GroovyDsl + +interface StubFinder extends StubTriggerer { /** * For the given groupId and artifactId tries to find the matching * URL of the running stub. @@ -23,4 +25,9 @@ interface StubFinder { * Returns all running stubs */ RunningStubs findAllRunningStubs() + + /** + * Returns the list of Accurest contracts + */ + Map> getAccurestContracts() } \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy index f7f43f0f2a..49a06075be 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy @@ -15,16 +15,23 @@ import org.codehaus.groovy.control.CompilerConfiguration class StubRepository { private final File path + final List projectDescriptors + final Collection accurestContracts StubRepository(File repository) { if (!repository.isDirectory()) { - throw new FileNotFoundException('Missing descriptor repository') + throw new FileNotFoundException("Missing descriptor repository under path [$path]") } this.path = repository + this.projectDescriptors = projectDescriptors() + this.accurestContracts = accurestContracts() } - Collection getAccurestContracts() { - List contracts = [] + /** + * Returns a list of {@link GroovyDsl} + */ + private Collection accurestContracts() { + List contracts = [] contracts.addAll(accurestDescriptors()) return contracts } @@ -32,7 +39,7 @@ class StubRepository { /** * Returns the list of WireMock JSON files wrapped in {@link WiremockMappingDescriptor} */ - List getProjectDescriptors() { + private List projectDescriptors() { List mappingDescriptors = [] mappingDescriptors.addAll(contextDescriptors()) return mappingDescriptors @@ -52,18 +59,17 @@ class StubRepository { return mappingDescriptors } - private Collection accurestDescriptors() { + private Collection accurestDescriptors() { return path.exists() ? collectAccurestDescriptors(path) : [] } - private Collection collectAccurestDescriptors(File descriptorsDirectory) { - List mappingDescriptors = [] + private Collection collectAccurestDescriptors(File descriptorsDirectory) { + List mappingDescriptors = [] descriptorsDirectory.eachFileRecurse { File file -> if (isAccurestDescriptor(file)) { try { - mappingDescriptors << new GroovyDslWrapper( + mappingDescriptors << ((new GroovyShell(delegate.class.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate(file)) as GroovyDsl) - ) } catch (Exception e) { log.warn("Exception occurred while trying to parse file [$file]", e) } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy index 496e1d49a3..839b12c401 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -2,6 +2,10 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.messaging.AccurestMessaging +import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging + /** * Represents a single instance of ready-to-run stubs. * Can run the stubs and then will return the name of the collaborator together with @@ -16,28 +20,34 @@ class StubRunner implements StubRunning { private final StubRepository stubRepository private final StubConfiguration stubsConfiguration private final StubRunnerOptions stubRunnerOptions - private StubRunnerExecutor localStubRunner + private final StubRunnerExecutor localStubRunner + private final AccurestMessaging accurestMessaging @Deprecated StubRunner(Arguments arguments) { - stubsConfiguration = arguments.stub - stubRunnerOptions = arguments.stubRunnerOptions + this.stubsConfiguration = arguments.stub + this.stubRunnerOptions = arguments.stubRunnerOptions this.stubRepository = new StubRepository(new File(arguments.repositoryPath)) + AvailablePortScanner portScanner = new AvailablePortScanner(stubRunnerOptions.minPortValue, + stubRunnerOptions.maxPortValue) + this.accurestMessaging = new NoOpAccurestMessaging() + this.localStubRunner = new StubRunnerExecutor(portScanner, accurestMessaging) } - StubRunner(StubRunnerOptions stubRunnerOptions, String repositoryPath, StubConfiguration stubsConfiguration) { + StubRunner(StubRunnerOptions stubRunnerOptions, String repositoryPath, StubConfiguration stubsConfiguration, + AccurestMessaging accurestMessaging) { this.stubsConfiguration = stubsConfiguration this.stubRunnerOptions = stubRunnerOptions this.stubRepository = new StubRepository(new File(repositoryPath)) + AvailablePortScanner portScanner = new AvailablePortScanner(stubRunnerOptions.minPortValue, + stubRunnerOptions.maxPortValue) + this.accurestMessaging = accurestMessaging + this.localStubRunner = new StubRunnerExecutor(portScanner, accurestMessaging) } @Override RunningStubs runStubs() { - AvailablePortScanner portScanner = new AvailablePortScanner(stubRunnerOptions.minPortValue, - stubRunnerOptions.maxPortValue) - localStubRunner = new StubRunnerExecutor(portScanner) registerShutdownHook() - return localStubRunner.runStubs(stubRepository, stubsConfiguration) } @@ -50,7 +60,8 @@ class StubRunner implements StubRunning { URL findStubUrl(String ivyNotation) { String[] splitString = ivyNotation.split(":") if (splitString.length == 1) { - throw new IllegalArgumentException("$ivyNotation is invalid") + // assuming that ivy notation represents artifactId only + return findStubUrl(null, splitString[0]) } return findStubUrl(splitString[0], splitString[1]) } @@ -60,6 +71,26 @@ class StubRunner implements StubRunning { return localStubRunner.findAllRunningStubs() } + @Override + Map> getAccurestContracts() { + return localStubRunner.getAccurestContracts() + } + + @Override + void trigger(String ivyNotation, String labelName) { + localStubRunner.trigger(ivyNotation, labelName) + } + + @Override + void trigger(String labelName) { + localStubRunner.trigger(labelName) + } + + @Override + void trigger() { + localStubRunner.trigger() + } + private void registerShutdownHook() { Runnable stopAllServers = { this.close() } Runtime.runtime.addShutdownHook(new Thread(stopAllServers)) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index 67a1b40fee..98f18aab2f 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -2,6 +2,11 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.messaging.AccurestMessage +import io.codearte.accurest.messaging.AccurestMessaging +import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging + /** * Runs stubs for a particular {@link StubServer} */ @@ -10,10 +15,17 @@ import groovy.util.logging.Slf4j class StubRunnerExecutor implements StubFinder { private final AvailablePortScanner portScanner + private final AccurestMessaging accurestMessaging private StubServer stubServer + StubRunnerExecutor(AvailablePortScanner portScanner, AccurestMessaging accurestMessaging) { + this.portScanner = portScanner + this.accurestMessaging = accurestMessaging + } + StubRunnerExecutor(AvailablePortScanner portScanner) { this.portScanner = portScanner + this.accurestMessaging = new NoOpAccurestMessaging() } RunningStubs runStubs(StubRepository repository, StubConfiguration stubConfiguration) { @@ -30,7 +42,7 @@ class StubRunnerExecutor implements StubFinder { @Override URL findStubUrl(String groupId, String artifactId) { - if(!groupId) { + if (!groupId) { return returnStubUrlIfMatches(stubServer.stubConfiguration.artifactId == artifactId) } return returnStubUrlIfMatches(stubServer.stubConfiguration.artifactId == artifactId && @@ -51,13 +63,53 @@ class StubRunnerExecutor implements StubFinder { return new RunningStubs([(stubServer.stubConfiguration) : stubServer.port]) } + @Override + Map> getAccurestContracts() { + return [(stubServer.stubConfiguration): stubServer.contracts] + } + + @Override + void trigger(String ivyNotationAsString, String labelName) { + Collection matchingContracts = getAccurestContracts().findAll { + it.key.matches(ivyNotationAsString) + }.values().flatten() as Collection + triggerForDsls(matchingContracts, labelName) + } + + @Override + void trigger(String labelName) { + triggerForDsls(getAccurestContracts().values().flatten() as Collection, labelName) + } + + private void triggerForDsls(Collection dsls, String labelName) { + dsls.findAll { it.label == labelName}.each { + sendMessageIfApplicable(it) + } + } + + @Override + void trigger() { + (getAccurestContracts().values().flatten() as Collection).each { GroovyDsl groovyDsl -> + sendMessageIfApplicable(groovyDsl) + } + } + + private void sendMessageIfApplicable(GroovyDsl groovyDsl) { + if (!groovyDsl.outputMessage) { + return + } + AccurestMessage message = accurestMessaging.create(groovyDsl.outputMessage.body.clientValue, + groovyDsl.outputMessage.headers.asStubSideMap()) + accurestMessaging.send(message, groovyDsl.outputMessage.sentTo) + } + private URL returnStubUrlIfMatches(boolean condition) { return condition ? stubServer.stubUrl : null } private void startStubServers(StubConfiguration stubConfiguration, StubRepository repository) { List mappings = repository.getProjectDescriptors() - Collection contracts = repository.accurestContracts + Collection contracts = repository.accurestContracts stubServer = portScanner.tryToExecuteWithFreePort { int availablePort -> return new StubServer(availablePort, stubConfiguration, mappings, contracts).start() } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy index 9ea6992988..9a969213bf 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -1,9 +1,8 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic -import groovy.transform.PackageScope import groovy.util.logging.Slf4j - +import io.codearte.accurest.messaging.AccurestMessaging /** * Factory of StubRunners. Basing on the options and passed collaborators * downloads the stubs and returns a list of corresponding stub runners. @@ -15,13 +14,15 @@ class StubRunnerFactory { private final StubRunnerOptions stubRunnerOptions private final Collection collaborators private final StubDownloader stubDownloader + private final AccurestMessaging accurestMessaging StubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection collaborators, - StubDownloader stubDownloader) { + StubDownloader stubDownloader, AccurestMessaging accurestMessaging) { this.stubRunnerOptions = stubRunnerOptions this.collaborators = collaborators this.stubDownloader = stubDownloader + this.accurestMessaging = accurestMessaging } Collection createStubsFromServiceConfiguration() { @@ -42,7 +43,7 @@ class StubRunnerFactory { private StubRunner createStubRunner(File unzippedStubsDir, StubConfiguration stubsConfiguration, StubRunnerOptions stubRunnerOptions) { - return new StubRunner(stubRunnerOptions, unzippedStubsDir.path, stubsConfiguration) + return new StubRunner(stubRunnerOptions, unzippedStubsDir.path, stubsConfiguration, accurestMessaging) } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMessagingTrigger.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMessagingTrigger.groovy new file mode 100644 index 0000000000..0fd2ef1c8a --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMessagingTrigger.groovy @@ -0,0 +1,18 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.PackageScope +import io.codearte.accurest.messaging.AccurestMessaging +/** + * @author Marcin Grzejszczak + */ +@PackageScope +class StubRunnerMessagingTrigger { + + private final AccurestMessaging accurestMessaging + + StubRunnerMessagingTrigger(AccurestMessaging accurestMessaging) { + this.accurestMessaging = accurestMessaging + } + + void trigger +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy index 8fb22a1dd0..62e5cc5952 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy @@ -6,6 +6,7 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j +import io.codearte.accurest.dsl.GroovyDsl @CompileStatic @Slf4j @@ -14,10 +15,10 @@ class StubServer { private WireMockServer wireMockServer final StubConfiguration stubConfiguration final Collection mappings - final Collection contracts + final Collection contracts StubServer(int port, StubConfiguration stubConfiguration, Collection mappings, - Collection contracts) { + Collection contracts) { this.stubConfiguration = stubConfiguration this.mappings = mappings this.wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(port)) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy new file mode 100644 index 0000000000..99090b8bdc --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy @@ -0,0 +1,25 @@ +package io.codearte.accurest.stubrunner + +interface StubTriggerer { + + /** + * Triggers an event by a given label for a given {@code groupid:artifactid} notation. You can use only {@code artifactId} too. + * + * Feature related to messaging. + */ + void trigger(String ivyNotation, String labelName) + + /** + * Triggers an event by a given label. + * + * Feature related to messaging. + */ + void trigger(String labelName) + + /** + * Triggers all possible events. + * + * Feature related to messaging. + */ + void trigger() +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy index 2baa98ea68..0d368096bb 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.stubrunner +import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging import org.junit.Rule import org.junit.rules.TemporaryFolder import spock.lang.Specification @@ -12,7 +13,7 @@ class StubRunnerFactorySpec extends Specification { Collection collaborators = [new StubConfiguration("a:b"), new StubConfiguration("c:d")] StubDownloader downloader = Mock(StubDownloader) StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(stubRepositoryRoot: 'http://sth.net') - StubRunnerFactory factory = new StubRunnerFactory(stubRunnerOptions, collaborators, downloader) + StubRunnerFactory factory = new StubRunnerFactory(stubRunnerOptions, collaborators, downloader, new NoOpAccurestMessaging()) def "Should download stub definitions many times"() { given: From fc96041227d5653b30afcbb9fa705580de8f43af Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 22 Apr 2016 23:45:24 +0200 Subject: [PATCH 522/719] Fixing test --- .../stubrunner/messaging/camel/CamelStubRunnerSpec.groovy | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy index 63102256f1..c55cbe1440 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest.stubrunner.messaging.camel import com.fasterxml.jackson.databind.ObjectMapper +import groovy.json.JsonSlurper import io.codearte.accurest.stubrunner.StubFinder import org.apache.activemq.camel.component.ActiveMQComponent import org.apache.camel.CamelContext @@ -97,7 +98,9 @@ class CamelStubRunnerSpec extends Specification { Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - objectMapper.writeValueAsString(receivedMessage.in.body) == '{"bookName":"foo"}' + new JsonSlurper().parseText( + objectMapper.writeValueAsString( + receivedMessage.in.body)) == new JsonSlurper().parseText('{"bookName":"foo"}') receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } From 1a50a4baf14fc1268300c07fb6727f246d6e3cc0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 23 Apr 2016 01:16:06 +0200 Subject: [PATCH 523/719] Added Spring Integration client side --- .../camel/AccurestCamelMessaging.java | 17 ++- .../accurest/messaging/AccurestMessaging.java | 6 + .../messaging/noop/NoOpAccurestMessaging.java | 11 +- .../AccurestIntegrationMessaging.java | 17 ++- .../stream/AccurestStreamMessaging.java | 17 ++- samples/messaging-integration/build.gradle | 1 - .../config/AccurestSpringMessaging.groovy | 6 + .../camel/CamelStubRunnerSpec.groovy | 23 ++-- .../build.gradle | 22 ++++ .../StubRunnerIntegrationConfiguration.groovy | 46 +++++++ ...tubRunnerIntegrationMessageSelector.groovy | 58 +++++++++ .../StubRunnerIntegrationTransformer.groovy | 29 +++++ .../main/resources/META-INF/spring.factories | 3 + .../messaging/integration/BookReturned.groovy | 16 +++ .../IntegrationStubRunnerSpec.groovy | 114 ++++++++++++++++++ .../src/test/resources/application.yml | 2 + .../test/resources/integration-context.xml | 19 +++ ...ntegrationService-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1746 bytes .../integrationService-0.0.1-SNAPSHOT.pom | 9 ++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++ .../maven-metadata-local.xml | 12 ++ 21 files changed, 411 insertions(+), 29 deletions(-) create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/resources/META-INF/spring.factories create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/BookReturned.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/integration-context.xml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata-local.xml diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java index bf1eef7dc1..914d962f47 100644 --- a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java +++ b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java @@ -1,8 +1,8 @@ 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 java.util.Map; +import java.util.concurrent.TimeUnit; + import org.apache.camel.CamelContext; import org.apache.camel.ConsumerTemplate; import org.apache.camel.Exchange; @@ -14,8 +14,9 @@ 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; +import io.codearte.accurest.messaging.AccurestMessage; +import io.codearte.accurest.messaging.AccurestMessageBuilder; +import io.codearte.accurest.messaging.AccurestMessaging; /** * @author Marcin Grzejszczak @@ -49,6 +50,12 @@ public class AccurestCamelMessaging implements AccurestMessaging } } + @Override + @SuppressWarnings("unchecked") + public void send(T payload, Map headers, String destination) { + send(builder.create(payload, headers), destination); + } + @Override @SuppressWarnings("unchecked") public AccurestMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit) { diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java index 226f800046..17ee2e40bf 100644 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java @@ -1,5 +1,6 @@ package io.codearte.accurest.messaging; +import java.util.Map; import java.util.concurrent.TimeUnit; /** @@ -15,6 +16,11 @@ public interface AccurestMessaging extends Accure */ void send(AccurestMessage message, String destination); + /** + * Sends the given payload with headers, to the given destination. + */ + void send(PAYLOAD payload, Map headers, String destination); + /** * Receives the {@link AccurestMessage} from the given destination. You can provide the timeout * for receiving that message. diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java index b99efe7a49..77d186bcd8 100644 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java @@ -1,11 +1,11 @@ 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; +import io.codearte.accurest.messaging.AccurestMessage; +import io.codearte.accurest.messaging.AccurestMessaging; + /** * @author Marcin Grzejszczak */ @@ -15,6 +15,11 @@ public class NoOpAccurestMessaging implements AccurestMessaging { } + @Override + public void send(Object payload, Map headers, String destination) { + + } + @Override public AccurestMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit) { return null; diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java index 2486080560..b977036e36 100644 --- a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java +++ b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java @@ -1,8 +1,8 @@ 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 java.util.Map; +import java.util.concurrent.TimeUnit; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -12,8 +12,9 @@ import org.springframework.messaging.MessageChannel; import org.springframework.messaging.PollableChannel; import org.springframework.stereotype.Component; -import java.util.Map; -import java.util.concurrent.TimeUnit; +import io.codearte.accurest.messaging.AccurestMessage; +import io.codearte.accurest.messaging.AccurestMessageBuilder; +import io.codearte.accurest.messaging.AccurestMessaging; /** * @author Marcin Grzejszczak @@ -33,6 +34,12 @@ public class AccurestIntegrationMessaging implements AccurestMessaging headers, String destination) { + send(builder.create(payload, headers), destination); + } + @Override public void send(AccurestMessage> message, String destination) { try { diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java index 368a7d5cd0..a300178cc0 100644 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java @@ -1,8 +1,8 @@ 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 java.util.Map; +import java.util.concurrent.TimeUnit; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -11,8 +11,9 @@ import org.springframework.context.ApplicationContext; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; -import java.util.Map; -import java.util.concurrent.TimeUnit; +import io.codearte.accurest.messaging.AccurestMessage; +import io.codearte.accurest.messaging.AccurestMessageBuilder; +import io.codearte.accurest.messaging.AccurestMessaging; /** * @author Marcin Grzejszczak @@ -33,6 +34,12 @@ public class AccurestStreamMessaging implements AccurestMessaging headers, String destination) { + send(builder.create(payload, headers), destination); + } + @Override public void send(AccurestMessage> message, String destination) { try { diff --git a/samples/messaging-integration/build.gradle b/samples/messaging-integration/build.gradle index 5096207045..d583c1e803 100644 --- a/samples/messaging-integration/build.gradle +++ b/samples/messaging-integration/build.gradle @@ -13,7 +13,6 @@ 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' diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy index 8604d1e641..7599cbbb7f 100644 --- a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy +++ b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy @@ -29,6 +29,12 @@ public class AccurestSpringMessaging implements AccurestMessaging this.jmsTemplate = jmsTemplate } + @Override + @SuppressWarnings("unchecked") + public void send(T payload, Map headers, String destination) { + send(builder.create(payload, headers), destination); + } + @Override public void send(AccurestMessage message, String destination) { try { diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy index c55cbe1440..b578196da2 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -1,6 +1,6 @@ package io.codearte.accurest.stubrunner.messaging.camel -import com.fasterxml.jackson.databind.ObjectMapper +import groovy.json.JsonOutput import groovy.json.JsonSlurper import io.codearte.accurest.stubrunner.StubFinder import org.apache.activemq.camel.component.ActiveMQComponent @@ -34,7 +34,7 @@ class CamelStubRunnerSpec extends Specification { Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - receivedMessage.in.body == '{"bookName":"foo"}' + assertJsons(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } @@ -45,7 +45,7 @@ class CamelStubRunnerSpec extends Specification { Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - receivedMessage.in.body == '{ "bookName" : "foo" }' + assertJsons(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } @@ -56,7 +56,7 @@ class CamelStubRunnerSpec extends Specification { Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - receivedMessage.in.body == '{ "bookName" : "foo" }' + assertJsons(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } @@ -67,7 +67,7 @@ class CamelStubRunnerSpec extends Specification { Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - receivedMessage.in.body == '{ "bookName" : "foo" }' + assertJsons(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } @@ -90,20 +90,23 @@ class CamelStubRunnerSpec extends Specification { } def 'should trigger messages by running all triggers'() { - given: - ObjectMapper objectMapper = new ObjectMapper() when: stubFinder.trigger() then: Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - new JsonSlurper().parseText( - objectMapper.writeValueAsString( - receivedMessage.in.body)) == new JsonSlurper().parseText('{"bookName":"foo"}') + assertJsons(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } + private boolean assertJsons(Object payload) { + String objectAsString = payload instanceof String ? payload : + JsonOutput.toJson(payload) + def json = new JsonSlurper().parseText(objectAsString) + return json.bookName == 'foo' + } + @Bean ActiveMQComponent activeMQComponent(@Value('${activemq.url:vm://localhost?broker.persistent=false}') String url) { return new ActiveMQComponent(brokerURL: url) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle new file mode 100644 index 0000000000..89699fedfe --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle @@ -0,0 +1,22 @@ +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +dependencies { + compile project(':stub-runner-root:stub-runner-spring') + compile project(':accurest-messaging-root:accurest-messaging-integration') + compile 'org.springframework.integration:spring-integration-java-dsl:[1.1.2.RELEASE,)' + + testCompile 'org.springframework.boot:spring-boot-starter-integration:1.3.3.RELEASE' + 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') + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy new file mode 100644 index 0000000000..581dc1e98d --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -0,0 +1,46 @@ +package io.codearte.accurest.stubrunner.messaging.integration + +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.stubrunner.BatchStubRunner +import io.codearte.accurest.stubrunner.StubConfiguration +import org.springframework.beans.factory.config.AutowireCapableBeanFactory +import org.springframework.context.Lifecycle +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.integration.dsl.FilterEndpointSpec +import org.springframework.integration.dsl.GenericEndpointSpec +import org.springframework.integration.dsl.IntegrationFlow +import org.springframework.integration.dsl.IntegrationFlows +import org.springframework.stereotype.Service +/** + * Spring Integration configuration that iterates over the downloaded Groovy DSLs + * and registers a flow for each DSL. + * + * @author Marcin Grzejszczak + */ +@Configuration +class StubRunnerIntegrationConfiguration { + + @Bean + FlowRegistrar service(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner) { + Map> accurestContracts = batchStubRunner.accurestContracts + accurestContracts.each { StubConfiguration key, Collection value -> + String name = "${key.groupId}_${key.artifactId}" + value.findAll { it?.input?.messageFrom && it?.outputMessage?.sentTo }.each { GroovyDsl dsl -> + String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" + IntegrationFlow integrationFlow = IntegrationFlows.from(dsl.input.messageFrom) + .filter(new StubRunnerIntegrationMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) + .transform(new StubRunnerIntegrationTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) + .channel(dsl.outputMessage.sentTo) + .get() + beanFactory.initializeBean(integrationFlow, "${name}_${dsl.label}_${dsl.hashCode()}") + beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); + beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); + } + } + return new FlowRegistrar() + } + + @Service + static class FlowRegistrar {} +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy new file mode 100644 index 0000000000..976edb9909 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy @@ -0,0 +1,58 @@ +package io.codearte.accurest.stubrunner.messaging.integration + +import com.fasterxml.jackson.databind.ObjectMapper +import com.jayway.jsonpath.DocumentContext +import com.jayway.jsonpath.JsonPath +import com.toomuchcoding.jsonassert.JsonAssertion +import com.toomuchcoding.jsonassert.JsonVerifiable +import groovy.transform.CompileStatic +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.util.JsonPaths +import io.codearte.accurest.util.JsonToJsonPathsConverter +import org.springframework.integration.core.MessageSelector +import org.springframework.messaging.Message + +/** + * Passes through a message that matches the one defined in the DSL + * + * @author Marcin Grzejszczak + */ +@CompileStatic +class StubRunnerIntegrationMessageSelector implements MessageSelector { + + private final GroovyDsl groovyDsl + private final ObjectMapper objectMapper = new ObjectMapper() + + StubRunnerIntegrationMessageSelector(GroovyDsl groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + boolean accept(Message message) { + if(!headersMatch(message)){ + return false + } + Object inputMessage = message.getPayload() + JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValues(groovyDsl.input.messageBody) + DocumentContext parsedJson = JsonPath.parse(objectMapper.writeValueAsString(inputMessage)) + return jsonPaths.every { matchesJsonPath(parsedJson, it) } + } + + private boolean matchesJsonPath(DocumentContext parsedJson, JsonVerifiable jsonVerifiable) { + try { + JsonAssertion.assertThat(parsedJson).matchesJsonPath(jsonVerifiable.jsonPath()) + return true + } catch (Exception e) { + return false + } + } + + private boolean headersMatch(Message message) { + Map headers = message.getHeaders() + return groovyDsl.input.messageHeaders.entries.every { + String name = it.name + Object value = it.clientValue + return headers.get(name) == value + } + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy new file mode 100644 index 0000000000..e90cab0ca3 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy @@ -0,0 +1,29 @@ +package io.codearte.accurest.stubrunner.messaging.integration + +import io.codearte.accurest.builder.BodyAsString +import io.codearte.accurest.dsl.GroovyDsl +import org.springframework.integration.transformer.GenericTransformer +import org.springframework.messaging.Message +import org.springframework.messaging.MessageHeaders +import org.springframework.messaging.support.MessageBuilder + +/** + * Sends forward a message defined in the DSL. + * + * @author Marcin Grzejszczak + */ +class StubRunnerIntegrationTransformer implements GenericTransformer, Message> { + + private final GroovyDsl groovyDsl + + StubRunnerIntegrationTransformer(GroovyDsl groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + Message transform(Message source) { + String payload = BodyAsString.extractClientValueFrom(groovyDsl.outputMessage.body) + Map headers = groovyDsl.outputMessage.headers.asStubSideMap() + return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..dfd989c8bc --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.stubrunner.messaging.integration.StubRunnerIntegrationConfiguration diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/BookReturned.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/BookReturned.groovy new file mode 100644 index 0000000000..c5826c848d --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/BookReturned.groovy @@ -0,0 +1,16 @@ +package io.codearte.accurest.stubrunner.messaging.integration + +import com.fasterxml.jackson.annotation.JsonCreator +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode + +@CompileStatic +@EqualsAndHashCode +class BookReturned implements Serializable { + final String bookName + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + BookReturned(String bookName) { + this.bookName = bookName + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy new file mode 100644 index 0000000000..f9e81b6846 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy @@ -0,0 +1,114 @@ +package io.codearte.accurest.stubrunner.messaging.integration + +import groovy.json.JsonOutput +import groovy.json.JsonSlurper +import io.codearte.accurest.messaging.AccurestMessage +import io.codearte.accurest.messaging.AccurestMessaging +import io.codearte.accurest.stubrunner.StubFinder +import org.springframework.beans.factory.BeanNotOfRequiredTypeException +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.ImportResource +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification + +import java.util.concurrent.TimeUnit +/** + * @author Marcin Grzejszczak + */ +@Configuration +@ComponentScan +@EnableAutoConfiguration +@ContextConfiguration(classes = IntegrationStubRunnerSpec, loader = SpringApplicationContextLoader) +@ImportResource("classpath*:integration-context.xml") +class IntegrationStubRunnerSpec extends Specification { + + @Autowired StubFinder stubFinder + @Autowired AccurestMessaging messaging + + def 'should download the stub and register a route for it'() { + when: + messaging.send(new BookReturned('foo'), [sample: 'header'], 'input') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a message by label'() { + when: + stubFinder.trigger('return_book_1') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a label for the existing groupId:artifactId'() { + when: + stubFinder.trigger('io.codearte.accurest.stubs:integrationService', 'return_book_1') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a label for the existing artifactId'() { + when: + stubFinder.trigger('integrationService', 'return_book_1') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + def 'should not run any wrong trigger when missing label is passed'() { + given: + stubFinder.trigger('missing label') + when: + messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + then: + Exception e = thrown(RuntimeException) + e.cause.class == BeanNotOfRequiredTypeException + } + + def 'should not run any wrong trigger when missing label and artifactid is passed'() { + given: + stubFinder.trigger('some:service', 'return_book_1') + when: + messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + then: + Exception e = thrown(RuntimeException) + e.cause.class == BeanNotOfRequiredTypeException + } + + def 'should trigger messages by running all triggers'() { + when: + stubFinder.trigger() + then: + AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + private boolean assertJsons(Object payload) { + String objectAsString = payload instanceof String ? payload : + JsonOutput.toJson(payload) + def json = new JsonSlurper().parseText(objectAsString) + return json.bookName == 'foo' + } + +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml new file mode 100644 index 0000000000..890cbe6dd8 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo/repository/ +stubrunner.stubs.ids: io.codearte.accurest.stubs:integrationService \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/integration-context.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/integration-context.xml new file mode 100644 index 0000000000..c342dc9e94 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/integration-context.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..86c61d52ec4b9571f84240dc880daa2e9e5f5b71 GIT binary patch literal 1746 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJwREYr^0ql^9WtID{d1|?MEQiV35J8Cn-Na zJ1DiJv?wn%#ZWK3C_lffGBkvffjM}xRJbn?msW5yFtWU0W?%plroF!0O%4JM=U=an z*mH(UwdCzI5m~3!4|=PuXZ|qUxSLJs-}kb$dB%Ip^P{@5gEY1tjkxx8$;BHHGwt?e zE&5(lc3HvtiT8o3$i(xGi|2lc2y=<8Y-rf}ID6AP7961ES=3gdP0N#N2%2wI|U9La*jX!q(RaC(+5Y9PgfcBZ3DHgq-FmR zWAvPN|JzN?y$AZ5FPj&CoqwGl6n~H~i2{bnd$}npyMf_h#YkM37$JvA3@|)GF~g*_ z*B=xnN6)`r{=tmx>B8jgi|PelEsbtjW3_b0>l5#!Jbv6Q4qw6NXwW{>{Qcf|*F-7kF%T)__5$Z$tq9dMOLv*$5$!1-ViU9XS-^z{K3m zw=Nygy&0l$souP^NlvURE&cwNCDBG4b_?3J&9y1I(6;to<)Y^?$Il*Yc)D6ZOlr$g zlMKTLTNR~J6n`DJXe|-toB6OW+TX9%dDE|-(ng!D+;v^5Y#R=jYUaBLD(Tf9v~6-c zKT~s;&Xkmb#jZQGo*qB>M3v8AG5>MCrb(UEOzVob2ZnO#9{t3I$lzLNB>`GS%S|jO z$jnPG24^%zCJ|=bXL*rE(CSWgY zSRsWCT0w(s8)n8uw(TX*Qf%%;whfVufwqCNF&^76a{{t$Y`~Hbmu=|z0%#W~UtqBd omUghEIB-A$)6QQ + + 4.0.0 + io.codearte.accurest.stubs + integrationService + 0.0.1-SNAPSHOT + pom + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..20ba9761d8 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + integrationService + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata-local.xml new file mode 100644 index 0000000000..b93b655f1f --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + integrationService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + From b7e923af6dab9b0970e154ccd24b9f1ce7ba393c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 23 Apr 2016 01:20:02 +0200 Subject: [PATCH 524/719] Removed duplicated code --- .../integration/StubRunnerIntegrationConfiguration.groovy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy index 581dc1e98d..24199906fc 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -33,7 +33,7 @@ class StubRunnerIntegrationConfiguration { .transform(new StubRunnerIntegrationTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) .channel(dsl.outputMessage.sentTo) .get() - beanFactory.initializeBean(integrationFlow, "${name}_${dsl.label}_${dsl.hashCode()}") + beanFactory.initializeBean(integrationFlow, flowName) beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); } From bc53b23f335c57d84d93513e5f5021764c74f974 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 23 Apr 2016 08:54:43 +0200 Subject: [PATCH 525/719] Added matching for headers as Patterns --- .../messaging/camel/StubRunnerCamelPredicate.groovy | 7 ++++++- .../StubRunnerIntegrationMessageSelector.groovy | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy index 5c5834807f..3ab58d6d8e 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy @@ -12,6 +12,8 @@ import io.codearte.accurest.util.JsonToJsonPathsConverter import org.apache.camel.Exchange import org.apache.camel.Predicate +import java.util.regex.Pattern + /** * Passes through a message that matches the one defined in the DSL * @@ -52,7 +54,10 @@ class StubRunnerCamelPredicate implements Predicate { return groovyDsl.input.messageHeaders.entries.every { String name = it.name Object value = it.clientValue - return headers.get(name) == value + Object valueInHeader = headers.get(name) + return value instanceof Pattern ? + value.matcher(valueInHeader.toString()).matches() : + valueInHeader == value } } } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy index 976edb9909..1184f0acef 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy @@ -12,6 +12,8 @@ import io.codearte.accurest.util.JsonToJsonPathsConverter import org.springframework.integration.core.MessageSelector import org.springframework.messaging.Message +import java.util.regex.Pattern + /** * Passes through a message that matches the one defined in the DSL * @@ -52,7 +54,10 @@ class StubRunnerIntegrationMessageSelector implements MessageSelector { return groovyDsl.input.messageHeaders.entries.every { String name = it.name Object value = it.clientValue - return headers.get(name) == value + Object valueInHeader = headers.get(name) + return value instanceof Pattern ? + value.matcher(valueInHeader.toString()).matches() : + valueInHeader == value } } } From 4c16055ea5bdabd5bd34e98d45694acbea8bb229 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 23 Apr 2016 12:00:10 +0200 Subject: [PATCH 526/719] Added Stream integration --- .../accurest-messaging-stream/build.gradle | 3 +- .../messaging/stream/StreamMessage.java | 6 +- .../stub-runner-messaging-stream/build.gradle | 22 ++++ .../StubRunnerStreamConfiguration.groovy | 52 ++++++++ .../StubRunnerStreamMessageSelector.groovy | 63 ++++++++++ .../stream/StubRunnerStreamTransformer.groovy | 29 +++++ .../main/resources/META-INF/spring.factories | 3 + .../messaging/stream/BookReturned.groovy | 16 +++ .../stream/StreamStubRunnerSpec.groovy | 111 ++++++++++++++++++ .../src/test/resources/application.yml | 2 + .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ++ .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1746 bytes .../streamService-0.0.1-SNAPSHOT.pom | 9 ++ .../streamService/maven-metadata-local.xml | 12 ++ 14 files changed, 338 insertions(+), 2 deletions(-) create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/BookReturned.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml diff --git a/accurest-messaging/accurest-messaging-stream/build.gradle b/accurest-messaging/accurest-messaging-stream/build.gradle index 4b045bb943..7cf3543d4f 100644 --- a/accurest-messaging/accurest-messaging-stream/build.gradle +++ b/accurest-messaging/accurest-messaging-stream/build.gradle @@ -11,6 +11,7 @@ repositories { 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:[1.0.0.RC2,)' + // for MessageCollector compile 'org.springframework.cloud:spring-cloud-stream-test-support:[1.0.0.RC2,)' } \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java index 7b7faeb68a..8bc2a9ecb0 100644 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java @@ -1,9 +1,10 @@ package io.codearte.accurest.messaging.stream; -import io.codearte.accurest.messaging.AccurestMessage; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; +import io.codearte.accurest.messaging.AccurestMessage; + /** * @author Marcin Grzejszczak */ @@ -12,6 +13,9 @@ public class StreamMessage implements AccurestMessage> { private final Message delegate; public StreamMessage(Message delegate) { + if (delegate == null) { + throw new IllegalArgumentException("Message can't be null"); + } this.delegate = delegate; } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle new file mode 100644 index 0000000000..20d6bac9f4 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle @@ -0,0 +1,22 @@ +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +dependencies { + compile project(':stub-runner-root:stub-runner-spring') + compile project(':accurest-messaging-root:accurest-messaging-stream') + compile 'org.springframework.integration:spring-integration-java-dsl:[1.1.2.RELEASE,)' + + testCompile 'org.springframework.cloud:spring-cloud-stream-test-support:1.0.0.RC2' + 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') + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy new file mode 100644 index 0000000000..7520883395 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy @@ -0,0 +1,52 @@ +package io.codearte.accurest.stubrunner.messaging.stream + +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.stubrunner.BatchStubRunner +import io.codearte.accurest.stubrunner.StubConfiguration +import org.springframework.beans.factory.config.AutowireCapableBeanFactory +import org.springframework.cloud.stream.annotation.EnableBinding +import org.springframework.cloud.stream.binding.ChannelBindingService +import org.springframework.context.Lifecycle +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.integration.dsl.FilterEndpointSpec +import org.springframework.integration.dsl.GenericEndpointSpec +import org.springframework.integration.dsl.IntegrationFlow +import org.springframework.integration.dsl.IntegrationFlows +import org.springframework.messaging.MessageChannel +import org.springframework.stereotype.Service +/** + * Spring Cloud Stream configuration that iterates over the downloaded Groovy DSLs + * and registers a flow for each DSL. + * + * @author Marcin Grzejszczak + */ +@Configuration +@EnableBinding +class StubRunnerStreamConfiguration { + + @Bean + FlowRegistrar service(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner, ChannelBindingService channelBindingService) { + Map> accurestContracts = batchStubRunner.accurestContracts + accurestContracts.each { StubConfiguration key, Collection value -> + String name = "${key.groupId}_${key.artifactId}" + value.findAll { it?.input?.messageFrom && it?.outputMessage?.sentTo }.each { GroovyDsl dsl -> + String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" + IntegrationFlow integrationFlow = IntegrationFlows.from(dsl.input.messageFrom) + .filter(new StubRunnerStreamMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) + .transform(new StubRunnerStreamTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) + .channel(dsl.outputMessage.sentTo) + .get() + beanFactory.initializeBean(integrationFlow, flowName) + beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); + beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); + channelBindingService.bindConsumer(beanFactory.getBean(dsl.input.messageFrom, MessageChannel.class), dsl.input.messageFrom) + channelBindingService.bindProducer(beanFactory.getBean(dsl.outputMessage.sentTo, MessageChannel.class), dsl.outputMessage.sentTo) + } + } + return new FlowRegistrar() + } + + @Service + static class FlowRegistrar {} +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy new file mode 100644 index 0000000000..37e60c85b7 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy @@ -0,0 +1,63 @@ +package io.codearte.accurest.stubrunner.messaging.stream + +import com.fasterxml.jackson.databind.ObjectMapper +import com.jayway.jsonpath.DocumentContext +import com.jayway.jsonpath.JsonPath +import com.toomuchcoding.jsonassert.JsonAssertion +import com.toomuchcoding.jsonassert.JsonVerifiable +import groovy.transform.CompileStatic +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.util.JsonPaths +import io.codearte.accurest.util.JsonToJsonPathsConverter +import org.springframework.integration.core.MessageSelector +import org.springframework.messaging.Message + +import java.util.regex.Pattern + +/** + * Passes through a message that matches the one defined in the DSL + * + * @author Marcin Grzejszczak + */ +@CompileStatic +class StubRunnerStreamMessageSelector implements MessageSelector { + + private final GroovyDsl groovyDsl + private final ObjectMapper objectMapper = new ObjectMapper() + + StubRunnerStreamMessageSelector(GroovyDsl groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + boolean accept(Message message) { + if(!headersMatch(message)){ + return false + } + Object inputMessage = message.getPayload() + JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithStubsSideValues(groovyDsl.input.messageBody) + DocumentContext parsedJson = JsonPath.parse(objectMapper.writeValueAsString(inputMessage)) + return jsonPaths.every { matchesJsonPath(parsedJson, it) } + } + + private boolean matchesJsonPath(DocumentContext parsedJson, JsonVerifiable jsonVerifiable) { + try { + JsonAssertion.assertThat(parsedJson).matchesJsonPath(jsonVerifiable.jsonPath()) + return true + } catch (Exception e) { + return false + } + } + + private boolean headersMatch(Message message) { + Map headers = message.getHeaders() + return groovyDsl.input.messageHeaders.entries.every { + String name = it.name + Object value = it.clientValue + Object valueInHeader = headers.get(name) + return value instanceof Pattern ? + value.matcher(valueInHeader.toString()).matches() : + valueInHeader == value + } + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy new file mode 100644 index 0000000000..3129f70ace --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy @@ -0,0 +1,29 @@ +package io.codearte.accurest.stubrunner.messaging.stream + +import io.codearte.accurest.builder.BodyAsString +import io.codearte.accurest.dsl.GroovyDsl +import org.springframework.integration.transformer.GenericTransformer +import org.springframework.messaging.Message +import org.springframework.messaging.MessageHeaders +import org.springframework.messaging.support.MessageBuilder + +/** + * Sends forward a message defined in the DSL. + * + * @author Marcin Grzejszczak + */ +class StubRunnerStreamTransformer implements GenericTransformer, Message> { + + private final GroovyDsl groovyDsl + + StubRunnerStreamTransformer(GroovyDsl groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + Message transform(Message source) { + String payload = BodyAsString.extractClientValueFrom(groovyDsl.outputMessage.body) + Map headers = groovyDsl.outputMessage.headers.asStubSideMap() + return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..7b69d1b85a --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.stubrunner.messaging.stream.StubRunnerStreamConfiguration diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/BookReturned.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/BookReturned.groovy new file mode 100644 index 0000000000..0dd3ca4216 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/BookReturned.groovy @@ -0,0 +1,16 @@ +package io.codearte.accurest.stubrunner.messaging.stream + +import com.fasterxml.jackson.annotation.JsonCreator +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode + +@CompileStatic +@EqualsAndHashCode +class BookReturned implements Serializable { + final String bookName + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + BookReturned(String bookName) { + this.bookName = bookName + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy new file mode 100644 index 0000000000..ffe676551c --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy @@ -0,0 +1,111 @@ +package io.codearte.accurest.stubrunner.messaging.stream + +import groovy.json.JsonOutput +import groovy.json.JsonSlurper +import io.codearte.accurest.messaging.AccurestMessage +import io.codearte.accurest.messaging.AccurestMessaging +import io.codearte.accurest.stubrunner.StubFinder +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.context.annotation.ComponentScan +import org.springframework.context.annotation.Configuration +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification + +import java.util.concurrent.TimeUnit +/** + * @author Marcin Grzejszczak + */ +@Configuration +@ComponentScan +@EnableAutoConfiguration +@ContextConfiguration(classes = StreamStubRunnerSpec, loader = SpringApplicationContextLoader) +class StreamStubRunnerSpec extends Specification { + + @Autowired StubFinder stubFinder + @Autowired AccurestMessaging messaging + + def 'should download the stub and register a route for it'() { + when: + messaging.send(new BookReturned('foo'), [sample: 'header'], 'input') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('output') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a message by label'() { + when: + stubFinder.trigger('return_book_1') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('output') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a label for the existing groupId:artifactId'() { + when: + stubFinder.trigger('io.codearte.accurest.stubs:streamService', 'return_book_1') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('output') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + def 'should trigger a label for the existing artifactId'() { + when: + stubFinder.trigger('streamService', 'return_book_1') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('output') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + def 'should not run any wrong trigger when missing label is passed'() { + given: + stubFinder.trigger('missing label') + when: + messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + then: + RuntimeException e = thrown(RuntimeException) + e.cause.message.contains("Message can't be null") + } + + def 'should not run any wrong trigger when missing label and artifactid is passed'() { + given: + stubFinder.trigger('some:service', 'return_book_1') + when: + messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + then: + RuntimeException e = thrown(RuntimeException) + e.cause.message.contains("Message can't be null") + } + + def 'should trigger messages by running all triggers'() { + when: + stubFinder.trigger() + then: + AccurestMessage receivedMessage = messaging.receiveMessage('output') + and: + receivedMessage != null + assertJsons(receivedMessage.payload) + receivedMessage.headers.get('BOOK-NAME') == 'foo' + } + + private boolean assertJsons(Object payload) { + String objectAsString = payload instanceof String ? payload : + JsonOutput.toJson(payload) + def json = new JsonSlurper().parseText(objectAsString) + return json.bookName == 'foo' + } + +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml new file mode 100644 index 0000000000..154bfe1b6a --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo/repository/ +stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..bad844ba2a --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + streamService + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..86c61d52ec4b9571f84240dc880daa2e9e5f5b71 GIT binary patch literal 1746 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJwREYr^0ql^9WtID{d1|?MEQiV35J8Cn-Na zJ1DiJv?wn%#ZWK3C_lffGBkvffjM}xRJbn?msW5yFtWU0W?%plroF!0O%4JM=U=an z*mH(UwdCzI5m~3!4|=PuXZ|qUxSLJs-}kb$dB%Ip^P{@5gEY1tjkxx8$;BHHGwt?e zE&5(lc3HvtiT8o3$i(xGi|2lc2y=<8Y-rf}ID6AP7961ES=3gdP0N#N2%2wI|U9La*jX!q(RaC(+5Y9PgfcBZ3DHgq-FmR zWAvPN|JzN?y$AZ5FPj&CoqwGl6n~H~i2{bnd$}npyMf_h#YkM37$JvA3@|)GF~g*_ z*B=xnN6)`r{=tmx>B8jgi|PelEsbtjW3_b0>l5#!Jbv6Q4qw6NXwW{>{Qcf|*F-7kF%T)__5$Z$tq9dMOLv*$5$!1-ViU9XS-^z{K3m zw=Nygy&0l$souP^NlvURE&cwNCDBG4b_?3J&9y1I(6;to<)Y^?$Il*Yc)D6ZOlr$g zlMKTLTNR~J6n`DJXe|-toB6OW+TX9%dDE|-(ng!D+;v^5Y#R=jYUaBLD(Tf9v~6-c zKT~s;&Xkmb#jZQGo*qB>M3v8AG5>MCrb(UEOzVob2ZnO#9{t3I$lzLNB>`GS%S|jO z$jnPG24^%zCJ|=bXL*rE(CSWgY zSRsWCT0w(s8)n8uw(TX*Qf%%;whfVufwqCNF&^76a{{t$Y`~Hbmu=|z0%#W~UtqBd omUghEIB-A$)6QQ + + 4.0.0 + io.codearte.accurest.stubs + streamService + 0.0.1-SNAPSHOT + pom + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml new file mode 100644 index 0000000000..dc32790f53 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + streamService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + From b89e5a45ad571f6dc6f8ff87cd3d622f51ad293e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 23 Apr 2016 23:24:42 +0200 Subject: [PATCH 527/719] Added more docs for messaging --- .../MessagingMethodBodyBuilderSpec.groovy | 18 ++- .../accurest/builder/MessagingSpec.groovy | 137 ------------------ docs/src/docs/asciidoc/index.adoc | 2 + docs/src/docs/asciidoc/messaging.adoc | 8 +- docs/src/docs/asciidoc/rest.adoc | 2 +- docs/src/docs/asciidoc/stubrunner.adoc | 2 +- docs/src/docs/asciidoc/stubrunner_msg.adoc | 53 +++++++ ...IntegrationMessagingApplicationSpec.groovy | 21 ++- .../stub-runner-messaging-camel/README.adoc | 105 ++++++++++++++ .../camel/CamelStubRunnerSpec.groovy | 67 ++++++++- 10 files changed, 262 insertions(+), 153 deletions(-) delete mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingSpec.groovy create mode 100644 docs/src/docs/asciidoc/stubrunner_msg.adoc create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy index 7d9c1020b5..fd8c191617 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy @@ -9,6 +9,7 @@ class MessagingMethodBodyBuilderSpec extends Specification { def "should work for triggered based messaging with Spock"() { given: + // tag::trigger_method_dsl[] def contractDsl = GroovyDsl.make { label 'some_label' input { @@ -22,13 +23,16 @@ class MessagingMethodBodyBuilderSpec extends Specification { } } } + // end::trigger_method_dsl[] MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped(''' + stripped(test) == stripped( + // tag::trigger_method_test[] + ''' when: bookReturnedTriggered() @@ -38,7 +42,9 @@ class MessagingMethodBodyBuilderSpec extends Specification { and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") - ''') + ''' + // end::trigger_method_test[] + ) } def "should work for triggered based messaging with JUnit"() { @@ -62,7 +68,9 @@ class MessagingMethodBodyBuilderSpec extends Specification { builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped(''' + stripped(test) == stripped( + // tag::trigger_method_junit_test[] + ''' // when: bookReturnedTriggered(); @@ -72,7 +80,9 @@ class MessagingMethodBodyBuilderSpec extends Specification { // and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); - ''') + ''' + // end::trigger_method_junit_test[] + ) } private String stripped(String text) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingSpec.groovy deleted file mode 100644 index 84ac3d5e27..0000000000 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingSpec.groovy +++ /dev/null @@ -1,137 +0,0 @@ -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') - } - } - } - } -} diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 29acda015d..039ee5fb36 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -578,6 +578,8 @@ Accurest will also generate tests with guaranteed order of execution. include::stubrunner.adoc[] +include::stubrunner_msg.adoc[] + == Migration Guide === Migration to 0.4.7 diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc index e808abad5d..f6b856edba 100644 --- a/docs/src/docs/asciidoc/messaging.adoc +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -43,4 +43,10 @@ You have to provide as a dependency the `accurest-messaging-core` module. Exampl [source,groovy,indent=0] ---- testCompile "io.codearte.accurest:accurest-messaging-core:${accurestVersion}" ----- \ No newline at end of file +---- + +=== Publisher side test generation + +Having the `input` or `outputMessage` sections in your DSL will result in creation of tests on the publisher's side. + +//TODO: add examples from MessaginMethodBodyBuilderSpec \ No newline at end of file diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index c11fc37f88..83add091e3 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -1,4 +1,4 @@ -== Accurest REST +== Accurest HTTP === Gradle Project diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index bd12682eea..c6efd38570 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -1,4 +1,4 @@ -== Stub Runner +== Stub Runner for HTTP One of the issues that you could have encountered while using Accurest was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). The same takes place in terms of client side generation for messaging. diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc new file mode 100644 index 0000000000..7ce50d7b25 --- /dev/null +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -0,0 +1,53 @@ +== Stub Runner for Messaging + +WARNING: Feature available since 1.0.7 + +Stub Runner has the functionality to run the published stubs in memory. It can integrate with the following frameworks out of the box + +- Spring Integration +- Spring Cloud Stream +- Apache Camel + +It also provides points of entry to integrate with any other solution on the market. + +=== DSL + +The DSL for messaging looks a little bit different than the one that focuses on HTTP. + +==== Output triggered by a method + +The output message can be triggered by calling a method (e.g. a Scheduler was started and a message was sent) + +[source,groovy] +---- +include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=method_trigger,indent=0] +---- + +In this case the output message will be sent to `output` if a method called `bookReturnedTriggered` will be executed. In the message *publisher's* side +we will generate a test that will call that method to trigger the message. On the *consumer* side you can use the `some_label` to trigger the message. + +==== Output triggered by a message + +The output message can be triggered by receiving a message. + +[source,groovy] +---- +include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=message_trigger,indent=0] +---- + +In this case the output message will be sent to `output` if a proper message will be received on the `input` destination. In the message *publisher's* side +we will generate a test that will send the input message to the defined destination. On the *consumer* side you can either send a message to the input +destination or use the `some_label` to trigger the message. + +=== Stub triggering + +To trigger a message it's enough to use the `StubTiggerer` interface: + +[source,groovy] +---- +include::../../stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy[] +---- + +For convenience the `StubFinder` interface extends `StubTrigger` so it's enough to use only one in your tests. + +include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc[] \ No newline at end of file diff --git a/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy b/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy index 6b8cfeda18..98b6f19658 100644 --- a/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy +++ b/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy @@ -14,9 +14,6 @@ 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 { @@ -27,19 +24,30 @@ public class IntegrationMessagingApplicationSpec extends Specification { def "should work for triggered based messaging"() { given: + // tag::method_trigger[] def dsl = GroovyDsl.make { + // Human readable description + description 'Some description' + // Label by means of which the output message can be triggered label 'some_label' + // input to the contract input { + // the contract will be triggered by a method triggeredBy('bookReturnedTriggered()') } + // output message of the contract outputMessage { + // destination to which the output message will be sent sentTo('output') + // the body of the output message body('''{ "bookName" : "foo" }''') + // the headers of the output message headers { header('BOOK-NAME', 'foo') } } } + // end::method_trigger[] // generated test should look like this: when: bookReturnedTriggered() @@ -53,13 +61,19 @@ public class IntegrationMessagingApplicationSpec extends Specification { def "should generate tests triggered by a message"() { given: + // tag::message_trigger[] def dsl = GroovyDsl.make { + description 'Some Description' label 'some_label' + // input is a message input { + // the message was received from this destination messageFrom('input') + // has the following body messageBody([ bookName: 'foo' ]) + // and the following headers messageHeaders { header('sample', 'header') } @@ -74,6 +88,7 @@ public class IntegrationMessagingApplicationSpec extends Specification { } } } + // end::message_trigger[] // generated test should look like this: diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc new file mode 100644 index 0000000000..c6da067a99 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc @@ -0,0 +1,105 @@ +:input_name: jms:input +:output_name: jms:output + +=== Stub Runner Messaging Camel + +Accurest Stub Runner's messaging module gives you an easy way to integrate with Apache Camel. +For the provided artifacts it will automatically download the stubs and register the required +routes. + +==== Examples + +===== Stubs structure + +Let us assume that we have the following Maven repository with a deployed stubs for the +`camelService` application. + +[source,bash,indent=0] +---- +└── .m2 + └── repository + └── io + └── codearte + └── accurest + └── stubs + └── camelService + ├── 0.0.1-SNAPSHOT + │   ├── camelService-0.0.1-SNAPSHOT.pom + │   ├── camelService-0.0.1-SNAPSHOT-stubs.jar + │   └── maven-metadata-local.xml + └── maven-metadata-local.xml +---- + +And the stubs contain the following structure: + +[source,bash,indent=0] +---- +├── META-INF +│   └── MANIFEST.MF +└── repository + ├── accurest + │   ├── bookDeleted.groovy + │   ├── bookReturned1.groovy + │   └── bookReturned2.groovy + └── mappings +---- + +Let's consider the following contracts (let' number it with *1*): + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=sample_dsl,indent=0] +---- + +and number *2* + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] +---- + +===== Scenario 1 (no input message) + +So as to trigger a message via the `return_book_1` label we'll use the `StubTiggerer` interface as follows + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger,indent=0] +---- + +Next we'll want to listen to the output of the message sent to `{output_name}` + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] +---- + +And the received message would pass the following assertions + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] +---- + +===== Scenario 2 (output triggered by input) + +Since the route is set for you it's enough to just send a message to the `{output_name}` destination. + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_send,indent=0] +---- + +Next we'll want to listen to the output of the message sent to `{output_name}` + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_receive,indent=0] +---- + +And the received message would pass the following assertions + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_receive_message,indent=0] +---- \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy index b578196da2..69cfbca14c 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.stubrunner.messaging.camel import groovy.json.JsonOutput import groovy.json.JsonSlurper +import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.stubrunner.StubFinder import org.apache.activemq.camel.component.ActiveMQComponent import org.apache.camel.CamelContext @@ -29,24 +30,36 @@ class CamelStubRunnerSpec extends Specification { def 'should download the stub and register a route for it'() { when: + // tag::client_send[] camelContext.createProducerTemplate().sendBodyAndHeaders('jms:input', new BookReturned('foo'), [sample: 'header']) + // end::client_send[] then: + // tag::client_receive[] Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) + // end::client_receive[] and: + // tag::client_receive_message[] receivedMessage != null - assertJsons(receivedMessage.in.body) + assertThatBodyContainsBookNameFoo(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' + // end::client_receive_message[] } def 'should trigger a message by label'() { when: + // tag::client_trigger[] stubFinder.trigger('return_book_1') + // end::client_trigger[] then: + // tag::client_trigger_receive[] Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) + // end::client_trigger_receive[] and: + // tag::client_trigger_message[] receivedMessage != null - assertJsons(receivedMessage.in.body) + assertThatBodyContainsBookNameFoo(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' + // end::client_trigger_message[] } def 'should trigger a label for the existing groupId:artifactId'() { @@ -56,7 +69,7 @@ class CamelStubRunnerSpec extends Specification { Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - assertJsons(receivedMessage.in.body) + assertThatBodyContainsBookNameFoo(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } @@ -67,7 +80,7 @@ class CamelStubRunnerSpec extends Specification { Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - assertJsons(receivedMessage.in.body) + assertThatBodyContainsBookNameFoo(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } @@ -96,11 +109,11 @@ class CamelStubRunnerSpec extends Specification { Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: receivedMessage != null - assertJsons(receivedMessage.in.body) + assertThatBodyContainsBookNameFoo(receivedMessage.in.body) receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } - private boolean assertJsons(Object payload) { + private boolean assertThatBodyContainsBookNameFoo(Object payload) { String objectAsString = payload instanceof String ? payload : JsonOutput.toJson(payload) def json = new JsonSlurper().parseText(objectAsString) @@ -111,4 +124,46 @@ class CamelStubRunnerSpec extends Specification { ActiveMQComponent activeMQComponent(@Value('${activemq.url:vm://localhost?broker.persistent=false}') String url) { return new ActiveMQComponent(brokerURL: url) } + + GroovyDsl dsl = + // tag::sample_dsl[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'return_book_1' + input { + triggeredBy('bookReturnedTriggered()') + } + outputMessage { + sentTo('jms:output') + body('''{ "bookName" : "foo" }''') + headers { + header('BOOK-NAME', 'foo') + } + } + } + // end::sample_dsl[] + + GroovyDsl dsl2 = + // tag::sample_dsl_2[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'return_book_2' + input { + messageFrom('jms:input') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + } + outputMessage { + sentTo('jms:output') + body([ + bookName: 'foo' + ]) + headers { + header('BOOK-NAME', 'foo') + } + } + } + // end::sample_dsl_2[] } From bc1bdb7d1681fc2085966356d1f814643b2b1cbd Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 23 Apr 2016 23:26:51 +0200 Subject: [PATCH 528/719] Fixed docs --- docs/src/docs/asciidoc/stubrunner_msg.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc index 7ce50d7b25..617ab903ee 100644 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -45,7 +45,7 @@ To trigger a message it's enough to use the `StubTiggerer` interface: [source,groovy] ---- -include::../../stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy[] +include::../../../../stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy[] ---- For convenience the `StubFinder` interface extends `StubTrigger` so it's enough to use only one in your tests. From 573695caf0b61aa82dfc414a6dd71b0ea170d147 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 08:34:38 +0200 Subject: [PATCH 529/719] Updated messaging docs --- .../MessagingMethodBodyBuilderSpec.groovy | 36 +++++-- docs/src/docs/asciidoc/messaging.adoc | 101 +++++++++++++++++- 2 files changed, 127 insertions(+), 10 deletions(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy index fd8c191617..88ddd86b90 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy @@ -91,6 +91,7 @@ class MessagingMethodBodyBuilderSpec extends Specification { def "should generate tests triggered by a message for Spock"() { given: + // tag::trigger_message_dsl[] def contractDsl = GroovyDsl.make { label 'some_label' input { @@ -112,13 +113,16 @@ class MessagingMethodBodyBuilderSpec extends Specification { } } } + // end::trigger_message_dsl[] MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped(''' + stripped(test) == stripped( + // tag::trigger_message_spock[] + ''' given: def inputMessage = accurestMessaging.create( \'\'\'{"bookName":"foo"}\'\'\', @@ -134,7 +138,9 @@ class MessagingMethodBodyBuilderSpec extends Specification { and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") - ''') + ''' + // end::trigger_message_spock[] + ) } def "should generate tests triggered by a message for JUnit"() { @@ -166,7 +172,9 @@ class MessagingMethodBodyBuilderSpec extends Specification { builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped(''' + stripped(test) == stripped( + // tag::trigger_message_junit[] + ''' // given: AccurestMessage inputMessage = accurestMessaging.create( "{\\"bookName\\":\\"foo\\"}" @@ -183,11 +191,14 @@ class MessagingMethodBodyBuilderSpec extends Specification { DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); - ''') + ''' + // end::trigger_message_junit[] + ) } def "should generate tests without destination, triggered by a message"() { given: + // tag::trigger_no_output_dsl[] def contractDsl = GroovyDsl.make { label 'some_label' input { @@ -201,13 +212,16 @@ class MessagingMethodBodyBuilderSpec extends Specification { assertThat('bookWasDeleted()') } } + // end::trigger_no_output_dsl[] MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped(''' + stripped(test) == stripped( + // tag::trigger_no_output_spock[] + ''' given: def inputMessage = accurestMessaging.create( \'\'\'{"bookName":"foo"}\'\'\', @@ -220,7 +234,9 @@ class MessagingMethodBodyBuilderSpec extends Specification { then: noExceptionThrown() bookWasDeleted() - ''') + ''' + // end::trigger_no_output_spock[] + ) } def "should generate tests without destination, triggered by a message for JUnit"() { @@ -244,7 +260,9 @@ class MessagingMethodBodyBuilderSpec extends Specification { builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped(''' + stripped(test) == stripped( + // tag::trigger_no_output_junit[] + ''' // given: AccurestMessage inputMessage = accurestMessaging.create( "{\\"bookName\\":\\"foo\\"}" @@ -256,7 +274,9 @@ class MessagingMethodBodyBuilderSpec extends Specification { // then: bookWasDeleted(); - ''') + ''' + // end::trigger_no_output_junit[] + ) } } diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc index f6b856edba..3c0f5eb50f 100644 --- a/docs/src/docs/asciidoc/messaging.adoc +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -47,6 +47,103 @@ testCompile "io.codearte.accurest:accurest-messaging-core:${accurestVersion}" === Publisher side test generation -Having the `input` or `outputMessage` sections in your DSL will result in creation of tests on the publisher's side. +Having the `input` or `outputMessage` sections in your DSL will result in creation of tests on the publisher's side. By default +JUnit tests will be created, however there is also a possibility to create Spock tests. -//TODO: add examples from MessaginMethodBodyBuilderSpec \ No newline at end of file +=== Examples + +There are 3 main scenarios that we should take into consideration: + +- Scenario 1: there is no input message that produces an output one. The output message is triggered by a component +inside the application (e.g. scheduler) +- Scenario 2: the input message triggers an output message +- Scenarion 3: the input message is consumed and there is no output message + +==== Scenario 1 (no input message) + +For the given contract: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl] +---- + +The following JUnit test will be created: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_junit_test] +---- + +And the following Spock test would be created: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_test] +---- + +==== Scenario 2 (output triggered by input) + +For the given contract: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_dsl] +---- + +The following JUnit test will be created: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_junit] +---- + +And the following Spock test would be created: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_spock] +---- + +==== Scenario 3 (no output message) + +For the given contract: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_dsl] +---- + +The following JUnit test will be created: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_junit] +---- + +And the following Spock test would be created: + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_spock] +---- + +=== Consumer Stub Side generation + +Unlike the HTTP part - in Messaging we need to publish the Groovy DSL inside the JAR with a stub. Then it's parsed on the consumer side +and proper stubbed routes are created. + +For more infromation please consult the Stub Runner Messaging sections. + +==== Gradle Setup + +Example of Accurest Gradle setup: + +[source,groovy,indent=0] +---- +include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=jar_setup,indent=0] +---- + +==== Maven Setup + +Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) From b11e8905f8d60f63130b16d2fd5080547d146e79 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 08:43:55 +0200 Subject: [PATCH 530/719] Updated Camel docs --- .../stub-runner-messaging-camel/README.adoc | 32 +++++++++++++++++++ .../camel/CamelStubRunnerSpec.groovy | 6 ++++ 2 files changed, 38 insertions(+) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc index c6da067a99..ae95b36c7c 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc @@ -102,4 +102,36 @@ And the received message would pass the following assertions [source,groovy] ---- include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_receive_message,indent=0] +---- + +===== Custom triggers + +`StubTrigger` gives you the following options to trigger a message: + +===== Trigger by label + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger,indent=0] +---- + +===== Trigger by group and artifact ids + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] +---- + +===== Trigger by artifact ids + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] +---- + +===== Trigger all messages + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_all,indent=0] ---- \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy index 69cfbca14c..ef0aae52db 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -64,7 +64,9 @@ class CamelStubRunnerSpec extends Specification { def 'should trigger a label for the existing groupId:artifactId'() { when: + // tag::trigger_group_artifact[] stubFinder.trigger('io.codearte.accurest.stubs:camelService', 'return_book_1') + // end::trigger_group_artifact[] then: Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: @@ -75,7 +77,9 @@ class CamelStubRunnerSpec extends Specification { def 'should trigger a label for the existing artifactId'() { when: + // tag::trigger_artifact[] stubFinder.trigger('camelService', 'return_book_1') + // end::trigger_artifact[] then: Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: @@ -104,7 +108,9 @@ class CamelStubRunnerSpec extends Specification { def 'should trigger messages by running all triggers'() { when: + // tag::trigger_all[] stubFinder.trigger() + // end::trigger_all[] then: Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) and: From a46391ee383f32f00dcfbb52b605400fee04abc8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 08:58:20 +0200 Subject: [PATCH 531/719] Added Integration and Stream docs --- docs/src/docs/asciidoc/messaging.adoc | 1 + docs/src/docs/asciidoc/stubrunner_msg.adoc | 6 +- .../stub-runner-messaging-camel/README.adoc | 9 + .../README.adoc | 154 ++++++++++++++++++ .../IntegrationStubRunnerSpec.groovy | 61 +++++++ .../stub-runner-messaging-stream/README.adoc | 146 +++++++++++++++++ .../stream/StreamStubRunnerSpec.groovy | 61 +++++++ 7 files changed, 437 insertions(+), 1 deletion(-) create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc index 3c0f5eb50f..ed25a833dc 100644 --- a/docs/src/docs/asciidoc/messaging.adoc +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -34,6 +34,7 @@ The `accurest-messaging-core` module contains 3 main interfaces: - AccurestMessage - describes a message received / sent to a channel / queue / topic etc. - AccurestMessageBuilder - describes how to build a message - AccurestMessaging - class that allows you to build, send and receive messages +- AccurestFilter - interface to filter out the messages that do not follow the pattern from the DSL In the generated test the `AccurestMessaging` is injected via `@Inject` annotation thus you can use other injection frameworks than Spring. diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc index 617ab903ee..2a027ba005 100644 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -50,4 +50,8 @@ include::../../../../stub-runner/stub-runner/src/main/groovy/io/codearte/accures For convenience the `StubFinder` interface extends `StubTrigger` so it's enough to use only one in your tests. -include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc[] \ No newline at end of file +include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc[] + +include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc[] + +include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc[] \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc index ae95b36c7c..7fdfc0011d 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc @@ -7,6 +7,15 @@ Accurest Stub Runner's messaging module gives you an easy way to integrate with For the provided artifacts it will automatically download the stubs and register the required routes. +==== Adding it to the project + +To use it you have to add the following dependency to your project (example for Gradle): + +[source,groovy,indent=0] +---- +testCompile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}" +---- + ==== Examples ===== Stubs structure diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc new file mode 100644 index 0000000000..8e87674940 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc @@ -0,0 +1,154 @@ +:input_name: input +:output_name: output + +=== Stub Runner Messaging Integration + +Accurest Stub Runner's messaging module gives you an easy way to integrate with Spring Integration. +For the provided artifacts it will automatically download the stubs and register the required +routes. + +==== Adding it to the project + +To use it you have to add the following dependency to your project (example for Gradle): + +[source,groovy,indent=0] +---- +testCompile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}" +---- + +==== Examples + +===== Stubs structure + +Let us assume that we have the following Maven repository with a deployed stubs for the +`integrationService` application. + +[source,bash,indent=0] +---- +└── .m2 + └── repository + └── io + └── codearte + └── accurest + └── stubs + └── integrationService + ├── 0.0.1-SNAPSHOT + │   ├── integrationService-0.0.1-SNAPSHOT.pom + │   ├── integrationService-0.0.1-SNAPSHOT-stubs.jar + │   └── maven-metadata-local.xml + └── maven-metadata-local.xml +---- + +And the stubs contain the following structure: + +[source,bash,indent=0] +---- +├── META-INF +│   └── MANIFEST.MF +└── repository + ├── accurest + │   ├── bookDeleted.groovy + │   ├── bookReturned1.groovy + │   └── bookReturned2.groovy + └── mappings +---- + +Let's consider the following contracts (let' number it with *1*): + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=sample_dsl,indent=0] +---- + +and number *2* + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] +---- + +and the following Spring Integration Route: + +[source,xml] +---- +include::src/test/resources/integration-context.xml[] +---- + + +===== Scenario 1 (no input message) + +So as to trigger a message via the `return_book_1` label we'll use the `StubTiggerer` interface as follows + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger,indent=0] +---- + +Next we'll want to listen to the output of the message sent to `{output_name}` + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] +---- + +And the received message would pass the following assertions + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] +---- + +===== Scenario 2 (output triggered by input) + +Since the route is set for you it's enough to just send a message to the `{output_name}` destination. + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_send,indent=0] +---- + +Next we'll want to listen to the output of the message sent to `{output_name}` + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_receive,indent=0] +---- + +And the received message would pass the following assertions + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_receive_message,indent=0] +---- + +===== Custom triggers + +`StubTrigger` gives you the following options to trigger a message: + +===== Trigger by label + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger,indent=0] +---- + +===== Trigger by group and artifact ids + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] +---- + +===== Trigger by artifact ids + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] +---- + +===== Trigger all messages + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_all,indent=0] +---- \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy index f9e81b6846..bd00d789eb 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.stubrunner.messaging.integration import groovy.json.JsonOutput import groovy.json.JsonSlurper +import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.messaging.AccurestMessage import io.codearte.accurest.messaging.AccurestMessaging import io.codearte.accurest.stubrunner.StubFinder @@ -31,29 +32,43 @@ class IntegrationStubRunnerSpec extends Specification { def 'should download the stub and register a route for it'() { when: + // tag::client_send[] messaging.send(new BookReturned('foo'), [sample: 'header'], 'input') + // end::client_send[] then: + // tag::client_receive[] AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + // end::client_receive[] and: + // tag::client_receive_message[] receivedMessage != null assertJsons(receivedMessage.payload) receivedMessage.headers.get('BOOK-NAME') == 'foo' + // end::client_receive_message[] } def 'should trigger a message by label'() { when: + // tag::client_trigger[] stubFinder.trigger('return_book_1') + // end::client_trigger[] then: + // tag::client_trigger_receive[] AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + // end::client_trigger_receive[] and: + // tag::client_trigger_message[] receivedMessage != null assertJsons(receivedMessage.payload) receivedMessage.headers.get('BOOK-NAME') == 'foo' + // end::client_trigger_message[] } def 'should trigger a label for the existing groupId:artifactId'() { when: + // tag::trigger_group_artifact[] stubFinder.trigger('io.codearte.accurest.stubs:integrationService', 'return_book_1') + // end::trigger_group_artifact[] then: AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') and: @@ -64,7 +79,9 @@ class IntegrationStubRunnerSpec extends Specification { def 'should trigger a label for the existing artifactId'() { when: + // tag::trigger_artifact[] stubFinder.trigger('integrationService', 'return_book_1') + // end::trigger_artifact[] then: AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') and: @@ -95,7 +112,9 @@ class IntegrationStubRunnerSpec extends Specification { def 'should trigger messages by running all triggers'() { when: + // tag::trigger_all[] stubFinder.trigger() + // end::trigger_all[] then: AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') and: @@ -111,4 +130,46 @@ class IntegrationStubRunnerSpec extends Specification { return json.bookName == 'foo' } + GroovyDsl dsl = + // tag::sample_dsl[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'return_book_1' + input { + triggeredBy('bookReturnedTriggered()') + } + outputMessage { + sentTo('jms:output') + body('''{ "bookName" : "foo" }''') + headers { + header('BOOK-NAME', 'foo') + } + } + } + // end::sample_dsl[] + + GroovyDsl dsl2 = + // tag::sample_dsl_2[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'return_book_2' + input { + messageFrom('jms:input') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + } + outputMessage { + sentTo('jms:output') + body([ + bookName: 'foo' + ]) + headers { + header('BOOK-NAME', 'foo') + } + } + } + // end::sample_dsl_2[] + } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc new file mode 100644 index 0000000000..6936bef94e --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc @@ -0,0 +1,146 @@ +:input_name: input +:output_name: output + +=== Stub Runner Messaging Stream + +Accurest Stub Runner's messaging module gives you an easy way to integrate with Spring Stream. +For the provided artifacts it will automatically download the stubs and register the required +routes. + +==== Adding it to the project + +To use it you have to add the following dependency to your project (example for Gradle): + +[source,groovy,indent=0] +---- +testCompile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}" +---- + +==== Examples + +===== Stubs structure + +Let us assume that we have the following Maven repository with a deployed stubs for the +`streamService` application. + +[source,bash,indent=0] +---- +└── .m2 + └── repository + └── io + └── codearte + └── accurest + └── stubs + └── streamService + ├── 0.0.1-SNAPSHOT + │   ├── streamService-0.0.1-SNAPSHOT.pom + │   ├── streamService-0.0.1-SNAPSHOT-stubs.jar + │   └── maven-metadata-local.xml + └── maven-metadata-local.xml +---- + +And the stubs contain the following structure: + +[source,bash,indent=0] +---- +├── META-INF +│   └── MANIFEST.MF +└── repository + ├── accurest + │   ├── bookDeleted.groovy + │   ├── bookReturned1.groovy + │   └── bookReturned2.groovy + └── mappings +---- + +Let's consider the following contracts (let' number it with *1*): + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=sample_dsl,indent=0] +---- + +and number *2* + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] +---- + +===== Scenario 1 (no input message) + +So as to trigger a message via the `return_book_1` label we'll use the `StubTiggerer` interface as follows + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger,indent=0] +---- + +Next we'll want to listen to the output of the message sent to `{output_name}` + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] +---- + +And the received message would pass the following assertions + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] +---- + +===== Scenario 2 (output triggered by input) + +Since the route is set for you it's enough to just send a message to the `{output_name}` destination. + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_send,indent=0] +---- + +Next we'll want to listen to the output of the message sent to `{output_name}` + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_receive,indent=0] +---- + +And the received message would pass the following assertions + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_receive_message,indent=0] +---- + +===== Custom triggers + +`StubTrigger` gives you the following options to trigger a message: + +===== Trigger by label + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger,indent=0] +---- + +===== Trigger by group and artifact ids + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] +---- + +===== Trigger by artifact ids + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] +---- + +===== Trigger all messages + +[source,groovy] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_all,indent=0] +---- \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy index ffe676551c..e521228eda 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.stubrunner.messaging.stream import groovy.json.JsonOutput import groovy.json.JsonSlurper +import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.messaging.AccurestMessage import io.codearte.accurest.messaging.AccurestMessaging import io.codearte.accurest.stubrunner.StubFinder @@ -28,29 +29,43 @@ class StreamStubRunnerSpec extends Specification { def 'should download the stub and register a route for it'() { when: + // tag::client_send[] messaging.send(new BookReturned('foo'), [sample: 'header'], 'input') + // end::client_send[] then: + // tag::client_receive[] AccurestMessage receivedMessage = messaging.receiveMessage('output') + // end::client_receive[] and: + // tag::client_receive_message[] receivedMessage != null assertJsons(receivedMessage.payload) receivedMessage.headers.get('BOOK-NAME') == 'foo' + // end::client_receive_message[] } def 'should trigger a message by label'() { when: + // tag::client_trigger[] stubFinder.trigger('return_book_1') + // end::client_trigger[] then: + // tag::client_trigger_receive[] AccurestMessage receivedMessage = messaging.receiveMessage('output') + // end::client_trigger_receive[] and: + // tag::client_trigger_message[] receivedMessage != null assertJsons(receivedMessage.payload) receivedMessage.headers.get('BOOK-NAME') == 'foo' + // end::client_trigger_message[] } def 'should trigger a label for the existing groupId:artifactId'() { when: + // tag::trigger_group_artifact[] stubFinder.trigger('io.codearte.accurest.stubs:streamService', 'return_book_1') + // end::trigger_group_artifact[] then: AccurestMessage receivedMessage = messaging.receiveMessage('output') and: @@ -61,7 +76,9 @@ class StreamStubRunnerSpec extends Specification { def 'should trigger a label for the existing artifactId'() { when: + // tag::trigger_artifact[] stubFinder.trigger('streamService', 'return_book_1') + // end::trigger_artifact[] then: AccurestMessage receivedMessage = messaging.receiveMessage('output') and: @@ -92,7 +109,9 @@ class StreamStubRunnerSpec extends Specification { def 'should trigger messages by running all triggers'() { when: + // tag::trigger_all[] stubFinder.trigger() + // end::trigger_all[] then: AccurestMessage receivedMessage = messaging.receiveMessage('output') and: @@ -108,4 +127,46 @@ class StreamStubRunnerSpec extends Specification { return json.bookName == 'foo' } + GroovyDsl dsl = + // tag::sample_dsl[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'return_book_1' + input { + triggeredBy('bookReturnedTriggered()') + } + outputMessage { + sentTo('jms:output') + body('''{ "bookName" : "foo" }''') + headers { + header('BOOK-NAME', 'foo') + } + } + } + // end::sample_dsl[] + + GroovyDsl dsl2 = + // tag::sample_dsl_2[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'return_book_2' + input { + messageFrom('jms:input') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + } + outputMessage { + sentTo('jms:output') + body([ + bookName: 'foo' + ]) + headers { + header('BOOK-NAME', 'foo') + } + } + } + // end::sample_dsl_2[] + } From 8007508e19c0e5dad4d16daefc81775a9584dec7 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 09:01:20 +0200 Subject: [PATCH 532/719] Fixed the link to Maven plugin --- docs/src/docs/asciidoc/messaging.adoc | 2 +- docs/src/docs/asciidoc/stubrunner.adoc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc index ed25a833dc..3653f4fc67 100644 --- a/docs/src/docs/asciidoc/messaging.adoc +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -147,4 +147,4 @@ include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/sc ==== Maven Setup -Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) +Example of Maven can be found in the https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar[Accurest Maven Plugin README] diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index c6efd38570..b429b2d4f8 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -20,11 +20,11 @@ include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/sc ==== Maven -Example of Maven can be found in the [AccuREST Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) +Example of Maven can be found in the [Accurest Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) === Modules -AccuREST comes with a new structure of modules +Accurest comes with a new structure of modules [source,indent=0] ---- From 91dc5764360515b634477b486374375c9e1d73c6 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 12:01:28 +0200 Subject: [PATCH 533/719] Updated docs --- docs/src/docs/asciidoc/stubrunner_msg.adoc | 30 ++++++++++++++ .../stubrunner/junit/AccurestRule.java | 6 +-- .../stub-runner-messaging-camel/README.adoc | 29 ++------------ .../camel/CamelStubRunnerSpec.groovy | 40 +++++++++++++++++++ .../MessageNotMatchingException.groovy | 12 ++++++ 5 files changed, 88 insertions(+), 29 deletions(-) create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MessageNotMatchingException.groovy diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc index 2a027ba005..788cba9990 100644 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -50,6 +50,36 @@ include::../../../../stub-runner/stub-runner/src/main/groovy/io/codearte/accures For convenience the `StubFinder` interface extends `StubTrigger` so it's enough to use only one in your tests. +`StubTrigger` gives you the following options to trigger a message: + +===== Trigger by label + +[source,groovy] +---- +include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger,indent=0] +---- + +===== Trigger by group and artifact ids + +[source,groovy] +---- +include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] +---- + +===== Trigger by artifact ids + +[source,groovy] +---- +include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] +---- + +===== Trigger all messages + +[source,groovy] +---- +include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_all,indent=0] +---- + include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc[] include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc[] diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index c4ecac01bf..85a8768e61 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -171,16 +171,16 @@ public class AccurestRule implements TestRule, StubFinder { @Override public void trigger(String ivyNotation, String labelName) { - throw new UnsupportedOperationException("Feature not yet supported"); + stubFinder.trigger(ivyNotation, labelName); } @Override public void trigger(String labelName) { - throw new UnsupportedOperationException("Feature not yet supported"); + stubFinder.trigger(labelName); } @Override public void trigger() { - throw new UnsupportedOperationException("Feature not yet supported"); + stubFinder.trigger(); } } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc index 7fdfc0011d..fb579dc507 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc @@ -113,34 +113,11 @@ And the received message would pass the following assertions include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_receive_message,indent=0] ---- -===== Custom triggers +===== Scenario 3 (input with no output) -`StubTrigger` gives you the following options to trigger a message: - -===== Trigger by label +Since the route is set for you it's enough to just send a message to the `{output_name}` destination. [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger,indent=0] +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] ---- - -===== Trigger by group and artifact ids - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] ----- - -===== Trigger by artifact ids - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] ----- - -===== Trigger all messages - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_all,indent=0] ----- \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy index ef0aae52db..dee3c93b00 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -119,6 +119,24 @@ class CamelStubRunnerSpec extends Specification { receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } + def 'should trigger a label with no output message'() { + when: + // tag::trigger_no_output[] + camelContext.createProducerTemplate().sendBodyAndHeaders('jms:delete', new BookReturned('foo'), [sample: 'header']) + // end::trigger_no_output[] + then: + noExceptionThrown() + } + + def 'should not trigger a message that does not match input'() { + when: + camelContext.createProducerTemplate().sendBodyAndHeaders('jms:input', new BookReturned('notmatching'), [wrong: 'header_value']) + then: + Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 100) + and: + receivedMessage == null + } + private boolean assertThatBodyContainsBookNameFoo(Object payload) { String objectAsString = payload instanceof String ? payload : JsonOutput.toJson(payload) @@ -126,6 +144,11 @@ class CamelStubRunnerSpec extends Specification { return json.bookName == 'foo' } + def setup() { + // ensure that message were taken from the queue + camelContext.createConsumerTemplate().receive('jms:output', 100) + } + @Bean ActiveMQComponent activeMQComponent(@Value('${activemq.url:vm://localhost?broker.persistent=false}') String url) { return new ActiveMQComponent(brokerURL: url) @@ -172,4 +195,21 @@ class CamelStubRunnerSpec extends Specification { } } // end::sample_dsl_2[] + + GroovyDsl dsl3 = + // tag::sample_dsl_3[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'delete_book' + input { + messageFrom('jms:delete') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + assertThat('bookWasDeleted()') + } + } + // end::sample_dsl_3[] } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MessageNotMatchingException.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MessageNotMatchingException.groovy new file mode 100644 index 0000000000..62368d75bf --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MessageNotMatchingException.groovy @@ -0,0 +1,12 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.InheritConstructors + +/** + * Exception thrown when message is not matched + * + * @author Marcin Grzejszczak + */ +@InheritConstructors +class MessageNotMatchingException extends RuntimeException { +} From 2d618584800cd35db2f83d232dbea094955c05de Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 12:03:55 +0200 Subject: [PATCH 534/719] Updated docs --- docs/src/docs/asciidoc/stubrunner_msg.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc index 788cba9990..2548584162 100644 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -52,7 +52,7 @@ For convenience the `StubFinder` interface extends `StubTrigger` so it's enough `StubTrigger` gives you the following options to trigger a message: -===== Trigger by label +==== Trigger by label [source,groovy] ---- From 496da246865f0a75c9232f5ad55494696601d02d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 18:20:39 +0200 Subject: [PATCH 535/719] Updated impl to support in-only scenario --- .../camel/AccurestCamelMessageBuilder.java | 10 ++-- .../AccurestIntegrationMessageBuilder.java | 10 ++-- .../stream/AccurestStreamMessageBuilder.java | 10 ++-- .../messaging/stream/StreamMessage.java | 3 -- docs/src/docs/asciidoc/index.adoc | 12 +++-- .../camel/CamelStubRunnerSpec.groovy | 10 ++-- .../StubRunnerIntegrationConfiguration.groovy | 23 ++++++--- .../StubRunnerIntegrationTransformer.groovy | 3 ++ .../IntegrationStubRunnerSpec.groovy | 40 +++++++++++++++ .../StubRunnerStreamConfiguration.groovy | 31 ++++++++---- .../stream/StubRunnerStreamTransformer.groovy | 3 ++ .../stream/StreamStubRunnerSpec.groovy | 50 ++++++++++++++++--- 12 files changed, 163 insertions(+), 42 deletions(-) diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java index 94b808d8b5..58f5609fd6 100644 --- a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java +++ b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java @@ -1,11 +1,12 @@ package io.codearte.accurest.messaging.camel; -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; +import java.util.Map; + import org.apache.camel.Message; import org.apache.camel.impl.DefaultMessage; -import java.util.Map; +import io.codearte.accurest.messaging.AccurestMessage; +import io.codearte.accurest.messaging.AccurestMessageBuilder; /** * @author Marcin Grzejszczak @@ -22,6 +23,9 @@ public class AccurestCamelMessageBuilder implements AccurestMessageBuilder create(Message message) { + if (message == null) { + return null; + } return new CamelMessage<>(message); } } diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java index 9b6b945570..20dc976523 100644 --- a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java +++ b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java @@ -1,12 +1,13 @@ package io.codearte.accurest.messaging.integration; -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; +import java.util.Map; + import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; -import java.util.Map; +import io.codearte.accurest.messaging.AccurestMessage; +import io.codearte.accurest.messaging.AccurestMessageBuilder; /** * @author Marcin Grzejszczak @@ -20,6 +21,9 @@ public class AccurestIntegrationMessageBuilder implements AccurestMessageBuil @Override public AccurestMessage> create(Message message) { + if (message == null) { + return null; + } return new IntegrationMessage<>(message); } } diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java index e6abccdd89..7f4d994e0a 100644 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java @@ -1,12 +1,13 @@ package io.codearte.accurest.messaging.stream; -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; +import java.util.Map; + import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; import org.springframework.messaging.support.MessageBuilder; -import java.util.Map; +import io.codearte.accurest.messaging.AccurestMessage; +import io.codearte.accurest.messaging.AccurestMessageBuilder; /** * @author Marcin Grzejszczak @@ -20,6 +21,9 @@ public class AccurestStreamMessageBuilder implements AccurestMessageBuilder> create(Message message) { + if (message == null) { + return null; + } return new StreamMessage<>(message); } } diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java index 8bc2a9ecb0..9f0a3ba694 100644 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java @@ -13,9 +13,6 @@ public class StreamMessage implements AccurestMessage> { private final Message delegate; public StreamMessage(Message delegate) { - if (delegate == null) { - throw new IllegalArgumentException("Message can't be null"); - } this.delegate = delegate; } diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 039ee5fb36..a34b2c266d 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,12 +1,16 @@ -Welcome to the Accurest Wiki! +ACCUREST +==================== +Marcin Grzejszczak, Jakub Kubrynski, Olga Maciaszek-Sharma, Mariusz Smykuła +:doctype: book -Please follow to the Introduction page to start your journey with Consumer Driven Contracts in JVM == Introduction -Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: +Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with +__REST Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: -* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by Accurest. +* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, +test data is produced by Accurest. * Acceptance tests (in Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by Accurest. Accurest moves TDD to the level of software architecture. diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy index dee3c93b00..fecb9fa70a 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -28,6 +28,11 @@ class CamelStubRunnerSpec extends Specification { @Autowired StubFinder stubFinder @Autowired CamelContext camelContext + def setup() { + // ensure that message were taken from the queue + camelContext.createConsumerTemplate().receive('jms:output', 100) + } + def 'should download the stub and register a route for it'() { when: // tag::client_send[] @@ -144,11 +149,6 @@ class CamelStubRunnerSpec extends Specification { return json.bookName == 'foo' } - def setup() { - // ensure that message were taken from the queue - camelContext.createConsumerTemplate().receive('jms:output', 100) - } - @Bean ActiveMQComponent activeMQComponent(@Value('${activemq.url:vm://localhost?broker.persistent=false}') String url) { return new ActiveMQComponent(brokerURL: url) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy index 24199906fc..25106d5f3d 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.stubrunner.messaging.integration +import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.stubrunner.BatchStubRunner import io.codearte.accurest.stubrunner.StubConfiguration @@ -9,8 +10,9 @@ import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.integration.dsl.FilterEndpointSpec import org.springframework.integration.dsl.GenericEndpointSpec -import org.springframework.integration.dsl.IntegrationFlow +import org.springframework.integration.dsl.IntegrationFlowBuilder import org.springframework.integration.dsl.IntegrationFlows +import org.springframework.messaging.Message import org.springframework.stereotype.Service /** * Spring Integration configuration that iterates over the downloaded Groovy DSLs @@ -19,6 +21,7 @@ import org.springframework.stereotype.Service * @author Marcin Grzejszczak */ @Configuration +@CompileStatic class StubRunnerIntegrationConfiguration { @Bean @@ -26,14 +29,17 @@ class StubRunnerIntegrationConfiguration { Map> accurestContracts = batchStubRunner.accurestContracts accurestContracts.each { StubConfiguration key, Collection value -> String name = "${key.groupId}_${key.artifactId}" - value.findAll { it?.input?.messageFrom && it?.outputMessage?.sentTo }.each { GroovyDsl dsl -> + value.findAll { it?.input?.messageFrom }.each { GroovyDsl dsl -> String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" - IntegrationFlow integrationFlow = IntegrationFlows.from(dsl.input.messageFrom) + IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom) .filter(new StubRunnerIntegrationMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) .transform(new StubRunnerIntegrationTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) - .channel(dsl.outputMessage.sentTo) - .get() - beanFactory.initializeBean(integrationFlow, flowName) + if (dsl.outputMessage) { + builder = builder.channel(dsl.outputMessage.sentTo) + } else { + builder = builder.handle(new DummyMessageHandler(), "handle") + } + beanFactory.initializeBean(builder.get(), flowName) beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); } @@ -41,6 +47,11 @@ class StubRunnerIntegrationConfiguration { return new FlowRegistrar() } + @CompileStatic + private static class DummyMessageHandler { + void handle(Message message) {} + } + @Service static class FlowRegistrar {} } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy index e90cab0ca3..2bb6fa19ca 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy @@ -22,6 +22,9 @@ class StubRunnerIntegrationTransformer implements GenericTransformer, @Override Message transform(Message source) { + if (!groovyDsl.outputMessage) { + return source + } String payload = BodyAsString.extractClientValueFrom(groovyDsl.outputMessage.body) Map headers = groovyDsl.outputMessage.headers.asStubSideMap() return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy index bd00d789eb..8f071f5bb1 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy @@ -30,6 +30,11 @@ class IntegrationStubRunnerSpec extends Specification { @Autowired StubFinder stubFinder @Autowired AccurestMessaging messaging + def setup() { + // ensure that message were taken from the queue + messaging.receiveMessage('outputTest', 100, TimeUnit.MILLISECONDS) + } + def 'should download the stub and register a route for it'() { when: // tag::client_send[] @@ -123,6 +128,24 @@ class IntegrationStubRunnerSpec extends Specification { receivedMessage.headers.get('BOOK-NAME') == 'foo' } + def 'should trigger a label with no output message'() { + when: + // tag::trigger_no_output[] + messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete') + // end::trigger_no_output[] + then: + noExceptionThrown() + } + + def 'should not trigger a message that does not match input'() { + when: + messaging.send(new BookReturned('not_matching'), [wrong: 'header_value'], 'input') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('outputTest', 100, TimeUnit.MILLISECONDS) + and: + receivedMessage == null + } + private boolean assertJsons(Object payload) { String objectAsString = payload instanceof String ? payload : JsonOutput.toJson(payload) @@ -172,4 +195,21 @@ class IntegrationStubRunnerSpec extends Specification { } // end::sample_dsl_2[] + GroovyDsl dsl3 = + // tag::sample_dsl_3[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'delete_book' + input { + messageFrom('jms:delete') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + assertThat('bookWasDeleted()') + } + } + // end::sample_dsl_3[] + } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy index 7520883395..3d3210ff7e 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.stubrunner.messaging.stream +import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.stubrunner.BatchStubRunner import io.codearte.accurest.stubrunner.StubConfiguration @@ -11,8 +12,9 @@ import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.integration.dsl.FilterEndpointSpec import org.springframework.integration.dsl.GenericEndpointSpec -import org.springframework.integration.dsl.IntegrationFlow +import org.springframework.integration.dsl.IntegrationFlowBuilder import org.springframework.integration.dsl.IntegrationFlows +import org.springframework.messaging.Message import org.springframework.messaging.MessageChannel import org.springframework.stereotype.Service /** @@ -23,6 +25,7 @@ import org.springframework.stereotype.Service */ @Configuration @EnableBinding +@CompileStatic class StubRunnerStreamConfiguration { @Bean @@ -30,23 +33,33 @@ class StubRunnerStreamConfiguration { Map> accurestContracts = batchStubRunner.accurestContracts accurestContracts.each { StubConfiguration key, Collection value -> String name = "${key.groupId}_${key.artifactId}" - value.findAll { it?.input?.messageFrom && it?.outputMessage?.sentTo }.each { GroovyDsl dsl -> + value.findAll { it?.input?.messageFrom }.each { GroovyDsl dsl -> String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" - IntegrationFlow integrationFlow = IntegrationFlows.from(dsl.input.messageFrom) - .filter(new StubRunnerStreamMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) - .transform(new StubRunnerStreamTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) - .channel(dsl.outputMessage.sentTo) - .get() - beanFactory.initializeBean(integrationFlow, flowName) + IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom) + .filter(new StubRunnerStreamMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) + .transform(new StubRunnerStreamTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) + if (dsl.outputMessage) { + builder = builder.channel(dsl.outputMessage.sentTo) + } else { + builder = builder.handle(new DummyMessageHandler(), "handle") + } + beanFactory.initializeBean(builder.get(), flowName) beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); channelBindingService.bindConsumer(beanFactory.getBean(dsl.input.messageFrom, MessageChannel.class), dsl.input.messageFrom) - channelBindingService.bindProducer(beanFactory.getBean(dsl.outputMessage.sentTo, MessageChannel.class), dsl.outputMessage.sentTo) + if (dsl.outputMessage) { + channelBindingService.bindProducer(beanFactory.getBean(dsl.outputMessage.sentTo, MessageChannel.class), dsl.outputMessage.sentTo) + } } } return new FlowRegistrar() } + @CompileStatic + private static class DummyMessageHandler { + void handle(Message message) {} + } + @Service static class FlowRegistrar {} } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy index 3129f70ace..c8e61b665f 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy @@ -22,6 +22,9 @@ class StubRunnerStreamTransformer implements GenericTransformer, Mess @Override Message transform(Message source) { + if (!groovyDsl.outputMessage) { + return source + } String payload = BodyAsString.extractClientValueFrom(groovyDsl.outputMessage.body) Map headers = groovyDsl.outputMessage.headers.asStubSideMap() return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy index e521228eda..72177a855e 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy @@ -27,6 +27,11 @@ class StreamStubRunnerSpec extends Specification { @Autowired StubFinder stubFinder @Autowired AccurestMessaging messaging + def setup() { + // ensure that message were taken from the queue + messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + } + def 'should download the stub and register a route for it'() { when: // tag::client_send[] @@ -91,20 +96,18 @@ class StreamStubRunnerSpec extends Specification { given: stubFinder.trigger('missing label') when: - messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + AccurestMessage message = messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) then: - RuntimeException e = thrown(RuntimeException) - e.cause.message.contains("Message can't be null") + message == null } def 'should not run any wrong trigger when missing label and artifactid is passed'() { given: stubFinder.trigger('some:service', 'return_book_1') when: - messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + AccurestMessage message = messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) then: - RuntimeException e = thrown(RuntimeException) - e.cause.message.contains("Message can't be null") + message == null } def 'should trigger messages by running all triggers'() { @@ -120,6 +123,24 @@ class StreamStubRunnerSpec extends Specification { receivedMessage.headers.get('BOOK-NAME') == 'foo' } + def 'should trigger a label with no output message'() { + when: + // tag::trigger_no_output[] + messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete') + // end::trigger_no_output[] + then: + noExceptionThrown() + } + + def 'should not trigger a message that does not match input'() { + when: + messaging.send(new BookReturned('not_matching'), [wrong: 'header_value'], 'input') + then: + AccurestMessage receivedMessage = messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + and: + receivedMessage == null + } + private boolean assertJsons(Object payload) { String objectAsString = payload instanceof String ? payload : JsonOutput.toJson(payload) @@ -169,4 +190,21 @@ class StreamStubRunnerSpec extends Specification { } // end::sample_dsl_2[] + GroovyDsl dsl3 = + // tag::sample_dsl_3[] + io.codearte.accurest.dsl.GroovyDsl.make { + label 'delete_book' + input { + messageFrom('jms:delete') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + assertThat('bookWasDeleted()') + } + } + // end::sample_dsl_3[] + } From b82f697bb6ee364eb80b0ab5da0c2626ef94c50a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 18:24:09 +0200 Subject: [PATCH 536/719] Updated docs --- .../README.adoc | 29 ++----------------- .../stub-runner-messaging-stream/README.adoc | 29 ++----------------- 2 files changed, 6 insertions(+), 52 deletions(-) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc index 8e87674940..0e935fe739 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc @@ -121,34 +121,11 @@ And the received message would pass the following assertions include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_receive_message,indent=0] ---- -===== Custom triggers +===== Scenario 3 (input with no output) -`StubTrigger` gives you the following options to trigger a message: - -===== Trigger by label +Since the route is set for you it's enough to just send a message to the `{input_name}` destination. [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger,indent=0] +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] ---- - -===== Trigger by group and artifact ids - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] ----- - -===== Trigger by artifact ids - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] ----- - -===== Trigger all messages - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_all,indent=0] ----- \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc index 6936bef94e..cda8a5a32b 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc @@ -113,34 +113,11 @@ And the received message would pass the following assertions include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_receive_message,indent=0] ---- -===== Custom triggers +===== Scenario 3 (input with no output) -`StubTrigger` gives you the following options to trigger a message: - -===== Trigger by label +Since the route is set for you it's enough to just send a message to the `{output_name}` destination. [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger,indent=0] +include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] ---- - -===== Trigger by group and artifact ids - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] ----- - -===== Trigger by artifact ids - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] ----- - -===== Trigger all messages - -[source,groovy] ----- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_all,indent=0] ----- \ No newline at end of file From 29cd44d391951beaae594325ccacfc8e8ee8101a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 18:27:45 +0200 Subject: [PATCH 537/719] Fixed docs --- docs/src/docs/asciidoc/index.adoc | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index a34b2c266d..df53f371ab 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,16 +1,10 @@ -ACCUREST -==================== -Marcin Grzejszczak, Jakub Kubrynski, Olga Maciaszek-Sharma, Mariusz Smykuła -:doctype: book - +Welcome to the Accurest Wiki! == Introduction -Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with -__REST Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: +Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: -* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, -test data is produced by Accurest. +* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by Accurest. * Acceptance tests (in Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by Accurest. Accurest moves TDD to the level of software architecture. From ec05acddbbff350ece3657ae4c27f086f8830d46 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 18:35:56 +0200 Subject: [PATCH 538/719] Reordered docs --- docs/src/docs/asciidoc/contract.adoc | 461 ++++++++++++++++++ docs/src/docs/asciidoc/index.adoc | 574 +---------------------- docs/src/docs/asciidoc/introduction.adoc | 88 ++++ docs/src/docs/asciidoc/messaging.adoc | 2 - docs/src/docs/asciidoc/rest.adoc | 23 +- 5 files changed, 575 insertions(+), 573 deletions(-) create mode 100644 docs/src/docs/asciidoc/contract.adoc create mode 100644 docs/src/docs/asciidoc/introduction.adoc diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/docs/asciidoc/contract.adoc new file mode 100644 index 0000000000..7e2d7f7c97 --- /dev/null +++ b/docs/src/docs/asciidoc/contract.adoc @@ -0,0 +1,461 @@ +== Contract DSL + +Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself. + +Let's look at full example of a contract definition. + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'POST' + urlPath('/users') { + queryParameters { + parameter 'limit': 100 + parameter 'offset': containing("1") + parameter 'filter': "email" + } + } + headers { + header 'Content-Type': 'application/json' + } + body '''{ "login" : "john", "name": "John The Contract" }''' + } + response { + status 200 + headers { + header 'Location': '/users/john' + } + } +} +---- + +Not all features of the DSL are used in example above. If you didn't find what you are looking for, please check next paragraphs on this page. + +> You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. + +=== Top-Level Elements + +Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + // Definition of HTTP request part of the contract + // (this can be a valid request or invalid depending + // on type of contract being specified). + request { + ... + } + + // Definition of HTTP response part of the contract + // (a service implementing this contract should respond + // with following response after receiving request + // specified in "request" part above). + response { + ... + } + + // Contract priority, which can be used for overriding + // contracts (1 is highest). Priority is optional. + priority 1 +} +---- + +=== Request + +HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of Accurest contract. + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + // HTTP request method (GET/POST/PUT/DELETE). + method 'GET' + + // Path component of request URL is specified as follows. + urlPath('/users') + } + + response { + ... + } +} +---- + +It is possible to specify whole `url` instead of just path, but `urlPath` is the recommended way as it makes the tests **host-independent**. + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'GET' + + // Specifying `url` and `urlPath` in one contract is illegal. + url('http://localhost:8888/users') + } + + response { + ... + } +} +---- + +Request may contain **query parameters**, which are specified in a closure nested in a call to `urlPath` or `url`. + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + ... + + urlPath('/users') { + + // Each parameter is specified in form + // `'paramName' : paramValue` where parameter value + // may be a simple literal or one of matcher functions, + // all of which are used in this example. + queryParameters { + + // If a simple literal is used as value + // default matcher function is used (equalTo) + parameter 'limit': 100 + + // `equalTo` function simply compares passed value + // using identity operator (==). + parameter 'filter': equalTo("email") + + // `containing` function matches strings + // that contains passed substring. + parameter 'gender': containing("[mf]") + + // `matching` function tests parameter + // against passed regular expression. + parameter 'offset': matching("[0-9]+") + + // `notMatching` functions tests if parameter + // does not match passed regular expression. + parameter 'loginStartsWith': notMatching(".{0,2}") + } + } + + ... + } + + response { + ... + } +} +---- + +It may contain additional **request headers**... + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + ... + + // Each header is added in form `'Header-Name' : 'Header-Value'`. + headers { + header 'Content-Type': 'application/json' + } + + ... + } + + response { + ... + } +} +---- + +...and a **request body**. + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + ... + + // JSON and XML formats of request body are supported. + // Format will be determined from a header or body's content. + body '''{ "login" : "john", "name": "John The Contract" }''' + } + + response { + ... + } +} +---- + +**Body's format** can also be specified explicitly by invoking one of format functions. + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + ... + + // In this case body will be formatted as XML. + body equalToXml( + '''johnJohn The Contract''' + ) + } + + response { + ... + } +} +---- + +=== Response + +Minimal response must contain **HTTP status code**. + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + ... + } + response { + // Status code sent by the server + // in response to request specified above. + status 200 + } +} +---- + +Besides status response may contain **headers** and **body**, which are specified the same way as in the request (see previous paragraph). + +=== Regular expressions +You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both for your test and your server side tests. + + Please see the example below: + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl groovyDsl == GroovyDsl.make { + request { + method('GET') + url $(client(~/\/[0-9]{2}/), server('/12')) + } + response { + status 200 + body( + id: value( + client('123'), + server(regex('[0-9]+')) + ), + surname: $( + client('Kowalsky'), + server('Lewandowski') + ), + name: 'Jan', + created: $(client('2014-02-02 12:23:43'), server({ currentDate(it) })) + correlationId: value(client('5d1f9fef-e0dc-4f3d-a7e4-72d2220dd827'), + server(regex('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') + ) + ) + headers { + header 'Content-Type': 'text/plain' + } + } +} +---- + +=== Passing optional parameters + +It is possible to provide optional parameters in your contract. It's only possible to have optional parameter for the: + +- __STUB__ side of the Request +- __TEST__ side of the Response + +Example: + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: value(stub("123123"), test(optional("123123"))), + message: "User not found by email == [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) + } +} +---- + +By wrapping a part of the body with the `optional()` method you are in fact creating a regular expression that should be present 0 or more times. + +That way for the example above the following test would be generated: + +[source,groovy,indent=0] +---- + given: + def request == given() + .header('Content-Type', 'application/json') + .body('{"email":"abc@abc.com","callback_url":"http://partners.com"}') + + when: + def response == given().spec(request) + .post("/users/password") + + then: + response.statusCode === 404 + response.header('Content-Type') === 'application/json' + and: + DocumentContext parsedJson == JsonPath.parse(response.body.asString()) + !parsedJson.read('''$[?(@.code =~ /(123123)?/)]''', JSONArray).empty + !parsedJson.read('''$[?(@.message =~ /User not found by email == \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]''', JSONArray).empty + +---- + +and the following stub: + +[source,javascript,indent=0] +---- +{ + "request" : { + "url" : "/users/password", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/)]" + }, { + "matchesJsonPath" : "$[?(@.email =~ /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4})?/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 404, + "body" : "{\"code\":\"123123\",\"message\":\"User not found by email == [not.existing@user.com]\"}", + "headers" : { + "Content-Type" : "application/json" + } + }, + "priority" : 1 +} +---- + +=== Executing custom methods on server side +It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. Please see the examples below: + +==== Groovy DSL + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] +''' + } + response { + body ( + path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), + correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) + ) + status 200 + } +} +---- + +==== Base Mock Spec + +[source,groovy,indent=0] +---- +abstract class BaseMockMvcSpec extends Specification { + + def setup() { + RestAssuredMockMvc.standaloneSetup(new PairIdController()) + } + + void isProperCorrelationId(Integer correlationId) { + assert correlationId === 123456 + } +} +---- + +=== JAX-RS support +Starting with release 0.8.0 we support JAX-RS 2 Client API. Base class needs to define `protected WebTarget webTarget` and server initialization, right now the only option how to test JAX-RS API is to start a web server. + +Request with a body needs to have a content type set otherwise `application/octet-stream` is going to be used. + +In order to use JAX-RS mode, use the following settings: + +[source,groovy,indent=0] +---- +testMode == 'JAXRSCLIENT' +---- + +Example of a test API generated: + +[source,groovy,indent=0] +---- +class FraudDetectionServiceSpec extends MvcSpec { + + def shouldMarkClientAsNotFraud() { + when: + def response == webTarget + .path('/fraudcheck') + .request() + .method('put', entity('{"clientPesel":"1234567890","loanAmount":123.123}', 'application/vnd.fraud.v1+json')) + + String responseAsString == response.readEntity(String) + + then: + response.status === 200 + response.getHeaderString('Content-Type') === 'application/vnd.fraud.v1+json' + and: + def responseBody == new JsonSlurper().parseText(responseAsString) + responseBody.fraudCheckStatus === "OK" + assertThatRejectionReasonIsNull(responseBody.rejectionReason) + } + + def shouldMarkClientAsFraud() { + when: + def response == webTarget + .path('/fraudcheck') + .request() + .method('put', entity('{"clientPesel":"1234567890","loanAmount":99999}', 'application/vnd.fraud.v1+json')) + + String responseAsString == response.readEntity(String) + + then: + response.status === 200 + response.getHeaderString('Content-Type') === 'application/vnd.fraud.v1+json' + and: + def responseBody == new JsonSlurper().parseText(responseAsString) + responseBody.fraudCheckStatus ==~ java.util.regex.Pattern.compile('[A-Z]{5}') + responseBody.rejectionReason === "Amount too high" + } + +} +---- \ No newline at end of file diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index df53f371ab..a1d3a7eb8b 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,579 +1,13 @@ -Welcome to the Accurest Wiki! +Welcome to the Accurest Documentation! -== Introduction - -Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: - -* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by Accurest. -* Acceptance tests (in Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by Accurest. - -Accurest moves TDD to the level of software architecture. - -=== Why? - -The main purposes of Accurest are: - - - to ensure that WireMock stubs (used when developing the client) are doing exactly what actual server-side implementation will do, - - to promote ATDD method and Microservices architectural style, - - to provide a way to publish changes in contracts that are immediately visible on both sides, - - to generate boilerplate test code used on the server side. +include::introduction.adoc[] include::rest.adoc[] +include::contract.adoc[] + include::messaging.adoc[] -== Contract DSL - -Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself. - -Let's look at full example of a contract definition. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'POST' - urlPath('/users') { - queryParameters { - parameter 'limit': 100 - parameter 'offset': containing("1") - parameter 'filter': "email" - } - } - headers { - header 'Content-Type': 'application/json' - } - body '''{ "login" : "john", "name": "John The Contract" }''' - } - response { - status 200 - headers { - header 'Location': '/users/john' - } - } -} ----- - -Not all features of the DSL are used in example above. If you didn't find what you are looking for, please check next paragraphs on this page. - -> You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. - -=== Top-Level Elements - -Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - // Definition of HTTP request part of the contract - // (this can be a valid request or invalid depending - // on type of contract being specified). - request { - ... - } - - // Definition of HTTP response part of the contract - // (a service implementing this contract should respond - // with following response after receiving request - // specified in "request" part above). - response { - ... - } - - // Contract priority, which can be used for overriding - // contracts (1 is highest). Priority is optional. - priority 1 -} ----- - -=== Request - -HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of Accurest contract. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - // HTTP request method (GET/POST/PUT/DELETE). - method 'GET' - - // Path component of request URL is specified as follows. - urlPath('/users') - } - - response { - ... - } -} ----- - -It is possible to specify whole `url` instead of just path, but `urlPath` is the recommended way as it makes the tests **host-independent**. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'GET' - - // Specifying `url` and `urlPath` in one contract is illegal. - url('http://localhost:8888/users') - } - - response { - ... - } -} ----- - -Request may contain **query parameters**, which are specified in a closure nested in a call to `urlPath` or `url`. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - urlPath('/users') { - - // Each parameter is specified in form - // `'paramName' : paramValue` where parameter value - // may be a simple literal or one of matcher functions, - // all of which are used in this example. - queryParameters { - - // If a simple literal is used as value - // default matcher function is used (equalTo) - parameter 'limit': 100 - - // `equalTo` function simply compares passed value - // using identity operator (==). - parameter 'filter': equalTo("email") - - // `containing` function matches strings - // that contains passed substring. - parameter 'gender': containing("[mf]") - - // `matching` function tests parameter - // against passed regular expression. - parameter 'offset': matching("[0-9]+") - - // `notMatching` functions tests if parameter - // does not match passed regular expression. - parameter 'loginStartsWith': notMatching(".{0,2}") - } - } - - ... - } - - response { - ... - } -} ----- - -It may contain additional **request headers**... - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // Each header is added in form `'Header-Name' : 'Header-Value'`. - headers { - header 'Content-Type': 'application/json' - } - - ... - } - - response { - ... - } -} ----- - -...and a **request body**. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // JSON and XML formats of request body are supported. - // Format will be determined from a header or body's content. - body '''{ "login" : "john", "name": "John The Contract" }''' - } - - response { - ... - } -} ----- - -**Body's format** can also be specified explicitly by invoking one of format functions. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // In this case body will be formatted as XML. - body equalToXml( - '''johnJohn The Contract''' - ) - } - - response { - ... - } -} ----- - -=== Response - -Minimal response must contain **HTTP status code**. - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - } - response { - // Status code sent by the server - // in response to request specified above. - status 200 - } -} ----- - -Besides status response may contain **headers** and **body**, which are specified the same way as in the request (see previous paragraph). - -=== Regular expressions -You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both for your test and your server side tests. - - Please see the example below: - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl groovyDsl == GroovyDsl.make { - request { - method('GET') - url $(client(~/\/[0-9]{2}/), server('/12')) - } - response { - status 200 - body( - id: value( - client('123'), - server(regex('[0-9]+')) - ), - surname: $( - client('Kowalsky'), - server('Lewandowski') - ), - name: 'Jan', - created: $(client('2014-02-02 12:23:43'), server({ currentDate(it) })) - correlationId: value(client('5d1f9fef-e0dc-4f3d-a7e4-72d2220dd827'), - server(regex('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') - ) - ) - headers { - header 'Content-Type': 'text/plain' - } - } -} ----- - -=== Passing optional parameters - -It is possible to provide optional parameters in your contract. It's only possible to have optional parameter for the: - -- __STUB__ side of the Request -- __TEST__ side of the Response - -Example: - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - email: $(stub(optional(regex(email()))), test('abc@abc.com')), - callback_url: $(stub(regex(hostname())), test('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: value(stub("123123"), test(optional("123123"))), - message: "User not found by email == [${value(test(regex(email())), stub('not.existing@user.com'))}]" - ) - } -} ----- - -By wrapping a part of the body with the `optional()` method you are in fact creating a regular expression that should be present 0 or more times. - -That way for the example above the following test would be generated: - -[source,groovy,indent=0] ----- - given: - def request == given() - .header('Content-Type', 'application/json') - .body('{"email":"abc@abc.com","callback_url":"http://partners.com"}') - - when: - def response == given().spec(request) - .post("/users/password") - - then: - response.statusCode === 404 - response.header('Content-Type') === 'application/json' - and: - DocumentContext parsedJson == JsonPath.parse(response.body.asString()) - !parsedJson.read('''$[?(@.code =~ /(123123)?/)]''', JSONArray).empty - !parsedJson.read('''$[?(@.message =~ /User not found by email == \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]''', JSONArray).empty - ----- - -and the following stub: - -[source,javascript,indent=0] ----- -{ - "request" : { - "url" : "/users/password", - "method" : "POST", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/)]" - }, { - "matchesJsonPath" : "$[?(@.email =~ /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4})?/)]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - } - }, - "response" : { - "status" : 404, - "body" : "{\"code\":\"123123\",\"message\":\"User not found by email == [not.existing@user.com]\"}", - "headers" : { - "Content-Type" : "application/json" - } - }, - "priority" : 1 -} ----- - -=== Executing custom methods on server side -It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. Please see the examples below: - -==== Groovy DSL - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - body ( - path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), - correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) - ) - status 200 - } -} ----- - -==== Base Mock Spec - -[source,groovy,indent=0] ----- -abstract class BaseMockMvcSpec extends Specification { - - def setup() { - RestAssuredMockMvc.standaloneSetup(new PairIdController()) - } - - void isProperCorrelationId(Integer correlationId) { - assert correlationId === 123456 - } -} ----- - -=== JAX-RS support -Starting with release 0.8.0 we support JAX-RS 2 Client API. Base class needs to define `protected WebTarget webTarget` and server initialization, right now the only option how to test JAX-RS API is to start a web server. - -Request with a body needs to have a content type set otherwise `application/octet-stream` is going to be used. - -In order to use JAX-RS mode, use the following settings: - -[source,groovy,indent=0] ----- -testMode == 'JAXRSCLIENT' ----- - -Example of a test API generated: - -[source,groovy,indent=0] ----- -class FraudDetectionServiceSpec extends MvcSpec { - - def shouldMarkClientAsNotFraud() { - when: - def response == webTarget - .path('/fraudcheck') - .request() - .method('put', entity('{"clientPesel":"1234567890","loanAmount":123.123}', 'application/vnd.fraud.v1+json')) - - String responseAsString == response.readEntity(String) - - then: - response.status === 200 - response.getHeaderString('Content-Type') === 'application/vnd.fraud.v1+json' - and: - def responseBody == new JsonSlurper().parseText(responseAsString) - responseBody.fraudCheckStatus === "OK" - assertThatRejectionReasonIsNull(responseBody.rejectionReason) - } - - def shouldMarkClientAsFraud() { - when: - def response == webTarget - .path('/fraudcheck') - .request() - .method('put', entity('{"clientPesel":"1234567890","loanAmount":99999}', 'application/vnd.fraud.v1+json')) - - String responseAsString == response.readEntity(String) - - then: - response.status === 200 - response.getHeaderString('Content-Type') === 'application/vnd.fraud.v1+json' - and: - def responseBody == new JsonSlurper().parseText(responseAsString) - responseBody.fraudCheckStatus ==~ java.util.regex.Pattern.compile('[A-Z]{5}') - responseBody.rejectionReason === "Amount too high" - } - -} ----- - -== Client Side - -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 - -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. - -== Examples - -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/api/12' - headers { - header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json' - } - body '''\ - [{ - "created_at": "Sat Jul 26 09:38:57 +0000 2014", - "id": 492967299297845248, - "id_str": "492967299297845248", - "text": "Gonna see you at Warsaw", - "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" - } - }] -''' - } - response { - status 200 - } -} ----- - -== Scenarios - -It's possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore. - -[source,indent=0] ----- -my_contracts_dir\ - scenario1\ - 1_login.groovy - 2_showCart.groovy - 3_logout.groovy ----- - -Such tree will cause Accurest generating Wiremock's scenario with name `scenario1` and three steps: - - login marked as `Started` pointing to: - - showCart marked as `Step1` pointing to: - - logout marked as `Step2` which will close the scenario. -More details about Wiremock scenarios can be found under [http://wiremock.org/stateful-behaviour.html](http://wiremock.org/stateful-behaviour.html) - -Accurest will also generate tests with guaranteed order of execution. - include::stubrunner.adoc[] include::stubrunner_msg.adoc[] diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc new file mode 100644 index 0000000000..6714efb910 --- /dev/null +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -0,0 +1,88 @@ +== Introduction + +Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: + +* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by Accurest. +* Acceptance tests (in Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by Accurest. + +Accurest moves TDD to the level of software architecture. + +=== Why? + +The main purposes of Accurest are: + + - to ensure that WireMock stubs (used when developing the client) are doing exactly what actual server-side implementation will do, + - to promote ATDD method and Microservices architectural style, + - to provide a way to publish changes in contracts that are immediately visible on both sides, + - to generate boilerplate test code used on the server side. + +=== Client Side + +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 + +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. + +=== Examples + +[source,groovy,indent=0] +---- +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/api/12' + headers { + header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json' + } + body '''\ + [{ + "created_at": "Sat Jul 26 09:38:57 +0000 2014", + "id": 492967299297845248, + "id_str": "492967299297845248", + "text": "Gonna see you at Warsaw", + "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" + } + }] +''' + } + response { + status 200 + } +} +---- + +//TODO: Add videos, slides \ No newline at end of file diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc index 3653f4fc67..037d49cb24 100644 --- a/docs/src/docs/asciidoc/messaging.adoc +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -51,8 +51,6 @@ testCompile "io.codearte.accurest:accurest-messaging-core:${accurestVersion}" Having the `input` or `outputMessage` sections in your DSL will result in creation of tests on the publisher's side. By default JUnit tests will be created, however there is also a possibility to create Spock tests. -=== Examples - There are 3 main scenarios that we should take into consideration: - Scenario 1: there is no input message that produces an output one. The output message is triggered by a component diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index 83add091e3..cdad848333 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -346,4 +346,25 @@ class LoanApplicationServiceSpec extends Specification { } ---- -Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. \ No newline at end of file +Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. + +=== Scenarios + +It's possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore. + +[source,indent=0] +---- +my_contracts_dir\ + scenario1\ + 1_login.groovy + 2_showCart.groovy + 3_logout.groovy +---- + +Such tree will cause Accurest generating Wiremock's scenario with name `scenario1` and three steps: + - login marked as `Started` pointing to: + - showCart marked as `Step1` pointing to: + - logout marked as `Step2` which will close the scenario. +More details about Wiremock scenarios can be found under [http://wiremock.org/stateful-behaviour.html](http://wiremock.org/stateful-behaviour.html) + +Accurest will also generate tests with guaranteed order of execution. \ No newline at end of file From 268f10f8483a1985b4f7696299ad322f3bccd2a1 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 24 Apr 2016 18:46:47 +0200 Subject: [PATCH 539/719] plugin documentation [ci skip] --- README.md | 90 +------ src/site/asciidoc/junit.adoc | 29 +++ src/site/asciidoc/spock.adoc | 29 +++ src/site/asciidoc/usage.adoc | 49 ++-- src/site/site.xml | 2 + .../io/codearte/accurest/maven/PluginIT.java | 4 +- src/test/projects/spring-boot-groovy/pom.xml | 241 +++++++++--------- .../ofg/twitter/place/PairIdController.groovy | 36 --- .../groovy/com/ofg/twitter/place/Tweet.java | 13 - .../src/main/java/hello/Application.java | 12 + .../src/main/java/hello/Greeting.java | 20 ++ .../main/java/hello/GreetingController.java | 19 ++ .../sample/SampleSimpleBootApplication.java | 12 - .../src/main/resources/application.properties | 0 .../src/test/accurest/greetings_ok.groovy | 21 ++ .../greetings_with_default_value.groovy | 17 ++ .../ofg/twitter/place/AcceptanceTest.groovy | 23 -- .../ofg/twitter/place/BaseMockMvcTest.groovy | 16 -- .../src/test/groovy/hello/BaseAccurest.groovy | 12 + .../SampleSimpleBootApplicationTests.java | 16 -- .../src/test/resources/logback-test.groovy | 14 - .../stubs/collerate_PlacesFrom_Tweet.groovy | 18 -- .../resources/stubs/moreComplexVersion.groovy | 21 -- src/test/projects/spring-boot-java/pom.xml | 10 +- ...BaseMockMvcTest.java => BaseAccurest.java} | 2 +- 25 files changed, 321 insertions(+), 405 deletions(-) create mode 100644 src/site/asciidoc/junit.adoc create mode 100644 src/site/asciidoc/spock.adoc delete mode 100644 src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy delete mode 100644 src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java create mode 100644 src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java create mode 100644 src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java create mode 100644 src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java delete mode 100644 src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java delete mode 100644 src/test/projects/spring-boot-groovy/src/main/resources/application.properties create mode 100644 src/test/projects/spring-boot-groovy/src/test/accurest/greetings_ok.groovy create mode 100644 src/test/projects/spring-boot-groovy/src/test/accurest/greetings_with_default_value.groovy delete mode 100644 src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy delete mode 100644 src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy create mode 100644 src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy delete mode 100644 src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java delete mode 100644 src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy delete mode 100644 src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy delete mode 100644 src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy rename src/test/projects/spring-boot-java/src/test/java/hello/{BaseMockMvcTest.java => BaseAccurest.java} (87%) diff --git a/README.md b/README.md index 155c017944..99fb9e48b8 100644 --- a/README.md +++ b/README.md @@ -3,91 +3,9 @@ Accurate REST Maven Plugin ==== -Converting [Accurest](https://github.com/Codearte/accurest/wiki/1.-Introduction) GroovyDSL into WireMock stub mappings: +Documentation +--- - mvn io.codearte.accurest:accurest-maven-plugin:convert - -or shortly * - - mvn accurest:convert - -For more information please go to the [Accurest Wiki](https://github.com/Codearte/accurest/wiki/2.2-Maven-Project) or [Plugin Documentation Site](http://codearte.github.io/accurest-maven-plugin/plugin-info.html). +* [Accurest Wiki](https://github.com/Codearte/accurest/) +* [Accurest Maven Plugin Documentation Site](http://codearte.github.io/accurest-maven-plugin/plugin-info.html) - - - -Accurest Stub Runner ---- - -Run stubs mappings from current directory: - - mvn io.codearte.accurest:accurest-maven-plugin:run - -or shortly * - - mvn accurest:run - -Running stubs from repository: - - mvn accurest:run -Dstubs="org.springframework:gs-rest-service" - -where `org.springframework:gs-rest-service` is artifact with `stubs` classifier contains wiremock mappings. - - -Project configuration ----- - -```xml - - io.codearte.accurest - accurest-maven-plugin - 0.5.7 - - - - convert - generateStubs - generateTests - - - - - foobar.BaseAccurestTest - - -``` - -Sample `BaseAccurateTest.java` - -```java -package foobar; - -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; -import org.junit.Before; - -public class BaseAccurestTest { - - @Before - public void setup() { - RestAssuredMockMvc.standaloneSetup(new FoobarController()); - } - -} -``` - - ---- - -* Additional configuration inside `~/.m2/settings.xml` is required. - -```xml - - ... - - io.codearte.accurest - - ... - - -``` - diff --git a/src/site/asciidoc/junit.adoc b/src/site/asciidoc/junit.adoc new file mode 100644 index 0000000000..ad56a34c79 --- /dev/null +++ b/src/site/asciidoc/junit.adoc @@ -0,0 +1,29 @@ +== Java Project with JUnit Tests + +Sample minimal configuration for Java Project with JUnit tests. + +=== Test dependencies for generated contract verification tests + +[source,xml] +---- +include::../../../src/test/projects/spring-boot-java/pom.xml[tags=dependencies] +---- + +=== Project configuration for Accurest with JUnit tests and stub publishing + +[source,xml] +---- +include::../../../src/test/projects/spring-boot-java/pom.xml[tags=plugin] +---- + +=== Base Test class + +[source,java] +---- +include::../../../src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java[] +---- + + +=== Project source code + +https://github.com/Codearte/accurest-maven-plugin/tree/master/src/test/projects/spring-boot-java \ No newline at end of file diff --git a/src/site/asciidoc/spock.adoc b/src/site/asciidoc/spock.adoc new file mode 100644 index 0000000000..b9b4f92d24 --- /dev/null +++ b/src/site/asciidoc/spock.adoc @@ -0,0 +1,29 @@ +== Groovy Project with Spock Specifications + +Sample minimal configuration for Groovy Project with Spock Specification + +=== Test dependencies for generated contract verification tests + +[source,xml] +---- +include::../../../src/test/projects/spring-boot-groovy/pom.xml[tags=dependencies] +---- + +=== Project configuration for Accurest, Groovy and Spock specifications and stub publishing + + +[source,xml] +---- +include::../../../src/test/projects/spring-boot-groovy/pom.xml[tags=plugin] +---- + +=== Base Specification class + +[source,java] +---- +include::../../../src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy[] +---- + +=== Project source code + +https://github.com/Codearte/accurest-maven-plugin/tree/master/src/test/projects/spring-boot-groovy diff --git a/src/site/asciidoc/usage.adoc b/src/site/asciidoc/usage.adoc index 9cdbcc2140..976de79d95 100644 --- a/src/site/asciidoc/usage.adoc +++ b/src/site/asciidoc/usage.adoc @@ -1,24 +1,35 @@ -== Usage += Usage -Sample minimal configuration for project with Java source code. +== Converting Accurest GroovyDSL into WireMock stub mappings + mvn io.codearte.accurest:accurest-maven-plugin:convert + +or shortly footnoteref:[prefix,Additional configuration inside `~/.m2/settings.xml` is required: `io.codearte.accurest`.] + + mvn accurest:convert + +For more information please go to the Accurest Wiki or Plugin Documentation Site. + +== Accurest Stub Runner + +Run stubs mappings from current directory: + + mvn io.codearte.accurest:accurest-maven-plugin:run + +or shortly footnoteref:[prefix] + + mvn accurest:run + +== Running stubs from repository + + mvn accurest:run -Dstubs="org.springframework:gs-rest-service" + +where `org.springframework:gs-rest-service` is artifact with stubs classifier contains wiremock mappings. + +== Project configuration + +[source,xml] ---- - - io.codearte.accurest - accurest-maven-plugin - 0.5.8 - - - - convert - generateStubs - generateTests - - - - - foobar.AccurestBaseTest - - +include::../../../src/test/projects/spring-boot-java/pom.xml[tags=plugin] ---- diff --git a/src/site/site.xml b/src/site/site.xml index 99c060eba2..005d021238 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -28,6 +28,8 @@ + + diff --git a/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/io/codearte/accurest/maven/PluginIT.java index 15305cf7d2..b1e5415683 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIT.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIT.java @@ -37,7 +37,7 @@ public class PluginIT { .assertLogText("Generated 1 test classes.") .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") .assertLogText("Creating new json") - .assertLogText("Compiled 3 files.") // groovy test classes + .assertLogText("Running io.codearte.accurest.tests.AccurestSpec") .assertErrorFreeLog(); } @@ -51,7 +51,7 @@ public class PluginIT { .assertLogText("Generated 1 test classes.") .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") .assertLogText("Creating new json") - .assertLogText("Compiling 2 source files") + .assertLogText("Running io.codearte.accurest.tests.AccurestTest") .assertErrorFreeLog(); } diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index 50d56c8e6a..f833504383 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -1,137 +1,128 @@ - 4.0.0 + 4.0.0 - io.codearte.sample - sample-simple-boot - 0.0.1-SNAPSHOT - jar + org.springframework + gs-rest-service + 0.1.0 - sample-simple-boot - Demo project for Spring Boot + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + - - org.springframework.boot - spring-boot-starter-parent - 1.3.3.RELEASE - - + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + - - UTF-8 - 1.8 - ${it-plugin.version} - + + + + org.spockframework + spock-core + test + + + com.jayway.restassured + rest-assured + 2.9.0 + test + + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + test + + + com.toomuchcoding.jsonassert + jsonassert + 0.3.0 + test + + - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-test - test - + - - org.codehaus.groovy - groovy-all - + + 1.8 + ${it-plugin.version} + - - - org.spockframework - spock-core - 1.0-groovy-2.4 - test - - - com.jayway.restassured - rest-assured - 2.9.0 - test - - - com.jayway.restassured - spring-mock-mvc - 2.9.0 - test - - - com.toomuchcoding.jsonassert - jsonassert - 0.3.0 - test - - + + + + org.springframework.boot + spring-boot-maven-plugin + + + + io.codearte.accurest + accurest-maven-plugin + ${accurest-plugin.version} + + + + convert + generateStubs + generateTests + + + + + hello.BaseAccurest + SPOCK + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.5 + + + + testCompile + + + + + + + ${project.basedir}/src/test/groovy + + **/*.groovy + + + + ${project.build.directory}/generated-test-sources/accurest + + **/*.groovy + + + + + + + maven-surefire-plugin + 2.19 + + + **/*Spec.java + + + + + + - - - - org.springframework.boot - spring-boot-maven-plugin - - - io.codearte.accurest - accurest-maven-plugin - ${accurest.version} - - - - convert - generateStubs - generateTests - - - - - com.ofg.twitter.place.BaseMockMvcTest - src/test/resources/stubs - SPOCK - Test - - - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.5 - - - - addSources - compile - testCompile - - - - - - - ${project.basedir}/src/test/groovy - - **/*.groovy - - - - ${project.build.directory}/generated-test-sources/accurest - - **/*.groovy - - - - - - - - diff --git a/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy deleted file mode 100644 index 3a7671793c..0000000000 --- a/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy +++ /dev/null @@ -1,36 +0,0 @@ -package com.ofg.twitter.place - -import groovy.transform.TypeChecked -import groovy.util.logging.Slf4j -import org.springframework.http.MediaType -import org.springframework.web.bind.annotation.PathVariable -import org.springframework.web.bind.annotation.RequestBody -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -import static org.springframework.web.bind.annotation.RequestMethod.PUT - -@Slf4j -@RestController -@RequestMapping('/api') -@TypeChecked -class PairIdController { - - @RequestMapping( - value = '{pairId}', - method = PUT, - consumes = MediaType.APPLICATION_JSON_VALUE, - produces = MediaType.APPLICATION_JSON_VALUE) - String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { - log.info("Inside PairIdController, doing very important logic") - if (tweets?.text != ["Gonna see you at Warsaw"]) { - throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") - } - return """ - { - "path" : "/api/$pairId", - "correlationId" : 123456 - } - """ - } -} diff --git a/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java b/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java deleted file mode 100644 index 5d1e9c2835..0000000000 --- a/src/test/projects/spring-boot-groovy/src/main/groovy/com/ofg/twitter/place/Tweet.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.ofg.twitter.place; - -public class Tweet { - private String text; - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } -} diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java b/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java new file mode 100644 index 0000000000..5abd411428 --- /dev/null +++ b/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java @@ -0,0 +1,12 @@ +package hello; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java b/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java new file mode 100644 index 0000000000..5d10b59b77 --- /dev/null +++ b/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java @@ -0,0 +1,20 @@ +package hello; + +public class Greeting { + + private final long id; + private final String content; + + public Greeting(long id, String content) { + this.id = id; + this.content = content; + } + + public long getId() { + return id; + } + + public String getContent() { + return content; + } +} diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java b/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java new file mode 100644 index 0000000000..e356ab2b10 --- /dev/null +++ b/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java @@ -0,0 +1,19 @@ +package hello; + +import java.util.concurrent.atomic.AtomicLong; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GreetingController { + + private static final String template = "Hello, %s!"; + private final AtomicLong counter = new AtomicLong(); + + @RequestMapping("/greeting") + public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { + return new Greeting(counter.incrementAndGet(), + String.format(template, name)); + } +} diff --git a/src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java b/src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java deleted file mode 100644 index 1ef9cf14fa..0000000000 --- a/src/test/projects/spring-boot-groovy/src/main/java/io/codearte/sample/SampleSimpleBootApplication.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.codearte.sample; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class SampleSimpleBootApplication { - - public static void main(String[] args) { - SpringApplication.run(SampleSimpleBootApplication.class, args); - } -} diff --git a/src/test/projects/spring-boot-groovy/src/main/resources/application.properties b/src/test/projects/spring-boot-groovy/src/main/resources/application.properties deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/test/projects/spring-boot-groovy/src/test/accurest/greetings_ok.groovy b/src/test/projects/spring-boot-groovy/src/test/accurest/greetings_ok.groovy new file mode 100644 index 0000000000..1a1f0c44f7 --- /dev/null +++ b/src/test/projects/spring-boot-groovy/src/test/accurest/greetings_ok.groovy @@ -0,0 +1,21 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'GET' + urlPath('/greeting') { + queryParameters { + parameter 'name': 'Something' + } + } + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body ( + id: 1, + content: "Hello, Something!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/spring-boot-groovy/src/test/accurest/greetings_with_default_value.groovy b/src/test/projects/spring-boot-groovy/src/test/accurest/greetings_with_default_value.groovy new file mode 100644 index 0000000000..d61159c084 --- /dev/null +++ b/src/test/projects/spring-boot-groovy/src/test/accurest/greetings_with_default_value.groovy @@ -0,0 +1,17 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'GET' + url('/greeting') + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body ( + id: 1, + content: "Hello, World!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy b/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy deleted file mode 100644 index d132261ded..0000000000 --- a/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/AcceptanceTest.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package com.ofg.twitter.place - -import com.ofg.twitter.place.PairIdController -import org.springframework.http.MediaType -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import spock.lang.Specification - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status - -class AcceptanceTest extends Specification { - - def "should have controller up and running"() { - given: - MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PairIdController()).build() - expect: - mockMvc.perform(put("/api/${1}"). - contentType(MediaType.APPLICATION_JSON). - content("""[{"text":"Gonna see you at Warsaw"}]""")). - andExpect(status().isOk()) - } -} diff --git a/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy b/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy deleted file mode 100644 index 96bf1e60c4..0000000000 --- a/src/test/projects/spring-boot-groovy/src/test/groovy/com/ofg/twitter/place/BaseMockMvcTest.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package com.ofg.twitter.place - -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import com.ofg.twitter.place.PairIdController -import spock.lang.Specification - -abstract class BaseMockMvcTest extends Specification { - - def setup() { - RestAssuredMockMvc.standaloneSetup(new PairIdController()) - } - - void isProperCorrelationId(Integer correlationId) { - assert correlationId == 123456 - } -} diff --git a/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy b/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy new file mode 100644 index 0000000000..4819faaf12 --- /dev/null +++ b/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy @@ -0,0 +1,12 @@ +package hello + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import spock.lang.Specification + +public class BaseAccurest extends Specification { + + def setup() { + RestAssuredMockMvc.standaloneSetup(new GreetingController()) + } + +} \ No newline at end of file diff --git a/src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java b/src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java deleted file mode 100644 index 345f6ef841..0000000000 --- a/src/test/projects/spring-boot-groovy/src/test/java/io/codearte/sample/SampleSimpleBootApplicationTests.java +++ /dev/null @@ -1,16 +0,0 @@ -package io.codearte.sample; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.boot.test.SpringApplicationConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -@RunWith(SpringJUnit4ClassRunner.class) -@SpringApplicationConfiguration(classes = SampleSimpleBootApplication.class) -public class SampleSimpleBootApplicationTests { - - @Test - public void contextLoads() { - } - -} diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy deleted file mode 100644 index 315c39c794..0000000000 --- a/src/test/projects/spring-boot-groovy/src/test/resources/logback-test.groovy +++ /dev/null @@ -1,14 +0,0 @@ -import ch.qos.logback.classic.encoder.PatternLayoutEncoder -import ch.qos.logback.core.ConsoleAppender - -String console = "CONSOLE" -String logPattern = "%d{yyyy-MM-dd HH:mm:ss.SSSZ, Europe/Warsaw} | %-5level | %X{correlationId} | %thread | %logger{1} | %m%n" - -appender(console, ConsoleAppender) { - encoder(PatternLayoutEncoder) { - pattern = logPattern - } -} - -root(INFO, [console]) -logger("com.ofg", DEBUG) diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy deleted file mode 100644 index 826f71b791..0000000000 --- a/src/test/projects/spring-boot-groovy/src/test/resources/stubs/collerate_PlacesFrom_Tweet.groovy +++ /dev/null @@ -1,18 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'PUT' - url '/api/12' - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - status 200 - } -} \ No newline at end of file diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy deleted file mode 100644 index 943fbc23b9..0000000000 --- a/src/test/projects/spring-boot-groovy/src/test/resources/stubs/moreComplexVersion.groovy +++ /dev/null @@ -1,21 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - body ( - path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), - correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) - ) - status 200 - } -} \ No newline at end of file diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index 3f1f635dbd..db9953406d 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -29,6 +29,7 @@ + com.jayway.restassured rest-assured @@ -53,10 +54,12 @@ 2.3.0 test + 1.8 + ${it-plugin.version} @@ -65,10 +68,11 @@ org.springframework.boot spring-boot-maven-plugin + io.codearte.accurest accurest-maven-plugin - ${it-plugin.version} + ${accurest-plugin.version} @@ -79,10 +83,10 @@ - hello - hello.BaseMockMvcTest + hello.BaseAccurest + diff --git a/src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java b/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java similarity index 87% rename from src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java rename to src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java index 2fe6a9564a..d3bf7124e2 100644 --- a/src/test/projects/spring-boot-java/src/test/java/hello/BaseMockMvcTest.java +++ b/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java @@ -3,7 +3,7 @@ package hello; import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; import org.junit.Before; -public class BaseMockMvcTest { +public class BaseAccurest { @Before public void setup() { From e6caa5429914144ebb151027a965cd7d0c4532fb Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 24 Apr 2016 19:05:09 +0200 Subject: [PATCH 540/719] small doc fixes [ci skip] --- README.md | 2 +- src/site/asciidoc/spock.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 99fb9e48b8..b785869107 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,6 @@ Accurate REST Maven Plugin Documentation --- -* [Accurest Wiki](https://github.com/Codearte/accurest/) +* [Accurest Wiki](http://codearte.github.io/accurest/) * [Accurest Maven Plugin Documentation Site](http://codearte.github.io/accurest-maven-plugin/plugin-info.html) diff --git a/src/site/asciidoc/spock.adoc b/src/site/asciidoc/spock.adoc index b9b4f92d24..6e262ede51 100644 --- a/src/site/asciidoc/spock.adoc +++ b/src/site/asciidoc/spock.adoc @@ -9,7 +9,7 @@ Sample minimal configuration for Groovy Project with Spock Specification include::../../../src/test/projects/spring-boot-groovy/pom.xml[tags=dependencies] ---- -=== Project configuration for Accurest, Groovy and Spock specifications and stub publishing +=== Project configuration for Accurest, Groovy, Spock specifications and stub publishing [source,xml] From 522ec70552694e9eb0067ab6879c78e94a2065c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sun, 24 Apr 2016 20:34:52 +0200 Subject: [PATCH 541/719] Add contracts to stub.jar by default (#13) --- .gitignore | 2 +- .../accurest/maven/ConvertMojo.groovy | 11 ++-------- .../accurest/maven/GenerateStubsMojo.groovy | 13 ++++++++++- .../accurest/maven/PluginUnitTest.java | 16 ++++++++++++++ src/test/projects/generatedStubs/pom.xml | 19 ++++++++++++++++ .../target/accurest/contracts/Sample.groovy | 18 +++++++++++++++ .../target/accurest/mappings/Sample.json | 22 +++++++++++++++++++ 7 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 src/test/projects/generatedStubs/pom.xml create mode 100644 src/test/projects/generatedStubs/target/accurest/contracts/Sample.groovy create mode 100644 src/test/projects/generatedStubs/target/accurest/mappings/Sample.json diff --git a/.gitignore b/.gitignore index 833eab7406..6c515d9c17 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ .idea/ *.iml -target +/target pom.xml.tag pom.xml.releaseBackup pom.xml.versionsBackup diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy index 6fab4377dd..9820d50781 100644 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -37,9 +37,6 @@ class ConvertMojo extends AbstractMojo { @Parameter(property = 'accurest.skip', defaultValue = 'false') private boolean skip - @Parameter(defaultValue = 'false') - private boolean attachContracts - @Parameter(defaultValue = '${session}', readonly = true) private MavenSession mavenSession @@ -56,13 +53,9 @@ class ConvertMojo extends AbstractMojo { return } - if (attachContracts) { - log.info("Attaching accurest contracts") - copyContracts() - } + copyContracts() AccurestConfigProperties config = new AccurestConfigProperties() - config.contractsDslDir = insideProject ? contractsDirectory : source config.stubsOutputDir = insideProject ? new File(outputDirectory, 'mappings') : destination @@ -75,8 +68,8 @@ class ConvertMojo extends AbstractMojo { } private void copyContracts() { + log.info("Copying accurest contracts") Resource testResource = new Resource(directory: contractsDirectory.absolutePath) - MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution([testResource], new File(outputDirectory, 'contracts'), project, 'UTF-8', diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy index ed88bd2b74..028ce108bc 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy @@ -17,6 +17,9 @@ import org.codehaus.plexus.archiver.jar.JarArchiver @CompileStatic class GenerateStubsMojo extends AbstractMojo { + private static final String STUB_MAPPING_FILE_PATTERN = '**/*.json' + private static final String ACCUREST_FILE_PATTERN = '**/*.groovy' + @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) private File projectBuildDirectory @@ -35,6 +38,9 @@ class GenerateStubsMojo extends AbstractMojo { @Component(role = Archiver.class, hint = "jar") private JarArchiver jarArchiver; + @Parameter(defaultValue = 'true') + private boolean attachContracts + void execute() throws MojoExecutionException, MojoFailureException { if (skip) { @@ -54,7 +60,12 @@ class GenerateStubsMojo extends AbstractMojo { File stubJarFile = new File(projectBuildDirectory, stubArchiveName); try { - jarArchiver.addDirectory(stubsOutputDir); + if (attachContracts) { + jarArchiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN, ACCUREST_FILE_PATTERN] as String[], [] as String[]); + } else { + log.info("Skipping attaching accurest contracts") + jarArchiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN] as String[], [ACCUREST_FILE_PATTERN] as String[]); + } jarArchiver.setCompress(true); jarArchiver.setDestFile(stubJarFile); jarArchiver.createArchive(); diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index d008614a00..8f2f195b97 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -1,6 +1,7 @@ package io.codearte.accurest.maven; import static io.takari.maven.testing.TestMavenRuntime.newParameter; +import static io.takari.maven.testing.TestResources.assertFileContents; import static io.takari.maven.testing.TestResources.assertFilesPresent; import java.io.File; @@ -56,4 +57,19 @@ public class PluginUnitTest { "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestTest.java"); } + @Test + public void shouldGenerateStubs() throws Exception { + File basedir = resources.getBasedir("generatedStubs"); + maven.executeMojo(basedir, "generateStubs"); + assertFilesPresent(basedir, "target/sample-project-0.1-stubs.jar"); + } + + @Test + public void shouldGenerateStubsWithMappingsOnly() throws Exception { + File basedir = resources.getBasedir("generatedStubs"); + maven.executeMojo(basedir, "generateStubs", newParameter("attachContracts", "false")); + assertFilesPresent(basedir, "target/sample-project-0.1-stubs.jar"); + // FIXME: add assertion for jar content + } + } diff --git a/src/test/projects/generatedStubs/pom.xml b/src/test/projects/generatedStubs/pom.xml new file mode 100644 index 0000000000..fed7b7d67e --- /dev/null +++ b/src/test/projects/generatedStubs/pom.xml @@ -0,0 +1,19 @@ + + + 4.0.0 + + io.codearte.accurest.sample + sample-project + 0.1 + + + + + io.codearte.accurest + accurest-maven-plugin + + + + + \ No newline at end of file diff --git a/src/test/projects/generatedStubs/target/accurest/contracts/Sample.groovy b/src/test/projects/generatedStubs/target/accurest/contracts/Sample.groovy new file mode 100644 index 0000000000..673ab7bd8d --- /dev/null +++ b/src/test/projects/generatedStubs/target/accurest/contracts/Sample.groovy @@ -0,0 +1,18 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'POST' + url('/users') { + + } + headers { + header 'Content-Type': 'application/json' + } + body '''{ "login" : "john", "name": "John The Contract" }''' + } + response { + status 200 + headers { + header 'Location': '/users/john' + } + } +} \ No newline at end of file diff --git a/src/test/projects/generatedStubs/target/accurest/mappings/Sample.json b/src/test/projects/generatedStubs/target/accurest/mappings/Sample.json new file mode 100644 index 0000000000..6641a7d26f --- /dev/null +++ b/src/test/projects/generatedStubs/target/accurest/mappings/Sample.json @@ -0,0 +1,22 @@ +{ + "request" : { + "url" : "/users", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.login == 'john')]" + }, { + "matchesJsonPath" : "$[?(@.name == 'John The Contract')]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 200, + "headers" : { + "Location" : "/users/john" + } + } +} \ No newline at end of file From 4bcf16db2d691e2900172d96a774315487700766 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sun, 24 Apr 2016 18:39:38 +0000 Subject: [PATCH 542/719] Sets project version to 0.5.10-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e2c246c1e6..902d01af3e 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.9-SNAPSHOT + 0.5.10-SNAPSHOT Accurest Maven Plugin Accurate REST Maven Plugin From b42774e1ab8cb868c3ce8dfb90cbf79a5e4e7818 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 21:08:31 +0200 Subject: [PATCH 543/719] Converted docs to adoc --- .../DslToWireMockClientConverterSpec.groovy | 66 + .../builder/ContractHttpDocsSpec.groovy | 299 ++++ .../JaxRsClientMethodBuilderSpec.groovy | 70 + .../MockMvcMethodBodyBuilderSpec.groovy | 1529 +++++++++-------- .../ofg/twitter/places/BaseMockMvcSpec.groovy | 2 + docs/src/docs/asciidoc/contract.adoc | 356 +--- docs/src/docs/asciidoc/images/Deps.png | Bin 0 -> 37192 bytes docs/src/docs/asciidoc/images/Stubs1.png | Bin 0 -> 35170 bytes docs/src/docs/asciidoc/images/Stubs2.png | Bin 0 -> 18143 bytes docs/src/docs/asciidoc/index.adoc | 28 +- docs/src/docs/asciidoc/introduction.adoc | 130 +- docs/src/docs/asciidoc/migration.adoc | 23 + 12 files changed, 1359 insertions(+), 1144 deletions(-) create mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy create mode 100644 docs/src/docs/asciidoc/images/Deps.png create mode 100644 docs/src/docs/asciidoc/images/Stubs1.png create mode 100644 docs/src/docs/asciidoc/images/Stubs2.png create mode 100644 docs/src/docs/asciidoc/migration.adoc 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 24d0eb2845..2382878856 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 @@ -171,4 +171,70 @@ class DslToWireMockClientConverterSpec extends Specification { } ''', json, false) } + + def 'should convert dsl to wiremock to show it in the docs'() { + given: + def converter = new DslToWireMockClientConverter() + and: + File file = tmpFolder.newFile("dsl_from_docs.groovy") + file.write(''' + io.codearte.accurest.dsl.GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: value(stub("123123"), test(optional("123123"))), + message: "User not found by email == [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) + } + } + ''') + when: + String json = converter.convertContent("Test", new Contract(file.toPath(), false, 0, null)) + then: + JSONAssert.assertEquals( // tag::wiremock[] +''' +{ + "request" : { + "url" : "/users/password", + "method" : "POST", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[?(@.email =~ /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4})?/)]" + }, { + "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]" + } ], + "headers" : { + "Content-Type" : { + "equalTo" : "application/json" + } + } + }, + "response" : { + "status" : 404, + "body" : "{\\"code\\":\\"123123\\",\\"message\\":\\"User not found by email == [not.existing@user.com]\\"}", + "headers" : { + "Content-Type" : "application/json" + } + }, + "priority" : 1 +} +''' +// end::wiremock[] + , json, false) + } + } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy new file mode 100644 index 0000000000..235e8184b5 --- /dev/null +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy @@ -0,0 +1,299 @@ +package io.codearte.accurest.builder + +import io.codearte.accurest.dsl.GroovyDsl +import spock.lang.Specification +/** + * Tests used for the documentation + * + * @author Marcin Grzejszczak + */ +class ContractHttpDocsSpec extends Specification { + + GroovyDsl httpDsl = + // tag::http_dsl[] + io.codearte.accurest.dsl.GroovyDsl.make { + // Definition of HTTP request part of the contract + // (this can be a valid request or invalid depending + // on type of contract being specified). + request { + //... + } + + // Definition of HTTP response part of the contract + // (a service implementing this contract should respond + // with following response after receiving request + // specified in "request" part above). + response { + //... + } + + // Contract priority, which can be used for overriding + // contracts (1 is highest). Priority is optional. + priority 1 + } + // end::http_dsl[] + + GroovyDsl request = + // tag::request[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + // HTTP request method (GET/POST/PUT/DELETE). + method 'GET' + + // Path component of request URL is specified as follows. + urlPath('/users') + } + + response { + //... + } + } + // end::request[] + + GroovyDsl url = + // tag::url[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'GET' + + // Specifying `url` and `urlPath` in one contract is illegal. + url('http://localhost:8888/users') + } + + response { + //... + } + } + // end::url[] + + GroovyDsl urlPaths = + // tag::urlpath[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + //... + + urlPath('/users') { + + // Each parameter is specified in form + // `'paramName' : paramValue` where parameter value + // may be a simple literal or one of matcher functions, + // all of which are used in this example. + queryParameters { + + // If a simple literal is used as value + // default matcher function is used (equalTo) + parameter 'limit': 100 + + // `equalTo` function simply compares passed value + // using identity operator (==). + parameter 'filter': equalTo("email") + + // `containing` function matches strings + // that contains passed substring. + parameter 'gender': value(stub(containing("[mf]")), server('mf')) + + // `matching` function tests parameter + // against passed regular expression. + parameter 'offset': value(stub(matching("[0-9]+")), server(123)) + + // `notMatching` functions tests if parameter + // does not match passed regular expression. + parameter 'loginStartsWith': value(stub(notMatching(".{0,2}")), server(3)) + } + } + + //... + } + + response { + //... + } + } + // end::urlpath[] + + GroovyDsl headers = + // tag::headers[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + //... + + // Each header is added in form `'Header-Name' : 'Header-Value'`. + headers { + header 'Content-Type': 'application/json' + } + + //... + } + + response { + //... + } + } + // end::headers[] + + GroovyDsl body = + // tag::body[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + //... + + // JSON and XML formats of request body are supported. + // Format will be determined from a header or body's content. + body '''{ "login" : "john", "name": "John The Contract" }''' + } + + response { + //... + } + } + // end::body[] + + GroovyDsl bodyAsXml = + // tag::bodyAsXml[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + //... + + // In this case body will be formatted as XML. + body equalToXml( + '''johnJohn The Contract''' + ) + } + + response { + //... + } + } + // end::bodyAsXml[] + + GroovyDsl response = + // tag::response[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + //... + } + response { + // Status code sent by the server + // in response to request specified above. + status 200 + } + } + // end::response[] + + GroovyDsl regex = + // tag::regex[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + method('GET') + url $(client(~/\/[0-9]{2}/), server('/12')) + } + response { + status 200 + body( + id: value( + client('123'), + server(regex('[0-9]+')) + ), + surname: $( + client('Kowalsky'), + server('Lewandowski') + ), + name: 'Jan', + created: $(client('2014-02-02 12:23:43'), server(execute('currentDate(it)'))), + correlationId: value(client('5d1f9fef-e0dc-4f3d-a7e4-72d2220dd827'), + server(regex('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')) + ) + ) + headers { + header 'Content-Type': 'text/plain' + } + } + } + // end::regex[] + + GroovyDsl optionals = + // tag::optionals[] + io.codearte.accurest.dsl.GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' + } + body( + email: $(stub(optional(regex(email()))), test('abc@abc.com')), + callback_url: $(stub(regex(hostname())), test('http://partners.com')) + ) + } + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: value(stub("123123"), test(optional("123123"))), + message: "User not found by email == [${value(test(regex(email())), stub('not.existing@user.com'))}]" + ) + } + } + // end::optionals[] + + def 'should convert dsl with optionals to proper Spock test'() { + given: + BlockBuilder blockBuilder = new BlockBuilder(" ") + new MockMvcSpockMethodRequestProcessingBodyBuilder(optionals).appendTo(blockBuilder) + expect: + stripped(blockBuilder.toString()) == stripped( +// tag::optionals_test[] +""" +given: + def request = given() + .header('Content-Type', 'application/json') + .body('''{"email":"abc@abc.com","callback_url":"http://partners.com"}''') + +when: + def response = given().spec(request) + .post("/users/password") + +then: + response.statusCode == 404 + response.header('Content-Type') == 'application/json' +and: + DocumentContext parsedJson = JsonPath.parse(response.body.asString()) + assertThatJson(parsedJson).field("message").matches("User not found by email == \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,4}\\\\\\\\]") + assertThatJson(parsedJson).field("code").matches("(123123)?") +""" +// end::optionals_test[] +) + } + + GroovyDsl method = + // tag::method[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] + ''' + } + response { + body ( + path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), + correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) + ) + status 200 + } + } + // end::method[] + + private String stripped(String string) { + return string.stripMargin().stripIndent().replace('\t', '').replace('\n', '') + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy index 0485a38d4d..3d36d7676f 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy @@ -591,4 +591,74 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")' } + def "should generate a call with an url path and query parameters with JUnit - we'll put it into docs"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() + } + } + } + response { + status 200 + body """ + { + "property1": "a", + "property2": "b" + } + """ + } + } + MethodBodyBuilder builder = new JaxRsClientJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + stripped(test) == stripped( // tag::jaxrs[] + ''' + // when: + Response response = webTarget + .path("/users") + .queryParam("limit", "10") + .queryParam("offset", "20") + .queryParam("filter", "email") + .queryParam("sort", "name") + .queryParam("search", "55") + .queryParam("age", "99") + .queryParam("name", "Denis.Stepanov") + .queryParam("email", "bob@email.com") + .request() + .method("GET"); + + String responseAsString = response.readEntity(String.class); + + // then: + assertThat(response.getStatus()).isEqualTo(200); + // and: + DocumentContext parsedJson = JsonPath.parse(responseAsString); + assertThatJson(parsedJson).field("property1").isEqualTo("a"); + assertThatJson(parsedJson).field("property2").isEqualTo("b"); +''' +// end::jaxrs[] +) + and: + stubMappingIsValidWireMockStub(contractDsl) + } + + private String stripped(String string) { + return string.stripMargin().stripIndent().replace('\t', '').replace('\n', '') + } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index 03d70d99ba..eaa303fb52 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -49,8 +49,12 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } body( """ { - "email" : "${value(stub(optional(regex(email()))), test('abc@abc.com'))}", - "callback_url" : "${value(client(regex(hostname())), server('http://partners.com'))}" + "email" : "${ + value(stub(optional(regex(email()))), test('abc@abc.com')) + }", + "callback_url" : "${ + value(client(regex(hostname())), server('http://partners.com')) + }" } """ ) @@ -74,1087 +78,1138 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub def "should generate assertions for simple response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body """{ + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ "property1": "a", "property2": "b" }""" - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isEqualTo("b")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#187") def "should generate assertions for null and boolean values with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body """{ + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ "property1": "true", "property2": null, "property3": false }""" - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("true")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isNull()""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property3").isEqualTo(false)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("true")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isNull()""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property3").isEqualTo(false)""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#79") def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property1: 'a', - property2: [ - [a: 'sth'], - [b: 'sthElse'] - ] - ) - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + body( + property1: 'a', + property2: [ + [a: 'sth'], + [b: 'sthElse'] + ] + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#82") def "should generate proper request when body constructed from map with a list #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - body( - items: ['HOP'] - ) - } - response { - status 200 - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + items: ['HOP'] + ) } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains(bodyString) + blockBuilder.toString().contains(bodyString) and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(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") def "should generate proper request when body constructed from GString with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - body( - "property1=VAL1" - ) - } - response { - status 200 - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + body( + "property1=VAL1" + ) } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains(bodyString) + blockBuilder.toString().contains(bodyString) and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(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") def "should generate assertions for a response body containing map with integers as keys with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property: [ - 14: 0.0, - 7 : 0.0 - ] - ) - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + body( + property: [ + 14: 0.0, + 7 : 0.0 + ] + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(7).isEqualTo(0.0)""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(14).isEqualTo(0.0)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(7).isEqualTo(0.0)""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").field(14).isEqualTo(0.0)""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for array in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body """[ + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """[ { "property1": "a" }, { "property2": "b" }]""" - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property2").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property2").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array().contains("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for array inside response body element with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body """{ + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body """{ "property1": [ { "property2": "test1"}, { "property3": "test2"} ] }""" - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property2").isEqualTo("test1")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property1").contains("property3").isEqualTo("test2")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for nested objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body '''\ + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body '''\ { "property1": "a", "property2": {"property3": "b"} } ''' - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").field("property3").isEqualTo("b")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").field("property3").isEqualTo("b")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate regex assertions for map objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body( - property1: "a", - property2: value( - client('123'), - server(regex('[0-9]{3}')) - ) - ) - headers { - header('Content-Type': 'application/json') - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body( + property1: "a", + property2: value( + client('123'), + server(regex('[0-9]{3}')) + ) + ) + headers { + header('Content-Type': 'application/json') } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate regex assertions for string objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body("""{"property1":"a","property2":"${value(client('123'), server(regex('[0-9]{3}')))}"}""") - headers { - header('Content-Type': 'application/json') - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property1":"a","property2":"${ + value(client('123'), server(regex('[0-9]{3}'))) + }"}""") + headers { + header('Content-Type': 'application/json') } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").matches("[0-9]{3}")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue(["#126", "#143"]) def "should generate escaped regex assertions for string objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - url "test" - } - response { - status 200 - body("""{"property":" ${value(client('123'), server(regex('\\d+')))}"}""") - headers { - header('Content-Type': 'application/json') - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + url "test" + } + response { + status 200 + body("""{"property":" ${ + value(client('123'), server(regex('\\d+'))) + }"}""") + headers { + header('Content-Type': 'application/json') } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) + builder.appendTo(blockBuilder) then: - blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").matches("\\\\d+")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property").matches("\\\\d+")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate a call with an url path and query parameters with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'GET' - urlPath('/users') { - queryParameters { - parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) - parameter 'offset': $(client(containing("20")), server(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) - parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) - parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) - parameter 'email': "bob@email.com" - parameter 'hello': $(client(matching("Denis.*")), server(absent())) - parameter 'hello': absent() - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath('/users') { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() } } - response { - status 200 - body """ + } + response { + status 200 + body """ { "property1": "a", "property2": "b" } """ - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - test.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') - test.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') + test.contains('get("/users?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + test.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') + test.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('#169') def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'GET' - url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { - queryParameters { - parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) - parameter 'offset': $(client(containing("20")), server(equalTo("20"))) - parameter 'filter': "email" - parameter 'sort': equalTo("name") - parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) - parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) - parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) - parameter 'email': "bob@email.com" - parameter 'hello': $(client(matching("Denis.*")), server(absent())) - parameter 'hello': absent() - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { + queryParameters { + parameter 'limit': $(client(equalTo("20")), server(equalTo("10"))) + parameter 'offset': $(client(containing("20")), server(equalTo("20"))) + parameter 'filter': "email" + parameter 'sort': equalTo("name") + parameter 'search': $(client(notMatching(~/^\/[0-9]{2}$/)), server("55")) + parameter 'age': $(client(notMatching("^\\w*\$")), server("99")) + parameter 'name': $(client(matching("Denis.*")), server("Denis.Stepanov")) + parameter 'email': "bob@email.com" + parameter 'hello': $(client(matching("Denis.*")), server(absent())) + parameter 'hello': absent() } } - response { - status 200 - body """ + } + response { + status 200 + body """ { "property1": "a", "property2": "b" } """ - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') - test.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') - test.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') + test.contains('get("/foo/123456?limit=10&offset=20&filter=email&sort=name&search=55&age=99&name=Denis.Stepanov&email=bob@email.com")') + test.contains('assertThatJson(parsedJson).field("property1").isEqualTo("a")') + test.contains('assertThatJson(parsedJson).field("property2").isEqualTo("b")') and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate test for empty body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method('POST') - url("/ws/payments") - body("") - } - response { - status 406 - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method('POST') + url("/ws/payments") + body("") } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 406 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains(bodyString) + test.contains(bodyString) and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(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(\"\\\"\\\"\")" } def "should generate test for String in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "POST" - url "test" - } - response { - status 200 - body "test" - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "POST" + url "test" } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + body "test" + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains(bodyDefinitionString) - test.contains(bodyEvaluationString) + test.contains(bodyDefinitionString) + test.contains(bodyEvaluationString) and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - 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");' + 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') def "should generate regex test for String in response header with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'POST' - url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) - headers { header 'Content-Type': 'application/json' } - body( - first_name: 'John', - last_name: 'Smith', - personal_id: '12345678901', - phone_number: '500500500', - invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', - password: 'john' - ) - } - response { - status 201 - headers { - header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex('http://localhost/partners/[0-9]+/users/[0-9]+'))) - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'POST' + url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) + headers { header 'Content-Type': 'application/json' } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex('http://localhost/partners/[0-9]+/users/[0-9]+'))) } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains(headerEvaluationString) + test.contains(headerEvaluationString) and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - 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]+");' + 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') def "should generate regex with helper method with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'POST' - url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) - headers { header 'Content-Type': 'application/json' } - body( - first_name: 'John', - last_name: 'Smith', - personal_id: '12345678901', - phone_number: '500500500', - invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', - password: 'john' - ) - } - response { - status 201 - headers { - header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex("^${hostname()}/partners/[0-9]+/users/[0-9]+"))) - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'POST' + url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) + headers { header 'Content-Type': 'application/json' } + body( + first_name: 'John', + last_name: 'Smith', + personal_id: '12345678901', + phone_number: '500500500', + invitation_token: '00fec7141bb94793bfe7ae1d0f39bda0', + password: 'john' + ) + } + response { + status 201 + headers { + header 'Location': $(client('http://localhost/partners/1000/users/1001'), server(regex("^${hostname()}/partners/[0-9]+/users/[0-9]+"))) } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains(headerEvaluationString) + test.contains(headerEvaluationString) and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - 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]+");' + 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]+");' } def "should work with more complex stuff and jsonpaths with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - priority 10 - request { - method 'POST' - url '/validation/client' - headers { - header 'Content-Type': 'application/json' - } - body( - bank_account_number: '0014282912345698765432161182', - email: 'foo@bar.com', - phone_number: '100299300', - personal_id: 'ABC123456' - ) - } - - response { - status 200 - body(errors: [ - [property: "bank_account_number", message: "incorrect_format"] - ]) + GroovyDsl contractDsl = GroovyDsl.make { + priority 10 + request { + method 'POST' + url '/validation/client' + headers { + header 'Content-Type': 'application/json' } + body( + bank_account_number: '0014282912345698765432161182', + email: 'foo@bar.com', + phone_number: '100299300', + personal_id: 'ABC123456' + ) } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + + response { + status 200 + body(errors: [ + [property: "bank_account_number", message: "incorrect_format"] + ]) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains("""assertThatJson(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number")""") - test.contains("""assertThatJson(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format")""") + test.contains("""assertThatJson(parsedJson).array("errors").contains("property").isEqualTo("bank_account_number")""") + test.contains("""assertThatJson(parsedJson).array("errors").contains("message").isEqualTo("incorrect_format")""") and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should work properly with GString url with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'PUT' - url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" - headers { - header 'Content-Type': 'application/json' - } - body( - first_name: 'Josef', - ) - } - response { - status 422 + request { + method 'PUT' + url "/partners/${value(client(regex('^[0-9]*$')), server('11'))}/agents/11/customers/09665703Z" + headers { + header 'Content-Type': 'application/json' } + body( + first_name: 'Josef', + ) } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 422 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains('''/partners/11/agents/11/customers/09665703Z''') + test.contains('''/partners/11/agents/11/customers/09665703Z''') and: - stubMappingIsValidWireMockStub(contractDsl) + stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should resolve properties in GString with regular expression with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - email: $(client(regex(email())), server('not.existing@user.com')), - callback_url: $(client(regex(hostname())), server('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: 4, - message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" - ) + GroovyDsl contractDsl = GroovyDsl.make { + priority 1 + request { + method 'POST' + url '/users/password' + headers { + header 'Content-Type': 'application/json' } + body( + email: $(client(regex(email())), server('not.existing@user.com')), + callback_url: $(client(regex(hostname())), server('http://partners.com')) + ) } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 404 + headers { + header 'Content-Type': 'application/json' + } + body( + code: 4, + message: "User not found by email = [${value(server(regex(email())), client('not.existing@user.com'))}]" + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - 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}\\\\\\\\]")""") + 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 MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('42') def "should not omit the optional field in the test creation with MockMvcSpockMethodBodyBuilder"() { given: - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains('''"email":"abc@abc.com"''') - test.contains("""assertThatJson(parsedJson).field("code").matches("(123123)?")""") - !test.contains('''REGEXP''') - !test.contains('''OPTIONAL''') - !test.contains('''OptionalProperty''') + test.contains('''"email":"abc@abc.com"''') + test.contains("""assertThatJson(parsedJson).field("code").matches("(123123)?")""") + !test.contains('''REGEXP''') + !test.contains('''OPTIONAL''') + !test.contains('''OptionalProperty''') where: - contractDsl << [dslWithOptionals, dslWithOptionalsInString] + contractDsl << [dslWithOptionals, dslWithOptionalsInString] } @Issue('42') def "should not omit the optional field in the test creation with MockMvcJUnitMethodBodyBuilder"() { given: - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains('\\"email\\":\\"abc@abc.com\\"') - test.contains('assertThatJson(parsedJson).field("code").matches("(123123)?");') - !test.contains('''REGEXP''') - !test.contains('''OPTIONAL''') - !test.contains('''OptionalProperty''') + test.contains('\\"email\\":\\"abc@abc.com\\"') + test.contains('assertThatJson(parsedJson).field("code").matches("(123123)?");') + !test.contains('''REGEXP''') + !test.contains('''OPTIONAL''') + !test.contains('''OptionalProperty''') where: - contractDsl << [dslWithOptionals, dslWithOptionalsInString] + contractDsl << [dslWithOptionals, dslWithOptionalsInString] } @Issue('72') def "should make the execute method work with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" + GroovyDsl contractDsl = GroovyDsl.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "clientPesel":"${ + value(client(regex('[0-9]{10}')), server('1234567890')) + }", "loanAmount":123.123 } """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") } - response { - status 200 - body("""{ + + } + response { + status 200 + body("""{ "fraudCheckStatus": "OK", - "rejectionReason": ${value(client(null), server(execute('assertThatRejectionReasonIsNull($it)')))} + "rejectionReason": ${ + value(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + } }""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - header 'Location': value( + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + header 'Location': value( stub(null), test(execute('assertThatLocationIsNull($it)')) - ) - } + ) } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - String test = blockBuilder.toString() + builder.appendTo(blockBuilder) + String test = blockBuilder.toString() then: - assertionStrings.each { String assertionString -> - assert test.contains(assertionString) - } + assertionStrings.each { String assertionString -> + assert test.contains(assertionString) + } where: - 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"))'''] + 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"))'''] } def "should support inner map and list definitions with #methodBuilderName"() { given: - Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) - Pattern ANYSTRING = Pattern.compile(/.*/) - Pattern NUMBERS = Pattern.compile(/[\d\.]*/) - Pattern DATETIME = ANYSTRING + Pattern PHONE_NUMBER = Pattern.compile(/[+\w]*/) + Pattern ANYSTRING = Pattern.compile(/.*/) + Pattern NUMBERS = Pattern.compile(/[\d\.]*/) + Pattern DATETIME = ANYSTRING - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" - headers { - header('Content-Type': 'application/json') - } - body( - client: [ - first_name : $(stub(regex(onlyAlphaUnicode())), test('Denis')), - last_name : $(stub(regex(onlyAlphaUnicode())), test('FakeName')), - email : $(stub(regex(email())), test('fakemail@fakegmail.com')), - fax : $(stub(PHONE_NUMBER), test('+xx001213214')), - phone : $(stub(PHONE_NUMBER), test('2223311')), - data_of_birth: $(stub(DATETIME), test('2002-10-22T00:00:00Z')) - ], - client_id_card: [ - id : $(stub(ANYSTRING), test('ABC12345')), - date_of_issue: $(stub(ANYSTRING), test('2002-10-02T00:00:00Z')), - address : [ - street : $(stub(ANYSTRING), test('Light Street')), - city : $(stub(ANYSTRING), test('Fire')), - region : $(stub(ANYSTRING), test('Skys')), - country: $(stub(ANYSTRING), test('HG')), - zip : $(stub(NUMBERS), test('658965')) - ] - ], - incomes_and_expenses: [ - monthly_income : $(stub(NUMBERS), test('0.0')), - monthly_loan_repayments: $(stub(NUMBERS), test('100')), - monthly_living_expenses: $(stub(NUMBERS), test('22')) - ], - additional_info: [ - allow_to_contact: $(stub(optional(regex(anyBoolean()))), test('true')) - ] - ) + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" + headers { + header('Content-Type': 'application/json') } - response { - status 200 - headers { - header('Content-Type': 'application/json') - } + body( + client: [ + first_name : $(stub(regex(onlyAlphaUnicode())), test('Denis')), + last_name : $(stub(regex(onlyAlphaUnicode())), test('FakeName')), + email : $(stub(regex(email())), test('fakemail@fakegmail.com')), + fax : $(stub(PHONE_NUMBER), test('+xx001213214')), + phone : $(stub(PHONE_NUMBER), test('2223311')), + data_of_birth: $(stub(DATETIME), test('2002-10-22T00:00:00Z')) + ], + client_id_card: [ + id : $(stub(ANYSTRING), test('ABC12345')), + date_of_issue: $(stub(ANYSTRING), test('2002-10-02T00:00:00Z')), + address : [ + street : $(stub(ANYSTRING), test('Light Street')), + city : $(stub(ANYSTRING), test('Fire')), + region : $(stub(ANYSTRING), test('Skys')), + country: $(stub(ANYSTRING), test('HG')), + zip : $(stub(NUMBERS), test('658965')) + ] + ], + incomes_and_expenses: [ + monthly_income : $(stub(NUMBERS), test('0.0')), + monthly_loan_repayments: $(stub(NUMBERS), test('100')), + monthly_living_expenses: $(stub(NUMBERS), test('22')) + ], + additional_info: [ + allow_to_contact: $(stub(optional(regex(anyBoolean()))), test('true')) + ] + ) + } + response { + status 200 + headers { + header('Content-Type': 'application/json') } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains bodyString - !test.contains("clientValue") - !test.contains("cursor") + test.contains bodyString + !test.contains("clientValue") + !test.contains("cursor") where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(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\\"' } def "shouldn't generate unicode escape characters with #methodBuilderName"() { given: - Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) + Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев" - headers { - header('Content-Type': 'application/json') - } - body( - client: [ - first_name: $(stub(ONLY_ALPHA_UNICODE), test('Пенева')), - last_name : $(stub(ONLY_ALPHA_UNICODE), test('Пенева')) - ] - ) + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев" + headers { + header('Content-Type': 'application/json') } - response { - status 200 - headers { - header('Content-Type': 'application/json') - } + body( + client: [ + first_name: $(stub(ONLY_ALPHA_UNICODE), test('Пенева')), + last_name : $(stub(ONLY_ALPHA_UNICODE), test('Пенева')) + ] + ) + } + response { + status 200 + headers { + header('Content-Type': 'application/json') } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - !test.contains("\\u041f") + !test.contains("\\u041f") where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('177') def "should generate proper test code when having multiline body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/multiline" - body('''hello, + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multiline" + body('''hello, World.''') - } - response { - status 200 - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.given(blockBuilder) - def test = blockBuilder.toString() + builder.given(blockBuilder) + def test = blockBuilder.toString() then: - test.contains(bodyString) + test.contains(bodyString) where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(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') def "should generate proper test code when having multipart parameters with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/multipart" - headers { - header('content-type', 'multipart/form-data;boundary=AaB03x') - } - multipart( - formParameter: value(client(regex('.+')), server('"formParameterValue"')), - someBooleanParameter: value(client(regex('(true|false)')), server('true')), - file: named(value(client(regex('.+')), server('filename.csv')), value(client(regex('.+')), server('file content'))) - ) - } - response { - status 200 + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + headers { + header('content-type', 'multipart/form-data;boundary=AaB03x') } + multipart( + formParameter: value(client(regex('.+')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named(value(client(regex('.+')), server('filename.csv')), value(client(regex('.+')), server('file content'))) + ) } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - for (String requestString : requestStrings) { - test.contains(requestString) - } + for (String requestString : requestStrings) { + test.contains(requestString) + } where: - 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());'] + 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());'] } @Issue('180') def "should generate proper test code when having multipart parameters with named as map with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "PUT" - url "/multipart" - multipart( - formParameter: value(client(regex('".+"')), server('"formParameterValue"')), - someBooleanParameter: value(client(regex('(true|false)')), server('true')), - file: named( - name: value(client(regex('.+')), server('filename.csv')), - content: value(client(regex('.+')), server('file content'))) - ) - } - response { - status 200 - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "PUT" + url "/multipart" + multipart( + formParameter: value(client(regex('".+"')), server('"formParameterValue"')), + someBooleanParameter: value(client(regex('(true|false)')), server('true')), + file: named( + name: value(client(regex('.+')), server('filename.csv')), + content: value(client(regex('.+')), server('file content'))) + ) } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.given(blockBuilder) - def test = blockBuilder.toString() + builder.given(blockBuilder) + def test = blockBuilder.toString() then: - test.contains('.multiPart') + test.contains('.multiPart') where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('#216') def "should parse JSON with arrays using #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method "GET" - urlPath('/auth/oauth/check_token') { - queryParameters { - parameter 'token': - value( - client(regex('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')), - server('6973b31d-7140-402a-bca6-1cdb954e03a7') - ) - } + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + urlPath('/auth/oauth/check_token') { + queryParameters { + parameter 'token': + value( + client(regex('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')), + server('6973b31d-7140-402a-bca6-1cdb954e03a7') + ) } } - response { - status 200 - body( - authorities: [ - value(stub('ROLE_ADMIN'), test(regex('^[a-zA-Z0-9_\\- ]+$'))) - ] - ) - } } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + body( + authorities: [ + value(stub('ROLE_ADMIN'), test(regex('^[a-zA-Z0-9_\\- ]+$'))) + ] + ) + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - test.contains('''assertThatJson(parsedJson).array("authorities").matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''') + test.contains('''assertThatJson(parsedJson).array("authorities").matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''') where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should work with execution property"() { given: - GroovyDsl contractDsl = GroovyDsl.make { - request { - method 'PUT' - url '/fraudcheck' - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) - ) - } - + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'PUT' + url '/fraudcheck' } - MethodBodyBuilder builder = methodBuilder(contractDsl) - BlockBuilder blockBuilder = new BlockBuilder(" ") + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + } + + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") when: - builder.appendTo(blockBuilder) - def test = blockBuilder.toString() + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() then: - !test.contains('''assertThatJson(parsedJson).field("rejectionReason").isEqualTo("assertThatRejectionReasonIsNull("''') - test.contains('''assertThatRejectionReasonIsNull(''') + !test.contains('''assertThatJson(parsedJson).field("rejectionReason").isEqualTo("assertThatRejectionReasonIsNull("''') + test.contains('''assertThatRejectionReasonIsNull(''') where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } - - -} + GroovyDsl dslForDocs = + // tag::dsl_example[] + io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/api/12' + headers { + header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json' + } + body '''\ + [{ + "created_at": "Sat Jul 26 09:38:57 +0000 2014", + "id": 492967299297845248, + "id_str": "492967299297845248", + "text": "Gonna see you at Warsaw", + "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" + } + }] + ''' + } + response { + status 200 + } + } + // end::dsl_example[] + } \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy index 37f40e1ba9..4e94ba6525 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy @@ -4,6 +4,7 @@ import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc import com.ofg.twitter.place.PairIdController import spock.lang.Specification +// tag::base_class[] abstract class BaseMockMvcSpec extends Specification { def setup() { @@ -19,3 +20,4 @@ abstract class BaseMockMvcSpec extends Specification { } } +// end::base_class[] diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/docs/asciidoc/contract.adoc index 7e2d7f7c97..000082923e 100644 --- a/docs/src/docs/asciidoc/contract.adoc +++ b/docs/src/docs/asciidoc/contract.adoc @@ -1,65 +1,28 @@ == Contract DSL -Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself. +Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only +a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself - + it's statically typed. Let's look at full example of a contract definition. + [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'POST' - urlPath('/users') { - queryParameters { - parameter 'limit': 100 - parameter 'offset': containing("1") - parameter 'filter': "email" - } - } - headers { - header 'Content-Type': 'application/json' - } - body '''{ "login" : "john", "name": "John The Contract" }''' - } - response { - status 200 - headers { - header 'Location': '/users/john' - } - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy[tags=dsl_example,indent=0] ---- Not all features of the DSL are used in example above. If you didn't find what you are looking for, please check next paragraphs on this page. > You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. -=== Top-Level Elements +=== HTTP Top-Level Elements Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - // Definition of HTTP request part of the contract - // (this can be a valid request or invalid depending - // on type of contract being specified). - request { - ... - } - - // Definition of HTTP response part of the contract - // (a service implementing this contract should respond - // with following response after receiving request - // specified in "request" part above). - response { - ... - } - - // Contract priority, which can be used for overriding - // contracts (1 is highest). Priority is optional. - priority 1 -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=http_dsl,indent=0] ---- === Request @@ -68,145 +31,43 @@ HTTP protocol requires only **method and address** to be specified in a request. [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - // HTTP request method (GET/POST/PUT/DELETE). - method 'GET' - - // Path component of request URL is specified as follows. - urlPath('/users') - } - - response { - ... - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=request,indent=0] ---- It is possible to specify whole `url` instead of just path, but `urlPath` is the recommended way as it makes the tests **host-independent**. [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'GET' +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=url,indent=0] - // Specifying `url` and `urlPath` in one contract is illegal. - url('http://localhost:8888/users') - } - - response { - ... - } -} ---- Request may contain **query parameters**, which are specified in a closure nested in a call to `urlPath` or `url`. [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - urlPath('/users') { - - // Each parameter is specified in form - // `'paramName' : paramValue` where parameter value - // may be a simple literal or one of matcher functions, - // all of which are used in this example. - queryParameters { - - // If a simple literal is used as value - // default matcher function is used (equalTo) - parameter 'limit': 100 - - // `equalTo` function simply compares passed value - // using identity operator (==). - parameter 'filter': equalTo("email") - - // `containing` function matches strings - // that contains passed substring. - parameter 'gender': containing("[mf]") - - // `matching` function tests parameter - // against passed regular expression. - parameter 'offset': matching("[0-9]+") - - // `notMatching` functions tests if parameter - // does not match passed regular expression. - parameter 'loginStartsWith': notMatching(".{0,2}") - } - } - - ... - } - - response { - ... - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=urlpath,indent=0] ---- It may contain additional **request headers**... [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // Each header is added in form `'Header-Name' : 'Header-Value'`. - headers { - header 'Content-Type': 'application/json' - } - - ... - } - - response { - ... - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=headers,indent=0] ---- ...and a **request body**. [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // JSON and XML formats of request body are supported. - // Format will be determined from a header or body's content. - body '''{ "login" : "john", "name": "John The Contract" }''' - } - - response { - ... - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=body,indent=0] ---- **Body's format** can also be specified explicitly by invoking one of format functions. [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - - // In this case body will be formatted as XML. - body equalToXml( - '''johnJohn The Contract''' - ) - } - - response { - ... - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=bodyAsXml,indent=0] ---- === Response @@ -215,54 +76,21 @@ Minimal response must contain **HTTP status code**. [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - ... - } - response { - // Status code sent by the server - // in response to request specified above. - status 200 - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=response,indent=0] ---- Besides status response may contain **headers** and **body**, which are specified the same way as in the request (see previous paragraph). === Regular expressions -You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both for your test and your server side tests. +You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response +should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both +for your test and your server side tests. - Please see the example below: +Please see the example below: [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl groovyDsl == GroovyDsl.make { - request { - method('GET') - url $(client(~/\/[0-9]{2}/), server('/12')) - } - response { - status 200 - body( - id: value( - client('123'), - server(regex('[0-9]+')) - ), - surname: $( - client('Kowalsky'), - server('Lewandowski') - ), - name: 'Jan', - created: $(client('2014-02-02 12:23:43'), server({ currentDate(it) })) - correlationId: value(client('5d1f9fef-e0dc-4f3d-a7e4-72d2220dd827'), - server(regex('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') - ) - ) - headers { - header 'Content-Type': 'text/plain' - } - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=regex,indent=0] ---- === Passing optional parameters @@ -276,131 +104,41 @@ Example: [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - priority 1 - request { - method 'POST' - url '/users/password' - headers { - header 'Content-Type': 'application/json' - } - body( - email: $(stub(optional(regex(email()))), test('abc@abc.com')), - callback_url: $(stub(regex(hostname())), test('http://partners.com')) - ) - } - response { - status 404 - headers { - header 'Content-Type': 'application/json' - } - body( - code: value(stub("123123"), test(optional("123123"))), - message: "User not found by email == [${value(test(regex(email())), stub('not.existing@user.com'))}]" - ) - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=optionals,indent=0] ---- By wrapping a part of the body with the `optional()` method you are in fact creating a regular expression that should be present 0 or more times. -That way for the example above the following test would be generated: +That way for the example above the following test would be generated if you pick Spock: [source,groovy,indent=0] ---- - given: - def request == given() - .header('Content-Type', 'application/json') - .body('{"email":"abc@abc.com","callback_url":"http://partners.com"}') - - when: - def response == given().spec(request) - .post("/users/password") - - then: - response.statusCode === 404 - response.header('Content-Type') === 'application/json' - and: - DocumentContext parsedJson == JsonPath.parse(response.body.asString()) - !parsedJson.read('''$[?(@.code =~ /(123123)?/)]''', JSONArray).empty - !parsedJson.read('''$[?(@.message =~ /User not found by email == \\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}\\]/)]''', JSONArray).empty - +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=optionals_test,indent=0] ---- and the following stub: [source,javascript,indent=0] ---- -{ - "request" : { - "url" : "/users/password", - "method" : "POST", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/)]" - }, { - "matchesJsonPath" : "$[?(@.email =~ /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4})?/)]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - } - }, - "response" : { - "status" : 404, - "body" : "{\"code\":\"123123\",\"message\":\"User not found by email == [not.existing@user.com]\"}", - "headers" : { - "Content-Type" : "application/json" - } - }, - "priority" : 1 -} +include::../../../../accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverterSpec.groovy[tags=wiremock,indent=0] ---- === Executing custom methods on server side -It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. Please see the examples below: +It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" +in the configuration. Please see the examples below: ==== Groovy DSL [source,groovy,indent=0] ---- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - body ( - path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), - correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) - ) - status 200 - } -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=method,indent=0] ---- ==== Base Mock Spec [source,groovy,indent=0] ---- -abstract class BaseMockMvcSpec extends Specification { - - def setup() { - RestAssuredMockMvc.standaloneSetup(new PairIdController()) - } - - void isProperCorrelationId(Integer correlationId) { - assert correlationId === 123456 - } -} +include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] ---- === JAX-RS support @@ -419,43 +157,5 @@ Example of a test API generated: [source,groovy,indent=0] ---- -class FraudDetectionServiceSpec extends MvcSpec { - - def shouldMarkClientAsNotFraud() { - when: - def response == webTarget - .path('/fraudcheck') - .request() - .method('put', entity('{"clientPesel":"1234567890","loanAmount":123.123}', 'application/vnd.fraud.v1+json')) - - String responseAsString == response.readEntity(String) - - then: - response.status === 200 - response.getHeaderString('Content-Type') === 'application/vnd.fraud.v1+json' - and: - def responseBody == new JsonSlurper().parseText(responseAsString) - responseBody.fraudCheckStatus === "OK" - assertThatRejectionReasonIsNull(responseBody.rejectionReason) - } - - def shouldMarkClientAsFraud() { - when: - def response == webTarget - .path('/fraudcheck') - .request() - .method('put', entity('{"clientPesel":"1234567890","loanAmount":99999}', 'application/vnd.fraud.v1+json')) - - String responseAsString == response.readEntity(String) - - then: - response.status === 200 - response.getHeaderString('Content-Type') === 'application/vnd.fraud.v1+json' - and: - def responseBody == new JsonSlurper().parseText(responseAsString) - responseBody.fraudCheckStatus ==~ java.util.regex.Pattern.compile('[A-Z]{5}') - responseBody.rejectionReason === "Amount too high" - } - -} +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy[tags=jaxrs,indent=0] ---- \ No newline at end of file diff --git a/docs/src/docs/asciidoc/images/Deps.png b/docs/src/docs/asciidoc/images/Deps.png new file mode 100644 index 0000000000000000000000000000000000000000..1426814308101b8ccf6ef95fd195e37c0a180392 GIT binary patch literal 37192 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 A(f|Me literal 0 HcmV?d00001 diff --git a/docs/src/docs/asciidoc/images/Stubs1.png b/docs/src/docs/asciidoc/images/Stubs1.png new file mode 100644 index 0000000000000000000000000000000000000000..ebadfdb91014284b917367e3d9c9c8a137da3993 GIT binary patch literal 35170 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 literal 0 HcmV?d00001 diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index a1d3a7eb8b..060f611643 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -2,36 +2,14 @@ Welcome to the Accurest Documentation! include::introduction.adoc[] -include::rest.adoc[] - include::contract.adoc[] +include::rest.adoc[] + include::messaging.adoc[] include::stubrunner.adoc[] include::stubrunner_msg.adoc[] -== Migration Guide - -=== Migration to 0.4.7 -- in 0.4.7 we've fixed package name (coderate to codearte) so you've to do the same in your projects. This means replacing ```io.coderate.accurest.dsl.GroovyDsl``` with ```io.codearte.accurest.dsl.GroovyDsl``` - -=== Migration to 1.0.0-RC1 -- from 1.0.0 we're distinguish ignored contracts from excluded contracts: - - `excludedFiles` pattern tells Accurest to skip processing those files at all - - `ignoredFiles` pattern tells Accurest to generate contracts and tests, but tests will be marked as `@Ignore` - -- from 1.0.0 the `basePackageForTests` behaviour has changed - - prior to the change all DSL files had to be under `contractsDslDir`/`basePackageForTests`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - - now all DSL files have to be under `contractsDslDir`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage* - -=== Migration to 1.0.7 -- from 1.0.7 we're setting JUnit as a default testing utility. You have to pass the following option to keep Spock -as your first choice: - -[source,groovy] ----- -include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=target_framework,indent=0] ----- \ No newline at end of file +include::migration.adoc[] \ No newline at end of file diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc index 6714efb910..f7ac2b0c17 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -1,26 +1,80 @@ == Introduction -Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __REST Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: +Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped +with __Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: -* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). Test code must still be written by hand, test data is produced by Accurest. -* Acceptance tests (in Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by Accurest. +* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). +Test code must still be written by hand, test data is produced by Accurest. +* Messaging routes if you're using one. We're integrating with Spring Integration, Spring Cloud Stream and Apache Camel. You can however set your own integrations if you want to +* Acceptance tests (in JUnit or Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by Accurest. Accurest moves TDD to the level of software architecture. === Why? -The main purposes of Accurest are: +Let us assume that we have a system comprising of multiple microservices: - - to ensure that WireMock stubs (used when developing the client) are doing exactly what actual server-side implementation will do, +image::Deps.png[Microservices Architecture] + +==== Testing issues + +If we wanted to test the application in top left corner if it can communicate with other services then we could do one of two things: + +- deploy all microservices and perform end to end tests +- mock other microservices in unit / integration tests + +Both have their advantages but also a lot of disadvantages. Let's focus on the latter. + +*Deploy all microservices and perform end to end tests* + +Advantages: +- simulates production +- tests real communication between services + +Disadvantages: +- to test one microservice we would have to deploy 6 microservices, a couple of databases etc. +- the environment where the tests would be conducted would be locked for a single suite of tests (i.e. nobody else would be able to run the tests in the meantime). +- long to run +- very late feedback +- extremely hard to debug + +*Mock other microservices in unit / integration tests* + +Advantages: +- very fast feedback +- no infrastructure requirements + +Disadvantages: +- the implementor of the service creates stubs thus they might have nothing to do with the reality +- you can go to production with passing tests and failing production + +To solve the aforementioned issues Accurest with Stub Runner were created. Their main idea is to give you very fast feedback, without the need +to set up the whole world of microservices. + +image::Stubs1.png[Stubbed Services] + +If you work on stubs then the only applications you need are those that your application is using directly. + +image::Stubs2.png[Stubbed Services] + +Accurest gives you the certainty that the stubs that you're using were created by the service that you're calling. Also if you can use them it means that they were +tested against the producer's side. In other words - you can trust those stubs. + + +=== Purposes + +The main purposes of Accurest with Stub Runner are: + + - to ensure that WireMock / Messaging stubs (used when developing the client) are doing exactly what actual server-side implementation will do, - to promote ATDD method and Microservices architectural style, - to provide a way to publish changes in contracts that are immediately visible on both sides, - to generate boilerplate test code used on the server side. === Client Side -During the tests you want to have a Wiremock instance up and running that simulates the service Y. +During the tests you want to have a Wiremock instance / Messaging route 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. +to be valid and 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. @@ -37,52 +91,20 @@ 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. -=== Examples +=== Dependencies -[source,groovy,indent=0] ----- -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/api/12' - headers { - header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json' - } - body '''\ - [{ - "created_at": "Sat Jul 26 09:38:57 +0000 2014", - "id": 492967299297845248, - "id_str": "492967299297845248", - "text": "Gonna see you at Warsaw", - "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" - } - }] -''' - } - response { - status 200 - } -} ----- +Accurest and Stub Runner are using the following libraries -//TODO: Add videos, slides \ No newline at end of file +- http://wiremock.org/[WireMock] +- https://github.com/jayway/JsonPath[Jayway JSONPath] +- https://github.com/marcingrzejszczak/jsonassert[JSONAssert from Marcin Grzejszczak] + +=== Additional readings / videos + +Below you can find some resources related to Accurest and Stub Runner. Note that some can be outdated since the Accurest project +is under constant development. + +- https://www.youtube.com/watch?v=daafmTYFoDU[Olga Maciaszek-Sharma talking about Accurest] +- https://vimeo.com/130779882[Marcin Grzejszczak and Jakub Kubrynski talking about Accurest] +- http://www.slideshare.net/MarcinGrzejszczak/stick-to-the-rules-consumer-driven-contracts-201507-confitura[Slides from Marcin Grzejszczak's talk about Accurest] +- http://toomuchcoding.com/blog/categories/accurest/[Accurest article from Marcin Grzejszczak's blog] diff --git a/docs/src/docs/asciidoc/migration.adoc b/docs/src/docs/asciidoc/migration.adoc new file mode 100644 index 0000000000..8ddc214619 --- /dev/null +++ b/docs/src/docs/asciidoc/migration.adoc @@ -0,0 +1,23 @@ +== Migration Guide + +=== Migration to 0.4.7 +- in 0.4.7 we've fixed package name (coderate to codearte) so you've to do the same in your projects. This means replacing ```io.coderate.accurest.dsl.GroovyDsl``` with ```io.codearte.accurest.dsl.GroovyDsl``` + +=== Migration to 1.0.0-RC1 +- from 1.0.0 we're distinguish ignored contracts from excluded contracts: + - `excludedFiles` pattern tells Accurest to skip processing those files at all + - `ignoredFiles` pattern tells Accurest to generate contracts and tests, but tests will be marked as `@Ignore` + +- from 1.0.0 the `basePackageForTests` behaviour has changed + - prior to the change all DSL files had to be under `contractsDslDir`/`basePackageForTests`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation + - now all DSL files have to be under `contractsDslDir`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation + - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage* + +=== Migration to 1.0.7 +- from 1.0.7 we're setting JUnit as a default testing utility. You have to pass the following option to keep Spock +as your first choice: + +[source,groovy] +---- +include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=target_framework,indent=0] +---- \ No newline at end of file From 767d414605ede741e245456fbebcf3dcec8f893c Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 24 Apr 2016 21:17:40 +0200 Subject: [PATCH 544/719] small fixes - mostly maven related [ci skip] --- docs/src/docs/asciidoc/rest.adoc | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index cdad848333..d17bf16a7c 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -49,7 +49,7 @@ dependencies { ---- -Read more: https://github.com/Codearte/accurest-maven-plugin[accurest-maven-plugin] +Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugin] ===== Add stubs @@ -58,8 +58,11 @@ Directory containing stub definitions is treated as a class name, and each stub 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.groovy -src/test/resources/stubs/myservice/shouldReturnUser.groovy +[source,groovy,indent=0] +---- +src/test/accurest/myservice/shouldCreateUser.groovy +src/test/accurest/myservice/shouldReturnUser.groovy +---- Accurest will create test class `defaultBasePackage.MyService` with two methods - shouldCreateUser() @@ -94,7 +97,7 @@ accurest { - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/accurest` - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `$buildDir/generated-test-sources/accurest` - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed - - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework + - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with JUnit being the default framework ===== Base class for tests @@ -176,7 +179,7 @@ Underneath LoanApplication makes a call to FraudDetection service. This request ---- -Read more: [accurest-maven-plugin](https://github.com/Codearte/accurest-maven-plugin) +Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugin] ==== Add stubs @@ -224,17 +227,17 @@ To change default configuration just add `configuration` section to plugin defin ---- -===== Configuration options +===== Important configuration options - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification`. - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/accurest`. - - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `target/generated-test-sources/accurest`. - - **mappingsDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed. - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework +For complete information take a look at http://codearte.github.io/accurest-maven-plugin/plugin-info.html[Plugin Documentation] + ===== Base class for tests When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. @@ -307,7 +310,7 @@ Sample configuration: io.codearte.accurest accurest-maven-plugin - ${accurest.version} + ${accurest-plugin.version} From 204637159e4a39aae29e58ce6344da083b068b34 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 21:54:16 +0200 Subject: [PATCH 545/719] Updated docs --- .../config/AccurestConfigProperties.groovy | 4 -- .../builder/ContractHttpDocsSpec.groovy | 36 ++++++++-------- .../JaxRsClientMethodBuilderSpec.groovy | 13 +++--- .../plugin/AccurestGradlePlugin.groovy | 7 +++- docs/src/docs/asciidoc/contract.adoc | 31 +++++++++++++- docs/src/docs/asciidoc/index.adoc | 2 - docs/src/docs/asciidoc/introduction.adoc | 18 ++++++-- docs/src/docs/asciidoc/rest.adoc | 42 ++++++++++--------- docs/src/docs/asciidoc/stubrunner_msg.adoc | 28 ------------- 9 files changed, 96 insertions(+), 85 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy index 253887ae7b..53567ed1a2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy @@ -75,8 +75,4 @@ class AccurestConfigProperties { */ File stubsOutputDir - /** - * Which version of Accurest Messaging Core to use - */ - String accurestMessagingCoreVersion = "+" } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy index 235e8184b5..d8610d92a9 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy @@ -232,8 +232,7 @@ class ContractHttpDocsSpec extends Specification { header 'Content-Type': 'application/json' } body( - code: value(stub("123123"), test(optional("123123"))), - message: "User not found by email == [${value(test(regex(email())), stub('not.existing@user.com'))}]" + code: value(stub("123123"), test(optional("123123"))) ) } } @@ -244,28 +243,27 @@ class ContractHttpDocsSpec extends Specification { BlockBuilder blockBuilder = new BlockBuilder(" ") new MockMvcSpockMethodRequestProcessingBodyBuilder(optionals).appendTo(blockBuilder) expect: - stripped(blockBuilder.toString()) == stripped( + String expectedTest = // tag::optionals_test[] """ -given: - def request = given() - .header('Content-Type', 'application/json') - .body('''{"email":"abc@abc.com","callback_url":"http://partners.com"}''') + given: + def request = given() + .header('Content-Type', 'application/json') + .body('''{"email":"abc@abc.com","callback_url":"http://partners.com"}''') -when: - def response = given().spec(request) - .post("/users/password") + when: + def response = given().spec(request) + .post("/users/password") -then: - response.statusCode == 404 - response.header('Content-Type') == 'application/json' -and: - DocumentContext parsedJson = JsonPath.parse(response.body.asString()) - assertThatJson(parsedJson).field("message").matches("User not found by email == \\\\\\\\[[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\\\\\.[a-zA-Z]{2,4}\\\\\\\\]") - assertThatJson(parsedJson).field("code").matches("(123123)?") + then: + response.statusCode == 404 + response.header('Content-Type') == 'application/json' + and: + DocumentContext parsedJson = JsonPath.parse(response.body.asString()) + assertThatJson(parsedJson).field("code").matches("(123123)?") """ // end::optionals_test[] -) + stripped(blockBuilder.toString()) == stripped(expectedTest) } GroovyDsl method = @@ -294,6 +292,6 @@ and: // end::method[] private String stripped(String string) { - return string.stripMargin().stripIndent().replace('\t', '').replace('\n', '') + return string.stripMargin().stripIndent().replace('\t', '').replace('\n', '').replace(' ','') } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy index 3d36d7676f..59a33c47c1 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy @@ -615,8 +615,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub status 200 body """ { - "property1": "a", - "property2": "b" + "property1": "a" } """ } @@ -627,8 +626,9 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped( // tag::jaxrs[] - ''' + String expectedResponse = +// tag::jaxrs[] +''' // when: Response response = webTarget .path("/users") @@ -650,15 +650,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub // and: DocumentContext parsedJson = JsonPath.parse(responseAsString); assertThatJson(parsedJson).field("property1").isEqualTo("a"); - assertThatJson(parsedJson).field("property2").isEqualTo("b"); ''' // end::jaxrs[] -) + stripped(test) == stripped(expectedResponse) and: stubMappingIsValidWireMockStub(contractDsl) } private String stripped(String string) { - return string.stripMargin().stripIndent().replace('\t', '').replace('\n', '') + return string.stripMargin().stripIndent().replace('\t', '').replace('\n', '').replace(' ','') } } 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 bf0edc316e..9709541e2d 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 @@ -38,6 +38,7 @@ class AccurestGradlePlugin implements Plugin { project.idea { module { testSourceDirs += extension.generatedTestSourcesDir + testSourceDirs += extension.contractsDslDir } } } @@ -47,11 +48,15 @@ class AccurestGradlePlugin implements Plugin { void setConfigurationDefaults(AccurestConfigProperties extension) { extension.with { generatedTestSourcesDir = project.file("${project.buildDir}/generated-test-sources/accurest") - contractsDslDir = project.file("${project.rootDir}/src/test/accurest") //TODO: Use sourceset + contractsDslDir = defaultAccurestContractsDir() //TODO: Use sourceset basePackageForTests = 'io.codearte.accurest.tests' } } + private File defaultAccurestContractsDir() { + project.file("${project.rootDir}/src/test/accurest") + } + private void createGenerateTestsTask(AccurestConfigProperties extension) { Task task = project.tasks.create(GENERATE_SERVER_TESTS_TASK_NAME, GenerateServerTestsTask) task.description = "Generate server tests from GroovyDSL" diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/docs/asciidoc/contract.adoc index 000082923e..a028da70cb 100644 --- a/docs/src/docs/asciidoc/contract.adoc +++ b/docs/src/docs/asciidoc/contract.adoc @@ -158,4 +158,33 @@ Example of a test API generated: [source,groovy,indent=0] ---- include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy[tags=jaxrs,indent=0] ----- \ No newline at end of file +---- + +=== Messaging Top-Level Elements + +The DSL for messaging looks a little bit different than the one that focuses on HTTP. + +==== Output triggered by a method + +The output message can be triggered by calling a method (e.g. a Scheduler was started and a message was sent) + +[source,groovy] +---- +include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=method_trigger,indent=0] +---- + +In this case the output message will be sent to `output` if a method called `bookReturnedTriggered` will be executed. In the message *publisher's* side +we will generate a test that will call that method to trigger the message. On the *consumer* side you can use the `some_label` to trigger the message. + +==== Output triggered by a message + +The output message can be triggered by receiving a message. + +[source,groovy] +---- +include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=message_trigger,indent=0] +---- + +In this case the output message will be sent to `output` if a proper message will be received on the `input` destination. In the message *publisher's* side +we will generate a test that will send the input message to the defined destination. On the *consumer* side you can either send a message to the input +destination or use the `some_label` to trigger the message. \ No newline at end of file diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 060f611643..2cd9d4ea76 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,5 +1,3 @@ -Welcome to the Accurest Documentation! - include::introduction.adoc[] include::contract.adoc[] diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc index f7ac2b0c17..07808673b8 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -99,12 +99,22 @@ Accurest and Stub Runner are using the following libraries - https://github.com/jayway/JsonPath[Jayway JSONPath] - https://github.com/marcingrzejszczak/jsonassert[JSONAssert from Marcin Grzejszczak] -=== Additional readings / videos +=== Additional links Below you can find some resources related to Accurest and Stub Runner. Note that some can be outdated since the Accurest project is under constant development. -- https://www.youtube.com/watch?v=daafmTYFoDU[Olga Maciaszek-Sharma talking about Accurest] -- https://vimeo.com/130779882[Marcin Grzejszczak and Jakub Kubrynski talking about Accurest] +==== Videos + +*Olga Maciaszek-Sharma talking about Accurest* + +video::daafmTYFoDU[youtube] + +*Marcin Grzejszczak and Jakub Kubrynski talking about Accurest* + +video::130779882[vimeo] + +==== Readings + - http://www.slideshare.net/MarcinGrzejszczak/stick-to-the-rules-consumer-driven-contracts-201507-confitura[Slides from Marcin Grzejszczak's talk about Accurest] -- http://toomuchcoding.com/blog/categories/accurest/[Accurest article from Marcin Grzejszczak's blog] +- http://toomuchcoding.com/blog/categories/accurest/[Accurest related articles from Marcin Grzejszczak's blog] diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index d17bf16a7c..ade4477aa9 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -15,7 +15,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'io.codearte.accurest:accurest-gradle-plugin:1.0.6' + classpath 'io.codearte.accurest:accurest-gradle-plugin:${accurest_version}' } } @@ -23,7 +23,7 @@ apply plugin: 'groovy' apply plugin: 'accurest' dependencies { - testCompile('org.codehaus.groovy:groovy-all:2.4.6') + testCompile 'org.codehaus.groovy:groovy-all:2.4.6' testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' // needed if you're going to use Spring MockMvc } @@ -53,7 +53,8 @@ Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugi ===== Add stubs -By default Accurest is looking for stubs in src/test/resources/stubs directory. +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 @@ -65,8 +66,8 @@ src/test/accurest/myservice/shouldReturnUser.groovy ---- Accurest will create test class `defaultBasePackage.MyService` with two methods - - shouldCreateUser() - - shouldReturnUser() + - `shouldCreateUser()` + - `shouldReturnUser()` ==== Run plugin @@ -105,29 +106,32 @@ accurest { [source,groovy,indent=0] ---- -package org.mycompany.tests - -import org.mycompany.ExampleSpringController -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new ExampleSpringController()) - } -} +include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] ---- -In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. +In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class +should also contain `protected WebTarget webTarget` field, right now the only option to test JAX-RS API is to start a web server. ==== Invoking generated tests To ensure that provider side is complaint with defined contracts, you need to invoke: -`./gradlew generateAccurest test` + +[source,bash,indent=0] +---- +./gradlew generateAccurest test +---- ==== Accurest on consumer side -In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/stubs and generate Wiremock json stubs using: `./gradlew generateWireMockClientStubs` command. Note that `stubsOutputDir` option has to be set for stub generation to work. +In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. If you don't want to use Stub Runner then you need to copy contracts stored in +`src/test/accurest` and generate WireMock json stubs using: + +[source,bash,indent=0] +---- +./gradlew generateWireMockClientStubs +---- + +command. Note that `stubsOutputDir` option has to be set for stub generation to work. When present, json stubs can be used in consumer automated tests. diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc index 2548584162..482dae2e01 100644 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -10,34 +10,6 @@ Stub Runner has the functionality to run the published stubs in memory. It can i It also provides points of entry to integrate with any other solution on the market. -=== DSL - -The DSL for messaging looks a little bit different than the one that focuses on HTTP. - -==== Output triggered by a method - -The output message can be triggered by calling a method (e.g. a Scheduler was started and a message was sent) - -[source,groovy] ----- -include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=method_trigger,indent=0] ----- - -In this case the output message will be sent to `output` if a method called `bookReturnedTriggered` will be executed. In the message *publisher's* side -we will generate a test that will call that method to trigger the message. On the *consumer* side you can use the `some_label` to trigger the message. - -==== Output triggered by a message - -The output message can be triggered by receiving a message. - -[source,groovy] ----- -include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=message_trigger,indent=0] ----- - -In this case the output message will be sent to `output` if a proper message will be received on the `input` destination. In the message *publisher's* side -we will generate a test that will send the input message to the defined destination. On the *consumer* side you can either send a message to the input -destination or use the `some_label` to trigger the message. === Stub triggering From 26afe17ec5b3e58ef0b558d33eee3240d0be20bb Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 22:08:46 +0200 Subject: [PATCH 546/719] Updated docs --- docs/src/docs/asciidoc/contract.adoc | 2 + docs/src/docs/asciidoc/index.adoc | 2 + docs/src/docs/asciidoc/messaging.adoc | 2 +- docs/src/docs/asciidoc/stubrunner_msg.adoc | 3 +- stub-runner/stub-runner-junit/README.adoc | 72 ++----------------- .../junit/AccurestRuleJUnitTest.java | 10 ++- .../stubrunner/junit/AccurestRuleSpec.groovy | 2 + .../stub-runner-spring-cloud/README.adoc | 3 +- stub-runner/stub-runner-spring/README.adoc | 31 +------- .../spring/StubRunnerConfigurationSpec.groovy | 2 + stub-runner/stub-runner/README.adoc | 13 ++-- 11 files changed, 35 insertions(+), 107 deletions(-) diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/docs/asciidoc/contract.adoc index a028da70cb..1e8fb9b780 100644 --- a/docs/src/docs/asciidoc/contract.adoc +++ b/docs/src/docs/asciidoc/contract.adoc @@ -162,6 +162,8 @@ include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ === Messaging Top-Level Elements +WARNING: Feature available since {messaging_version} + The DSL for messaging looks a little bit different than the one that focuses on HTTP. ==== Output triggered by a method diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 2cd9d4ea76..3447efe7db 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,3 +1,5 @@ +:messaging_version: 1.0.7 + include::introduction.adoc[] include::contract.adoc[] diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc index 037d49cb24..e47549ef98 100644 --- a/docs/src/docs/asciidoc/messaging.adoc +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -1,6 +1,6 @@ == Accurest Messaging -WARNING: Feature available since 1.0.7 +WARNING: Feature available since {messaging_version} Accurest allows you to verify your application that uses messaging as means of communication. All of our integrations are working with Spring but you can also set one yourself. diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc index 482dae2e01..76bf5c241e 100644 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -1,6 +1,6 @@ == Stub Runner for Messaging -WARNING: Feature available since 1.0.7 +WARNING: Feature available since {messaging_version} Stub Runner has the functionality to run the published stubs in memory. It can integrate with the following frameworks out of the box @@ -10,7 +10,6 @@ Stub Runner has the functionality to run the published stubs in memory. It can i It also provides points of entry to integrate with any other solution on the market. - === Stub triggering To trigger a message it's enough to use the `StubTiggerer` interface: diff --git a/stub-runner/stub-runner-junit/README.adoc b/stub-runner/stub-runner-junit/README.adoc index 23b995c55f..ff253fa537 100644 --- a/stub-runner/stub-runner-junit/README.adoc +++ b/stub-runner/stub-runner-junit/README.adoc @@ -4,11 +4,7 @@ Stub Runner comes with a JUnit rule thanks to which you can very easily download [source,java,indent=0] ---- -@ClassRule public static AccurestRule rule == new AccurestRule() - .repoRoot("http://your.repo.com") - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") - .downloadStub("io.codearte:stub1", "io.codearte:stub2:classifier", "io.codearte:stub3"); +include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java[tags=classrule] ---- After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to: @@ -25,81 +21,21 @@ Since the `AccurestRule` implements the `StubFinder` it allows you to find the s [source,groovy,indent=0] ---- -interface StubFinder { - /** - * For the given groupId and artifactId tries to find the matching - * URL of the running stub. - * - * @param groupId - might be null. In that case a search only via artifactId takes place - * @return URL of a running stub or null if not found - */ - URL findStubUrl(String groupId, String artifactId) - - /** - * For the given Ivy notation {@code groupId:artifactId} tries to find the matching - * URL of the running stub. You can also pass only {@code artifactId}. - * - * @param ivyNotation - Ivy representation of the Maven artifact - * @return URL of a running stub or null if not found - */ - URL findStubUrl(String ivyNotation) - - /** - * Returns all running stubs - */ - RunningStubs findAllRunningStubs() -} +include::../stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy[] ---- Example of usage in Spock tests: [source,groovy,indent=0] ---- -@ClassRule @Shared AccurestRule rule == new AccurestRule() - .repoRoot('http://your.repo.com') - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') !== null - rule.findStubUrl('loanIssuance') !== null - rule.findStubUrl('loanIssuance') === rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') !== null - and: - rule.findAllRunningStubs().isPresent('loanIssuance') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text === 'loanIssuance' - "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text === 'fraudDetectionServer' - } +include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.java[tags=classrule] ---- Example of usage in JUnit tests: [source,java,indent=0] ---- -@ClassRule public static AccurestRule rule == new AccurestRule() - .repoRoot("http://your.repo.com") - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); - - @Test - public void should_start_wiremock_servers() throws Exception { - // expect: 'WireMocks are running' - then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")); - then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull(); - // and: - then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue(); - // and: 'Stubs were registered' - then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); - then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); - } +include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java[tags=test] ---- Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java index 8b6b237925..db2719191d 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java @@ -1,14 +1,14 @@ package io.codearte.accurest.stubrunner.junit; +import java.io.InputStream; +import java.net.URI; + import org.apache.commons.io.IOUtils; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Test; -import java.io.InputStream; -import java.net.URI; - import static org.assertj.core.api.BDDAssertions.then; /** @@ -23,11 +23,14 @@ public class AccurestRuleJUnitTest { System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); } + // tag:classrule[] @ClassRule public static AccurestRule rule = new AccurestRule() .repoRoot(repoRoot()) .downloadStub("io.codearte.accurest.stubs", "loanIssuance") .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); + // end:classrule[] + // tag:test[] @Test public void should_start_wiremock_servers() throws Exception { // expect: 'WireMocks are running' @@ -43,6 +46,7 @@ public class AccurestRuleJUnitTest { then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); } + // end:test[] private static String repoRoot() { try { diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy index 91f693c113..1883c8b5d8 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy @@ -18,6 +18,7 @@ class AccurestRuleSpec extends Specification { System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); } + // tag:classrule[] @ClassRule @Shared AccurestRule rule = new AccurestRule() .repoRoot(AccurestRuleSpec.getResource("/m2repo").toURI().toString()) .downloadStub("io.codearte.accurest.stubs", "loanIssuance") @@ -37,4 +38,5 @@ class AccurestRuleSpec extends Specification { "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' } + // end:classrule[] } diff --git a/stub-runner/stub-runner-spring-cloud/README.adoc b/stub-runner/stub-runner-spring-cloud/README.adoc index 003b94422f..d874c8f9d6 100644 --- a/stub-runner/stub-runner-spring-cloud/README.adoc +++ b/stub-runner/stub-runner-spring-cloud/README.adoc @@ -9,7 +9,8 @@ io.codearte.accurest:stub-runner-spring-cloud and the Stub Runner autoconfiguration should be picked up. -You can match the artifactId of the stub with the name of your app by using the `stubrunner.stubs.idsToServiceIds:` map. +==== Additional Configuration +You can match the artifactId of the stub with the name of your app by using the `stubrunner.stubs.idsToServiceIds:` map. You can disable Stub Runner Ribbon support by providing: `stubrunner.cloud.ribbon.enabled` equal to `false` You can disable Stub Runner support by providing: `stubrunner.cloud.enabled` equal to `false` \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/README.adoc b/stub-runner/stub-runner-spring/README.adoc index 0d87fe9146..7d07363bdb 100644 --- a/stub-runner/stub-runner-spring/README.adoc +++ b/stub-runner/stub-runner-spring/README.adoc @@ -10,37 +10,12 @@ its methods as presented below: [source,groovy,indent=0] ---- -@ContextConfiguration(classes == Config, loader == SpringApplicationContextLoader) -class StubRunnerConfigurationSpec extends Specification { - - @Autowired StubFinder stubFinder - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') !== null - stubFinder.findStubUrl('loanIssuance') !== null - stubFinder.findStubUrl('loanIssuance') === stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') !== null - and: - stubFinder.findAllRunningStubs().isPresent('loanIssuance') - stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text === 'loanIssuance' - "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text === 'fraudDetectionServer' - } - - @Configuration - @Import(StubRunnerConfiguration) - @EnableAutoConfiguration - static class Config {} -} +include::src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=test] ---- for the following configuration file: -[source,groovy,indent=0] +[source,yml,indent=0] ---- -stubrunner.stubs.repository.root: classpath:m2repo -stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer +include::src/test/resources/application.yml[tags=test] ---- \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy b/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy index b43cd14143..a6800015b6 100644 --- a/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy +++ b/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy @@ -12,6 +12,7 @@ import spock.lang.Specification /** * @author Marcin Grzejszczak */ +// tag::test[] @ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) class StubRunnerConfigurationSpec extends Specification { @@ -37,3 +38,4 @@ class StubRunnerConfigurationSpec extends Specification { @EnableAutoConfiguration static class Config {} } +// end::test[] \ No newline at end of file diff --git a/stub-runner/stub-runner/README.adoc b/stub-runner/stub-runner/README.adoc index 102a4225cf..d6dd566c1f 100644 --- a/stub-runner/stub-runner/README.adoc +++ b/stub-runner/stub-runner/README.adoc @@ -3,6 +3,9 @@ Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of http://martinfowler.com/articles/consumerDrivenContracts.html[Consumer Driven Contracts]. +Stub Runner allows you to automatically download the stubs of the provided dependencies, start WireMock servers for them and feed them with proper stub definitions. +For messaging, special stub routes are defined. + ==== Running stubs ===== Running using main app @@ -64,7 +67,7 @@ or each parameter separately with a `-P` prefix and without the hyphen `-` in th ./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h ---- -===== Stubs +===== HTTP Stubs Stubs are defined in JSON documents, whose syntax is defined in http://wiremock.org/stubbing.html[WireMock documentation] @@ -87,8 +90,10 @@ Example: } ---- -In the provided JAR file we're harvesting all JSON files and try to put them inside running WireMock instance. - ===== Viewing registered mappings -Every stubbed collaborator exposes list of defined mappings under `__/admin/` endpoint. \ No newline at end of file +Every stubbed collaborator exposes list of defined mappings under `__/admin/` endpoint. + +===== Messaging Stubs + +Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up. \ No newline at end of file From 4907624bbe00153b8ab8ca68fa7464f6fcc850fc Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 22:11:24 +0200 Subject: [PATCH 547/719] Updated docs --- stub-runner/stub-runner-junit/README.adoc | 2 +- .../accurest/stubrunner/junit/AccurestRuleJUnitTest.java | 8 ++++---- .../accurest/stubrunner/junit/AccurestRuleSpec.groovy | 4 ++-- stub-runner/stub-runner-spring/README.adoc | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/stub-runner/stub-runner-junit/README.adoc b/stub-runner/stub-runner-junit/README.adoc index ff253fa537..92aae748a3 100644 --- a/stub-runner/stub-runner-junit/README.adoc +++ b/stub-runner/stub-runner-junit/README.adoc @@ -28,7 +28,7 @@ Example of usage in Spock tests: [source,groovy,indent=0] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.java[tags=classrule] +include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy[tags=classrule] ---- Example of usage in JUnit tests: diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java index db2719191d..407c78f781 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java @@ -23,14 +23,14 @@ public class AccurestRuleJUnitTest { System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); } - // tag:classrule[] + // tag::classrule[] @ClassRule public static AccurestRule rule = new AccurestRule() .repoRoot(repoRoot()) .downloadStub("io.codearte.accurest.stubs", "loanIssuance") .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); - // end:classrule[] + // end::classrule[] - // tag:test[] + // tag::test[] @Test public void should_start_wiremock_servers() throws Exception { // expect: 'WireMocks are running' @@ -46,7 +46,7 @@ public class AccurestRuleJUnitTest { then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); } - // end:test[] + // end::test[] private static String repoRoot() { try { diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy index 1883c8b5d8..a8bbca3cbd 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy @@ -18,7 +18,7 @@ class AccurestRuleSpec extends Specification { System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); } - // tag:classrule[] + // tag::classrule[] @ClassRule @Shared AccurestRule rule = new AccurestRule() .repoRoot(AccurestRuleSpec.getResource("/m2repo").toURI().toString()) .downloadStub("io.codearte.accurest.stubs", "loanIssuance") @@ -38,5 +38,5 @@ class AccurestRuleSpec extends Specification { "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' } - // end:classrule[] + // end::classrule[] } diff --git a/stub-runner/stub-runner-spring/README.adoc b/stub-runner/stub-runner-spring/README.adoc index 7d07363bdb..51342e9c14 100644 --- a/stub-runner/stub-runner-spring/README.adoc +++ b/stub-runner/stub-runner-spring/README.adoc @@ -17,5 +17,5 @@ for the following configuration file: [source,yml,indent=0] ---- -include::src/test/resources/application.yml[tags=test] +include::src/test/resources/application.yml[] ---- \ No newline at end of file From 4223c8874bdc6a63f2e72ff10435fff324011a2a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 22:12:47 +0200 Subject: [PATCH 548/719] Updated docs --- docs/src/docs/asciidoc/introduction.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc index 07808673b8..4c7701d85b 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -28,10 +28,12 @@ Both have their advantages but also a lot of disadvantages. Let's focus on the l *Deploy all microservices and perform end to end tests* Advantages: + - simulates production - tests real communication between services Disadvantages: + - to test one microservice we would have to deploy 6 microservices, a couple of databases etc. - the environment where the tests would be conducted would be locked for a single suite of tests (i.e. nobody else would be able to run the tests in the meantime). - long to run @@ -41,10 +43,12 @@ Disadvantages: *Mock other microservices in unit / integration tests* Advantages: + - very fast feedback - no infrastructure requirements Disadvantages: + - the implementor of the service creates stubs thus they might have nothing to do with the reality - you can go to production with passing tests and failing production From e7f7593a873895abb5446da7a21e479a3fa598c6 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 22:26:49 +0200 Subject: [PATCH 549/719] Updated docs --- .../MessagingMethodBodyBuilderSpec.groovy | 273 +++++++++--------- accurest-messaging/README.adoc | 2 +- docs/src/docs/asciidoc/messaging.adoc | 10 +- docs/src/docs/asciidoc/rest.adoc | 7 +- docs/src/docs/asciidoc/stubrunner.adoc | 2 +- 5 files changed, 148 insertions(+), 146 deletions(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy index 88ddd86b90..5e5ca20856 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification + /** * @author Marcin Grzejszczak */ @@ -9,21 +10,21 @@ class MessagingMethodBodyBuilderSpec extends Specification { def "should work for triggered based messaging with Spock"() { given: - // tag::trigger_method_dsl[] - def contractDsl = GroovyDsl.make { - label 'some_label' - input { - triggeredBy('bookReturnedTriggered()') - } - outputMessage { - sentTo('activemq:output') - body('''{ "bookName" : "foo" }''') - headers { - header('BOOK-NAME', 'foo') - } - } - } - // end::trigger_method_dsl[] +// tag::trigger_method_dsl[] +def contractDsl = GroovyDsl.make { + label 'some_label' + input { + triggeredBy('bookReturnedTriggered()') + } + outputMessage { + sentTo('activemq:output') + body('''{ "bookName" : "foo" }''') + headers { + header('BOOK-NAME', 'foo') + } + } +} +// end::trigger_method_dsl[] MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: @@ -31,19 +32,19 @@ class MessagingMethodBodyBuilderSpec extends Specification { def test = blockBuilder.toString() then: stripped(test) == stripped( - // tag::trigger_method_test[] - ''' - when: - bookReturnedTriggered() +// tag::trigger_method_test[] +''' +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") - ''' - // end::trigger_method_test[] +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") +''' +// end::trigger_method_test[] ) } @@ -69,19 +70,19 @@ class MessagingMethodBodyBuilderSpec extends Specification { def test = blockBuilder.toString() then: stripped(test) == stripped( - // tag::trigger_method_junit_test[] - ''' - // when: - bookReturnedTriggered(); +// tag::trigger_method_junit_test[] +''' +// 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"); - ''' - // end::trigger_method_junit_test[] +// 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"); +''' +// end::trigger_method_junit_test[] ) } @@ -92,27 +93,27 @@ class MessagingMethodBodyBuilderSpec extends Specification { def "should generate tests triggered by a message for Spock"() { given: // tag::trigger_message_dsl[] - 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') - } - } - } +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') + } + } +} // end::trigger_message_dsl[] MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") @@ -121,25 +122,25 @@ class MessagingMethodBodyBuilderSpec extends Specification { def test = blockBuilder.toString() then: stripped(test) == stripped( - // tag::trigger_message_spock[] - ''' - given: - def inputMessage = accurestMessaging.create( - \'\'\'{"bookName":"foo"}\'\'\', - ['sample': 'header'] - ) +// tag::trigger_message_spock[] +''' +given: + def inputMessage = accurestMessaging.create( + \'\'\'{"bookName":"foo"}\'\'\', + ['sample': 'header'] + ) - when: - accurestMessaging.send(inputMessage, 'jms:input') +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") - ''' - // end::trigger_message_spock[] +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") +''' +// end::trigger_message_spock[] ) } @@ -174,24 +175,24 @@ class MessagingMethodBodyBuilderSpec extends Specification { then: stripped(test) == stripped( // tag::trigger_message_junit[] - ''' - // given: - AccurestMessage inputMessage = accurestMessaging.create( - "{\\"bookName\\":\\"foo\\"}" - , headers() - .header("sample", "header")); +''' +// given: + AccurestMessage inputMessage = accurestMessaging.create( + "{\\"bookName\\":\\"foo\\"}" +, headers() + .header("sample", "header")); - // when: - accurestMessaging.send(inputMessage, "jms:input"); +// 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"); +// 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"); - ''' +''' // end::trigger_message_junit[] ) } @@ -199,19 +200,19 @@ class MessagingMethodBodyBuilderSpec extends Specification { def "should generate tests without destination, triggered by a message"() { given: // tag::trigger_no_output_dsl[] - def contractDsl = GroovyDsl.make { - label 'some_label' - input { - messageFrom('jms:delete') - messageBody([ - bookName: 'foo' - ]) - messageHeaders { - header('sample', 'header') - } - assertThat('bookWasDeleted()') - } - } +def contractDsl = GroovyDsl.make { + label 'some_label' + input { + messageFrom('jms:delete') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + assertThat('bookWasDeleted()') + } +} // end::trigger_no_output_dsl[] MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") @@ -219,24 +220,24 @@ class MessagingMethodBodyBuilderSpec extends Specification { builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped( - // tag::trigger_no_output_spock[] - ''' - given: - def inputMessage = accurestMessaging.create( - \'\'\'{"bookName":"foo"}\'\'\', - ['sample': 'header'] - ) + String expectedMsg = +// tag::trigger_no_output_spock[] +''' +given: + def inputMessage = accurestMessaging.create( + \'\'\'{"bookName":"foo"}\'\'\', + ['sample': 'header'] + ) - when: - accurestMessaging.send(inputMessage, 'jms:delete') +when: + accurestMessaging.send(inputMessage, 'jms:delete') - then: - noExceptionThrown() - bookWasDeleted() - ''' - // end::trigger_no_output_spock[] - ) +then: + noExceptionThrown() + bookWasDeleted() +''' +// end::trigger_no_output_spock[] + stripped(test) == stripped(expectedMsg) } def "should generate tests without destination, triggered by a message for JUnit"() { @@ -260,23 +261,23 @@ class MessagingMethodBodyBuilderSpec extends Specification { builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped( - // tag::trigger_no_output_junit[] - ''' - // given: - AccurestMessage inputMessage = accurestMessaging.create( - "{\\"bookName\\":\\"foo\\"}" - , headers() - .header("sample", "header")); + String expectedMsg = +// tag::trigger_no_output_junit[] +''' +// given: + AccurestMessage inputMessage = accurestMessaging.create( + "{\\"bookName\\":\\"foo\\"}" +, headers() + .header("sample", "header")); - // when: - accurestMessaging.send(inputMessage, "jms:delete"); +// when: + accurestMessaging.send(inputMessage, "jms:delete"); - // then: - bookWasDeleted(); - ''' - // end::trigger_no_output_junit[] - ) +// then: + bookWasDeleted(); +''' +// end::trigger_no_output_junit[] + stripped(test) == stripped(expectedMsg) } } diff --git a/accurest-messaging/README.adoc b/accurest-messaging/README.adoc index 8bd09cb051..b59884a982 100644 --- a/accurest-messaging/README.adoc +++ b/accurest-messaging/README.adoc @@ -1,4 +1,4 @@ -= Accurest Messaging + = Accurest Messaging Accurest allows you to verify your application that uses messaging as means of communication. All of our integrations are working with Spring but you can also set one yourself. diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc index e47549ef98..d6946f16ae 100644 --- a/docs/src/docs/asciidoc/messaging.adoc +++ b/docs/src/docs/asciidoc/messaging.adoc @@ -31,10 +31,10 @@ testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}" The `accurest-messaging-core` module contains 3 main interfaces: -- AccurestMessage - describes a message received / sent to a channel / queue / topic etc. -- AccurestMessageBuilder - describes how to build a message -- AccurestMessaging - class that allows you to build, send and receive messages -- AccurestFilter - interface to filter out the messages that do not follow the pattern from the DSL +- `AccurestMessage` - describes a message received / sent to a channel / queue / topic etc. +- `AccurestMessageBuilder` - describes how to build a message +- `AccurestMessaging` - class that allows you to build, send and receive messages +- `AccurestFilter` - interface to filter out the messages that do not follow the pattern from the DSL In the generated test the `AccurestMessaging` is injected via `@Inject` annotation thus you can use other injection frameworks than Spring. @@ -56,7 +56,7 @@ There are 3 main scenarios that we should take into consideration: - Scenario 1: there is no input message that produces an output one. The output message is triggered by a component inside the application (e.g. scheduler) - Scenario 2: the input message triggers an output message -- Scenarion 3: the input message is consumed and there is no output message +- Scenario 3: the input message is consumed and there is no output message ==== Scenario 1 (no input message) diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index ade4477aa9..b34e1301fe 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -53,7 +53,7 @@ Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugi ===== Add stubs -By default Accurest is looking for stubs in `src/test/resources/stubs` directory. +By default Accurest is looking for stubs in `src/test/accurest` 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. @@ -66,6 +66,7 @@ src/test/accurest/myservice/shouldReturnUser.groovy ---- Accurest will create test class `defaultBasePackage.MyService` with two methods + - `shouldCreateUser()` - `shouldReturnUser()` @@ -102,7 +103,7 @@ accurest { ===== Base class for tests - When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. +When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. [source,groovy,indent=0] ---- @@ -131,7 +132,7 @@ In consumer service you need to configure Accurest plugin in exactly the same wa ./gradlew generateWireMockClientStubs ---- -command. Note that `stubsOutputDir` option has to be set for stub generation to work. +Note that `stubsOutputDir` option has to be set for stub generation to work. When present, json stubs can be used in consumer automated tests. diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index b429b2d4f8..e62bb68312 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -20,7 +20,7 @@ include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/sc ==== Maven -Example of Maven can be found in the [Accurest Maven Plugin README](https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar) +Example of Maven can be found in the https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar[Accurest Maven Plugin README] === Modules From f8e149b8729ccd3bf7ff354c8ecd0b88a85e1d1e Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 22:31:19 +0200 Subject: [PATCH 550/719] Updated docs --- docs/src/docs/asciidoc/index.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 3447efe7db..d22d8762d0 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,5 +1,9 @@ :messaging_version: 1.0.7 += Accurest + +_Adam Dudczak, Marcin Grzejszczak, Jakub Kubrynski, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła_ + include::introduction.adoc[] include::contract.adoc[] From 796a1e2c19308c003219b57f3b7ffd555ff9217f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 22:37:42 +0200 Subject: [PATCH 551/719] Fixed typo --- docs/src/docs/asciidoc/index.adoc | 2 +- docs/src/docs/asciidoc/introduction.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index d22d8762d0..bbc6197a0e 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -2,7 +2,7 @@ = Accurest -_Adam Dudczak, Marcin Grzejszczak, Jakub Kubrynski, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła_ +_Adam Dudczak, Marcin Grzejszczak, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła_ include::introduction.adoc[] diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc index 4c7701d85b..d43ce58b18 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -114,7 +114,7 @@ is under constant development. video::daafmTYFoDU[youtube] -*Marcin Grzejszczak and Jakub Kubrynski talking about Accurest* +*Marcin Grzejszczak and Jakub Kubryński talking about Accurest* video::130779882[vimeo] From 5fdfd38bf53e64ffa4fb6d56822d14e7434dbc44 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 24 Apr 2016 23:45:24 +0200 Subject: [PATCH 552/719] Added Accurest class for DSL --- .../groovy/io/codearte/accurest/Accurest.groovy | 17 +++++++++++++++++ .../builder/MockMvcMethodBodyBuilderSpec.groovy | 3 ++- docs/src/docs/asciidoc/contract.adoc | 3 ++- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/Accurest.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/Accurest.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/Accurest.groovy new file mode 100644 index 0000000000..b50ed39835 --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/Accurest.groovy @@ -0,0 +1,17 @@ +package io.codearte.accurest + +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString +import groovy.transform.TypeChecked +import io.codearte.accurest.dsl.GroovyDsl + +/** + * A better name for GroovyDsl + * + * @author Marcin Grzejszczak + */ +@TypeChecked +@EqualsAndHashCode +@ToString(includeFields = true, includePackage = false, includeNames = true, includeSuper = true) +class Accurest extends GroovyDsl { +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index eaa303fb52..ea876a0ae6 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.builder +import io.codearte.accurest.Accurest import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubVerifier import spock.lang.Issue @@ -13,7 +14,7 @@ import java.util.regex.Pattern class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStubVerifier { @Shared - GroovyDsl dslWithOptionalsInString = GroovyDsl.make { + GroovyDsl dslWithOptionalsInString = Accurest.make { priority 1 request { method 'POST' diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/docs/asciidoc/contract.adoc index 1e8fb9b780..e2dc96c934 100644 --- a/docs/src/docs/asciidoc/contract.adoc +++ b/docs/src/docs/asciidoc/contract.adoc @@ -4,8 +4,9 @@ Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn' a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself - it's statically typed. -Let's look at full example of a contract definition. +WARNING: Since {messaging_version} you can use the `io.codearte.accurest.Accurest` class in your DSL files. +Let's look at full example of a contract definition. [source,groovy,indent=0] ---- From acead5c60537a88217d4d0e1ec3c707a499cc5c3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 11:20:07 +0200 Subject: [PATCH 553/719] Fixed docs --- docs/src/docs/asciidoc/rest.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index b34e1301fe..82bca2efc8 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -81,9 +81,9 @@ To change default configuration just add `accurest` snippet to your Gradle confi [source,groovy,indent=0] ---- accurest { - testMode == 'MockMvc' - baseClassForTests == 'org.mycompany.tests' - generatedTestSourcesDir == project.file('src/accurest') + testMode = 'MockMvc' + baseClassForTests = 'org.mycompany.tests' + generatedTestSourcesDir = project.file('src/accurest') } ---- From 65bb7b420a72ffa4589c67f4923be68f7072f9e8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 11:24:26 +0200 Subject: [PATCH 554/719] Moved Accurest to dsl package --- .../main/groovy/io/codearte/accurest/{ => dsl}/Accurest.groovy | 2 +- .../accurest/builder/MockMvcMethodBodyBuilderSpec.groovy | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename accurest-core/src/main/groovy/io/codearte/accurest/{ => dsl}/Accurest.groovy (92%) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/Accurest.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy similarity index 92% rename from accurest-core/src/main/groovy/io/codearte/accurest/Accurest.groovy rename to accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy index b50ed39835..9168f41f80 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/Accurest.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy @@ -1,4 +1,4 @@ -package io.codearte.accurest +package io.codearte.accurest.dsl import groovy.transform.EqualsAndHashCode import groovy.transform.ToString diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index ea876a0ae6..14ea6e61df 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1,6 +1,6 @@ package io.codearte.accurest.builder -import io.codearte.accurest.Accurest +import io.codearte.accurest.dsl.Accurest import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.dsl.WireMockStubVerifier import spock.lang.Issue From 91e29afb3adc3fe1d74684e62150ba845f01f9a2 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 11:24:57 +0200 Subject: [PATCH 555/719] Fixed docs and Accurest class --- .../src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy | 2 -- docs/src/docs/asciidoc/contract.adoc | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy index 9168f41f80..ee5c0392c7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy @@ -3,8 +3,6 @@ package io.codearte.accurest.dsl import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked -import io.codearte.accurest.dsl.GroovyDsl - /** * A better name for GroovyDsl * diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/docs/asciidoc/contract.adoc index e2dc96c934..eb083a9338 100644 --- a/docs/src/docs/asciidoc/contract.adoc +++ b/docs/src/docs/asciidoc/contract.adoc @@ -4,7 +4,7 @@ Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn' a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself - it's statically typed. -WARNING: Since {messaging_version} you can use the `io.codearte.accurest.Accurest` class in your DSL files. +WARNING: Since {messaging_version} you can use the `io.codearte.accurest.dsl.Accurest` class in your DSL files. Let's look at full example of a contract definition. From 728278dcc75cc39144300e6fa37f4449b49b7a3f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 11:43:21 +0200 Subject: [PATCH 556/719] Fixed a bug with missing response variable --- .../builder/MessagingMethodBodyBuilder.groovy | 4 +- .../MessagingMethodBodyBuilderSpec.groovy | 91 ++++++++++++++++++- 2 files changed, 91 insertions(+), 4 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy index 51d899e48b..6da92a5bce 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy @@ -52,9 +52,7 @@ abstract class MessagingMethodBodyBuilder extends MethodBodyBuilder { addColonIfRequired(bb) } if (outputMessage) { - if (outputMessage.headers) { - validateResponseHeadersBlock(bb) - } + validateResponseHeadersBlock(bb) if (outputMessage.body) { bb.endBlock() if (outputMessage.headers) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy index 5e5ca20856..9e74ebed24 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy @@ -2,7 +2,6 @@ package io.codearte.accurest.builder import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification - /** * @author Marcin Grzejszczak */ @@ -280,4 +279,94 @@ then: stripped(test) == stripped(expectedMsg) } + def "should generate tests without headers 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' + ]) + } + } + MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + String expectedMsg = +''' + // given: + AccurestMessage inputMessage = accurestMessaging.create( +\t\t\t"{\\"bookName\\":\\"foo\\"}" +\t\t, headers() +\t\t\t.header("sample", "header")); + + // when: + accurestMessaging.send(inputMessage, "jms:input"); + + // then: + AccurestMessage response = accurestMessaging.receiveMessage("jms:output"); + DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); + assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); +''' + stripped(test) == stripped(expectedMsg) + } + + def "should generate tests without headers 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' + ]) + } + } + MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + String expectedMsg = +""" + given: + def inputMessage = accurestMessaging.create('''{"bookName":"foo"}''' + ,[ + 'sample': 'header' + ]) + + when: + accurestMessaging.send(inputMessage, 'jms:input') + + then: + def response = accurestMessaging.receiveMessage('jms:output') + DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + assertThatJson(parsedJson).field("bookName").isEqualTo("foo") +""" + stripped(test) == stripped(expectedMsg) + } + } From f1a7975bcefec6448e483b9283cc5ea1085f2487 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 12:07:52 +0200 Subject: [PATCH 557/719] Fixed object mapping --- .../accurest/SingleTestGenerator.groovy | 6 ++-- .../MessagingMethodBodyBuilderSpec.groovy | 8 ++--- .../messaging/AccurestObjectMapper.java | 30 +++++++++++++++++++ 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestObjectMapper.java diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 8cb84a57dc..86a7bd47de 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest import groovy.transform.Canonical +import groovy.transform.EqualsAndHashCode import groovy.transform.PackageScope import groovy.util.logging.Slf4j import io.codearte.accurest.builder.ClassBuilder @@ -99,6 +100,7 @@ class SingleTestGenerator { } @Canonical + @EqualsAndHashCode private static class ParsedDsl { Contract contract GroovyDsl groovyDsl @@ -124,10 +126,10 @@ class SingleTestGenerator { private ClassBuilder addMessagingRelatedEntries(ClassBuilder clazz) { clazz.addField(['@Inject AccurestMessaging accurestMessaging', - 'ObjectMapper accurestObjectMapper = new ObjectMapper()' + 'AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper()' ]) clazz.addImport([ 'javax.inject.Inject', - 'com.fasterxml.jackson.databind.ObjectMapper', + 'io.codearte.accurest.messaging.AccurestObjectMapper', 'io.codearte.accurest.messaging.AccurestMessage', 'io.codearte.accurest.messaging.AccurestMessaging', ]) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy index 9e74ebed24..192c1036e5 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy @@ -86,7 +86,7 @@ and: } private String stripped(String text) { - return text.stripIndent().stripMargin().replace('\t', '').replace('\n', '') + return text.stripIndent().stripMargin().replace(' ', '').replace('\n', '') } def "should generate tests triggered by a message for Spock"() { @@ -309,9 +309,9 @@ then: ''' // given: AccurestMessage inputMessage = accurestMessaging.create( -\t\t\t"{\\"bookName\\":\\"foo\\"}" -\t\t, headers() -\t\t\t.header("sample", "header")); + "{\\"bookName\\":\\"foo\\"}" + , headers() + .header("sample", "header")); // when: accurestMessaging.send(inputMessage, "jms:input"); diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestObjectMapper.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestObjectMapper.java new file mode 100644 index 0000000000..39740539ad --- /dev/null +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestObjectMapper.java @@ -0,0 +1,30 @@ +package io.codearte.accurest.messaging; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Wrapper over {@link ObjectMapper} that won't try to parse + * String but will directly return it. + * + * @author Marcin Grzejszczak + */ +public class AccurestObjectMapper { + + private final ObjectMapper objectMapper; + + public AccurestObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + public AccurestObjectMapper() { + this.objectMapper = new ObjectMapper(); + } + + public String writeValueAsString(Object payload) throws JsonProcessingException { + if (payload instanceof String) { + return payload.toString(); + } + return objectMapper.writeValueAsString(payload); + } +} From 941a7bd30cdd1d96a59df01d1ec0ea6cb7f09308 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 12:40:51 +0200 Subject: [PATCH 558/719] Added AccurestObjectMapper --- .../accurest/builder/ClassBuilder.groovy | 2 + .../JUnitMessagingMethodBodyBuilder.groovy | 5 +- .../SpockMessagingMethodBodyBuilder.groovy | 7 +- .../MessagingMethodBodyBuilderSpec.groovy | 94 ++++++++++--------- docs/src/docs/asciidoc/index.adoc | 2 +- docs/src/docs/asciidoc/rest.adoc | 4 +- .../CamelMessagingApplicationSpec.groovy | 4 +- ...IntegrationMessagingApplicationSpec.groovy | 5 +- .../spring/SpringApplicationSpec.groovy | 5 +- .../StreamMessagingApplicationSpec.groovy | 5 +- .../camel/StubRunnerCamelPredicate.groovy | 4 +- ...tubRunnerIntegrationMessageSelector.groovy | 5 +- .../StubRunnerStreamMessageSelector.groovy | 5 +- 13 files changed, 76 insertions(+), 71 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy index 459bf57a4c..b24c5b57ec 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy @@ -123,12 +123,14 @@ class ClassBuilder { clazz.addEmptyLine() } + clazz.startBlock() fields.sort().each { clazz.addLine(it) } if (!fields.empty) { clazz.addEmptyLine() } + clazz.endBlock() methods.each { clazz.addBlock(it) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy index 11228c64e2..62f96f3fab 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy @@ -69,6 +69,7 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { bb.addLine("""AccurestMessage response = accurestMessaging.receiveMessage("${outputMessage.sentTo}");""") + bb.addLine("""assertThat(response).isNotNull();""") outputMessage.headers?.collect { Header header ->\ processHeaderElement(bb, header.name, header.serverValue) } @@ -114,13 +115,13 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { protected String getInputString() { String request = 'AccurestMessage inputMessage = accurestMessaging.create(' if (inputMessage.messageBody) { - request = "${request}\n\t\t\t\"${StringEscapeUtils.escapeJava(bodyAsString)}\"\n\t\t" + request = "${request}\n \"${StringEscapeUtils.escapeJava(bodyAsString)}\"\n " } if (inputMessage.messageHeaders) { request = "${request}, headers()\n" } inputMessage.messageHeaders?.collect { Header header -> - request = "${request}\t\t\t${getHeaderString(header)}" + request = "${request} ${getHeaderString(header)}" } return "${request})" } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy index 6e89373010..583acc9c73 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy @@ -63,6 +63,7 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { protected void validateResponseCodeBlock(BlockBuilder bb) { if (outputMessage) { bb.addLine("""def response = accurestMessaging.receiveMessage('${outputMessage.sentTo}')""") + bb.addLine("""assert response != null""") } else { bb.addLine('noExceptionThrown()') } @@ -114,18 +115,18 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { protected String getInputString() { String request = 'def inputMessage = accurestMessaging.create(' if (inputMessage.messageBody) { - request = "${request}'''${bodyAsString}'''\n\t\t" + request = "${request}'''${bodyAsString}'''\n " } if (inputMessage.messageHeaders) { request = "${request},[\n" } def headers = [] inputMessage.messageHeaders?.collect { Header header -> - headers << "\t\t\t${getHeaderString(header)}" + headers << " ${getHeaderString(header)}" } request = "${request}${headers.join(',\n')}" if (inputMessage.messageHeaders) { - request = "${request}\n\t\t]" + request = "${request}\n ]" } return "${request})" } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy index 192c1036e5..1855c7b88b 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy @@ -30,21 +30,23 @@ def contractDsl = GroovyDsl.make { builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped( + String expectedMessage = // tag::trigger_method_test[] ''' -when: - bookReturnedTriggered() + when: + bookReturnedTriggered() + + then: + def response = accurestMessaging.receiveMessage('activemq:output') + assert response != null + response.getHeader('BOOK-NAME') == 'foo' + and: + DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + assertThatJson(parsedJson).field("bookName").isEqualTo("foo") -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") ''' // end::trigger_method_test[] - ) + stripped(test) == stripped(expectedMessage) } def "should work for triggered based messaging with JUnit"() { @@ -68,25 +70,22 @@ and: builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped( + String expectedMessage = // tag::trigger_method_junit_test[] ''' -// when: - bookReturnedTriggered(); + // 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"); + // then: + AccurestMessage response = accurestMessaging.receiveMessage("activemq:output"); + assertThat(response).isNotNull(); + assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo"); + // and: + DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); + assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); ''' // end::trigger_method_junit_test[] - ) - } - - private String stripped(String text) { - return text.stripIndent().stripMargin().replace(' ', '').replace('\n', '') + stripped(test) == stripped(expectedMessage) } def "should generate tests triggered by a message for Spock"() { @@ -120,27 +119,28 @@ def contractDsl = GroovyDsl.make { builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped( + String expectedMessage = // tag::trigger_message_spock[] -''' +"""\ given: - def inputMessage = accurestMessaging.create( - \'\'\'{"bookName":"foo"}\'\'\', - ['sample': 'header'] - ) + def inputMessage = accurestMessaging.create( + '''{"bookName":"foo"}''', + ['sample': 'header'] + ) when: - accurestMessaging.send(inputMessage, 'jms:input') + accurestMessaging.send(inputMessage, 'jms:input') then: - def response = accurestMessaging.receiveMessage('jms:output') - response.getHeader('BOOK-NAME') == 'foo' + def response = accurestMessaging.receiveMessage('jms:output') + assert response !- null + response.getHeader('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) - assertThatJson(parsedJson).field("bookName").isEqualTo("foo") -''' + DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + assertThatJson(parsedJson).field("bookName").isEqualTo("foo") +""" // end::trigger_message_spock[] - ) + stripped(test) == stripped(expectedMessage) } def "should generate tests triggered by a message for JUnit"() { @@ -172,28 +172,28 @@ and: builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - stripped(test) == stripped( - // tag::trigger_message_junit[] + String expectedMessage = +// tag::trigger_message_junit[] ''' // given: AccurestMessage inputMessage = accurestMessaging.create( - "{\\"bookName\\":\\"foo\\"}" + "{\\"bookName\\":\\"foo\\"}" , headers() - .header("sample", "header")); + .header("sample", "header")); // when: accurestMessaging.send(inputMessage, "jms:input"); // then: AccurestMessage response = accurestMessaging.receiveMessage("jms:output"); + assertThat(response).isNotNull(); assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo"); // and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); - ''' - // end::trigger_message_junit[] - ) +// end::trigger_message_junit[] + stripped(test) == stripped(expectedMessage) } def "should generate tests without destination, triggered by a message"() { @@ -318,6 +318,7 @@ then: // then: AccurestMessage response = accurestMessaging.receiveMessage("jms:output"); + assertThat(response).isNotNull(); DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); ''' @@ -363,10 +364,15 @@ then: then: def response = accurestMessaging.receiveMessage('jms:output') + assert response != null DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") """ stripped(test) == stripped(expectedMsg) } + private String stripped(String text) { + return text.stripIndent().stripMargin().replace(' ', '').replace('\n', '').replace('\t', '').replaceAll("\\W", "") + } + } diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index bbc6197a0e..3e3dc3a980 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -1,4 +1,4 @@ -:messaging_version: 1.0.7 +:messaging_version: 1.1.0 = Accurest diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index 82bca2efc8..1dc0eda965 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -93,7 +93,7 @@ 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 [] - **basePackageForTests** - specifies base package for all generated tests. By default set to io.codearte.accurest.tests - - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` + - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` if using Spock tests. - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - **ignoredFiles** - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array [] - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/accurest` @@ -237,7 +237,7 @@ To change default configuration just add `configuration` section to plugin defin - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification`. + - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` if using Spock tests. - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/accurest`. - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework diff --git a/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy b/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy index 0400c9d359..0dfecf7e2e 100644 --- a/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy +++ b/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy @@ -1,12 +1,12 @@ 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 io.codearte.accurest.messaging.AccurestObjectMapper import org.apache.camel.model.ModelCamelContext import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader @@ -24,7 +24,7 @@ public class CamelMessagingApplicationSpec extends Specification { // ALL CASES @Inject AccurestMessaging accurestMessaging - ObjectMapper accurestObjectMapper = new ObjectMapper() + AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper() def "should work for triggered based messaging"() { given: diff --git a/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy b/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy index 98b6f19658..75b453940d 100644 --- a/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy +++ b/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy @@ -1,26 +1,25 @@ 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 io.codearte.accurest.messaging.AccurestObjectMapper 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 - // 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() + AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper() def "should work for triggered based messaging"() { given: diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy index a6296a02ae..0c79f467c2 100644 --- a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy +++ b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy @@ -1,12 +1,12 @@ 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 io.codearte.accurest.messaging.AccurestObjectMapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader import org.springframework.test.context.ContextConfiguration @@ -14,7 +14,6 @@ import spock.lang.Specification import spock.util.concurrent.PollingConditions import javax.inject.Inject - /** * SPIKE ON TESTS FROM NOTES IN MessagingSpec */ @@ -24,7 +23,7 @@ public class SpringApplicationSpec extends Specification { // ALL CASES @Inject AccurestMessaging accurestMessaging - ObjectMapper accurestObjectMapper = new ObjectMapper() + AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper() def "should work for triggered based messaging"() { given: diff --git a/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy b/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy index 4cc5d1b2e0..597f693709 100644 --- a/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy +++ b/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy @@ -1,19 +1,18 @@ 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 io.codearte.accurest.messaging.AccurestObjectMapper 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 */ @@ -23,7 +22,7 @@ public class StreamMessagingApplicationSpec extends Specification { // ALL CASES @Inject AccurestMessaging accurestMessaging - ObjectMapper accurestObjectMapper = new ObjectMapper() + AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper() def "should work for triggered based messaging"() { given: diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy index 3ab58d6d8e..b38b82fabe 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy @@ -1,12 +1,12 @@ package io.codearte.accurest.stubrunner.messaging.camel -import com.fasterxml.jackson.databind.ObjectMapper import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import com.toomuchcoding.jsonassert.JsonVerifiable import groovy.transform.PackageScope import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.messaging.AccurestObjectMapper import io.codearte.accurest.util.JsonPaths import io.codearte.accurest.util.JsonToJsonPathsConverter import org.apache.camel.Exchange @@ -23,7 +23,7 @@ import java.util.regex.Pattern class StubRunnerCamelPredicate implements Predicate { private final GroovyDsl groovyDsl - private final ObjectMapper objectMapper = new ObjectMapper() + private final AccurestObjectMapper objectMapper = new AccurestObjectMapper() StubRunnerCamelPredicate(GroovyDsl groovyDsl) { this.groovyDsl = groovyDsl diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy index 1184f0acef..1bdf1398f2 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy @@ -1,19 +1,18 @@ package io.codearte.accurest.stubrunner.messaging.integration -import com.fasterxml.jackson.databind.ObjectMapper import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import com.toomuchcoding.jsonassert.JsonVerifiable import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.messaging.AccurestObjectMapper import io.codearte.accurest.util.JsonPaths import io.codearte.accurest.util.JsonToJsonPathsConverter import org.springframework.integration.core.MessageSelector import org.springframework.messaging.Message import java.util.regex.Pattern - /** * Passes through a message that matches the one defined in the DSL * @@ -23,7 +22,7 @@ import java.util.regex.Pattern class StubRunnerIntegrationMessageSelector implements MessageSelector { private final GroovyDsl groovyDsl - private final ObjectMapper objectMapper = new ObjectMapper() + private final AccurestObjectMapper objectMapper = new AccurestObjectMapper() StubRunnerIntegrationMessageSelector(GroovyDsl groovyDsl) { this.groovyDsl = groovyDsl diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy index 37e60c85b7..628f423cf4 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy @@ -1,19 +1,18 @@ package io.codearte.accurest.stubrunner.messaging.stream -import com.fasterxml.jackson.databind.ObjectMapper import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import com.toomuchcoding.jsonassert.JsonVerifiable import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.messaging.AccurestObjectMapper import io.codearte.accurest.util.JsonPaths import io.codearte.accurest.util.JsonToJsonPathsConverter import org.springframework.integration.core.MessageSelector import org.springframework.messaging.Message import java.util.regex.Pattern - /** * Passes through a message that matches the one defined in the DSL * @@ -23,7 +22,7 @@ import java.util.regex.Pattern class StubRunnerStreamMessageSelector implements MessageSelector { private final GroovyDsl groovyDsl - private final ObjectMapper objectMapper = new ObjectMapper() + private final AccurestObjectMapper objectMapper = new AccurestObjectMapper() StubRunnerStreamMessageSelector(GroovyDsl groovyDsl) { this.groovyDsl = groovyDsl From 3232adefe621e5a401b7704cbb63e349ac2e16bb Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 15:43:42 +0200 Subject: [PATCH 559/719] Updated Groovy version, changed StubTrigger name --- docs/src/docs/asciidoc/migration.adoc | 4 ++-- docs/src/docs/asciidoc/stubrunner_msg.adoc | 2 +- stub-runner/stub-runner/build.gradle | 2 +- .../groovy/io/codearte/accurest/stubrunner/StubFinder.groovy | 2 +- .../stubrunner/{StubTriggerer.groovy => StubTrigger.groovy} | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/{StubTriggerer.groovy => StubTrigger.groovy} (94%) diff --git a/docs/src/docs/asciidoc/migration.adoc b/docs/src/docs/asciidoc/migration.adoc index 8ddc214619..98e1215e9a 100644 --- a/docs/src/docs/asciidoc/migration.adoc +++ b/docs/src/docs/asciidoc/migration.adoc @@ -13,8 +13,8 @@ - now all DSL files have to be under `contractsDslDir`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage* -=== Migration to 1.0.7 -- from 1.0.7 we're setting JUnit as a default testing utility. You have to pass the following option to keep Spock +=== Migration to {messaging_version} +- from {messaging_version} we're setting JUnit as a default testing utility. You have to pass the following option to keep Spock as your first choice: [source,groovy] diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc index 76bf5c241e..4b383c095e 100644 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -16,7 +16,7 @@ To trigger a message it's enough to use the `StubTiggerer` interface: [source,groovy] ---- -include::../../../../stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy[] +include::../../../../stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy[] ---- For convenience the `StubFinder` interface extends `StubTrigger` so it's enough to use only one in your tests. diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index c6e992b79a..158628c06b 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -7,7 +7,7 @@ dependencies { compile project(':accurest-core') compile project(':accurest-messaging-root:accurest-messaging-core') compile 'org.apache.ivy:ivy:2.4.0' - compile localGroovy() + compile 'org.codehaus.groovy:groovy-all:2.4.4' compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile 'javax.servlet:javax.servlet-api:3.1.0' compile 'args4j:args4j:2.32' diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy index 9c14c75735..f69f88044c 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy @@ -2,7 +2,7 @@ package io.codearte.accurest.stubrunner import io.codearte.accurest.dsl.GroovyDsl -interface StubFinder extends StubTriggerer { +interface StubFinder extends StubTrigger { /** * For the given groupId and artifactId tries to find the matching * URL of the running stub. diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy similarity index 94% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy rename to stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy index 99090b8bdc..94b900bc6d 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTriggerer.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy @@ -1,6 +1,6 @@ package io.codearte.accurest.stubrunner -interface StubTriggerer { +interface StubTrigger { /** * Triggers an event by a given label for a given {@code groupid:artifactid} notation. You can use only {@code artifactId} too. From 50dc90df76d5a73d029b69f4805275e7252de34b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 15:47:23 +0200 Subject: [PATCH 560/719] Changed remaining StubTrigger interface name --- docs/src/docs/asciidoc/stubrunner_msg.adoc | 2 +- .../stub-runner-messaging-camel/README.adoc | 2 +- .../stub-runner-messaging-integration/README.adoc | 2 +- .../stub-runner-messaging-stream/README.adoc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc index 4b383c095e..28f31d6211 100644 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ b/docs/src/docs/asciidoc/stubrunner_msg.adoc @@ -12,7 +12,7 @@ It also provides points of entry to integrate with any other solution on the mar === Stub triggering -To trigger a message it's enough to use the `StubTiggerer` interface: +To trigger a message it's enough to use the `StubTigger` interface: [source,groovy] ---- diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc index fb579dc507..d931a61a10 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc @@ -69,7 +69,7 @@ include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelSt ===== Scenario 1 (no input message) -So as to trigger a message via the `return_book_1` label we'll use the `StubTiggerer` interface as follows +So as to trigger a message via the `return_book_1` label we'll use the `StubTigger` interface as follows [source,groovy] ---- diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc index 0e935fe739..89c30d9dcf 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc @@ -77,7 +77,7 @@ include::src/test/resources/integration-context.xml[] ===== Scenario 1 (no input message) -So as to trigger a message via the `return_book_1` label we'll use the `StubTiggerer` interface as follows +So as to trigger a message via the `return_book_1` label we'll use the `StubTigger` interface as follows [source,groovy] ---- diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc index cda8a5a32b..2201ae5f98 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc @@ -69,7 +69,7 @@ include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/Stream ===== Scenario 1 (no input message) -So as to trigger a message via the `return_book_1` label we'll use the `StubTiggerer` interface as follows +So as to trigger a message via the `return_book_1` label we'll use the `StubTigger` interface as follows [source,groovy] ---- From c1ca81154fc6b041459705bd27cfa01b8b570319 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 16:20:59 +0200 Subject: [PATCH 561/719] Fixed names for flow registrars --- .../integration/StubRunnerIntegrationConfiguration.groovy | 4 +--- .../messaging/stream/StubRunnerStreamConfiguration.groovy | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy index 25106d5f3d..412db09b30 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -13,7 +13,6 @@ import org.springframework.integration.dsl.GenericEndpointSpec import org.springframework.integration.dsl.IntegrationFlowBuilder import org.springframework.integration.dsl.IntegrationFlows import org.springframework.messaging.Message -import org.springframework.stereotype.Service /** * Spring Integration configuration that iterates over the downloaded Groovy DSLs * and registers a flow for each DSL. @@ -25,7 +24,7 @@ import org.springframework.stereotype.Service class StubRunnerIntegrationConfiguration { @Bean - FlowRegistrar service(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner) { + FlowRegistrar flowRegistrar(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner) { Map> accurestContracts = batchStubRunner.accurestContracts accurestContracts.each { StubConfiguration key, Collection value -> String name = "${key.groupId}_${key.artifactId}" @@ -52,6 +51,5 @@ class StubRunnerIntegrationConfiguration { void handle(Message message) {} } - @Service static class FlowRegistrar {} } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy index 3d3210ff7e..0085c1724d 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy @@ -16,7 +16,6 @@ import org.springframework.integration.dsl.IntegrationFlowBuilder import org.springframework.integration.dsl.IntegrationFlows import org.springframework.messaging.Message import org.springframework.messaging.MessageChannel -import org.springframework.stereotype.Service /** * Spring Cloud Stream configuration that iterates over the downloaded Groovy DSLs * and registers a flow for each DSL. @@ -29,7 +28,7 @@ import org.springframework.stereotype.Service class StubRunnerStreamConfiguration { @Bean - FlowRegistrar service(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner, ChannelBindingService channelBindingService) { + FlowRegistrar flowRegistrar(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner, ChannelBindingService channelBindingService) { Map> accurestContracts = batchStubRunner.accurestContracts accurestContracts.each { StubConfiguration key, Collection value -> String name = "${key.groupId}_${key.artifactId}" @@ -60,6 +59,5 @@ class StubRunnerStreamConfiguration { void handle(Message message) {} } - @Service static class FlowRegistrar {} } From b589633292a0bd987333ceda4c9ac5fa3ad56868 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 16:23:50 +0200 Subject: [PATCH 562/719] Added missing imports --- .../integration/StubRunnerIntegrationConfiguration.groovy | 4 ++++ .../messaging/stream/StubRunnerStreamConfiguration.groovy | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy index 412db09b30..a5e7159611 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -4,15 +4,18 @@ import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.stubrunner.BatchStubRunner import io.codearte.accurest.stubrunner.StubConfiguration +import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration import org.springframework.beans.factory.config.AutowireCapableBeanFactory import org.springframework.context.Lifecycle import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Import import org.springframework.integration.dsl.FilterEndpointSpec import org.springframework.integration.dsl.GenericEndpointSpec import org.springframework.integration.dsl.IntegrationFlowBuilder import org.springframework.integration.dsl.IntegrationFlows import org.springframework.messaging.Message + /** * Spring Integration configuration that iterates over the downloaded Groovy DSLs * and registers a flow for each DSL. @@ -20,6 +23,7 @@ import org.springframework.messaging.Message * @author Marcin Grzejszczak */ @Configuration +@Import(StubRunnerConfiguration) @CompileStatic class StubRunnerIntegrationConfiguration { diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy index 0085c1724d..bd41ea07bf 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy @@ -4,18 +4,21 @@ import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.stubrunner.BatchStubRunner import io.codearte.accurest.stubrunner.StubConfiguration +import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration import org.springframework.beans.factory.config.AutowireCapableBeanFactory import org.springframework.cloud.stream.annotation.EnableBinding import org.springframework.cloud.stream.binding.ChannelBindingService import org.springframework.context.Lifecycle import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Import import org.springframework.integration.dsl.FilterEndpointSpec import org.springframework.integration.dsl.GenericEndpointSpec import org.springframework.integration.dsl.IntegrationFlowBuilder import org.springframework.integration.dsl.IntegrationFlows import org.springframework.messaging.Message import org.springframework.messaging.MessageChannel + /** * Spring Cloud Stream configuration that iterates over the downloaded Groovy DSLs * and registers a flow for each DSL. @@ -23,6 +26,7 @@ import org.springframework.messaging.MessageChannel * @author Marcin Grzejszczak */ @Configuration +@Import(StubRunnerConfiguration) @EnableBinding @CompileStatic class StubRunnerStreamConfiguration { From 819e35bd88e37129bb088e8109581e816ef6623b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 17:21:20 +0200 Subject: [PATCH 563/719] Fixed sentTo attribute --- .../accurest/builder/JUnitMessagingMethodBodyBuilder.groovy | 2 +- .../accurest/builder/SpockMessagingMethodBodyBuilder.groovy | 2 +- .../io/codearte/accurest/dsl/internal/OutputMessage.groovy | 6 +++++- .../messaging/camel/StubRunnerCamelConfiguration.groovy | 2 +- .../integration/StubRunnerIntegrationConfiguration.groovy | 2 +- .../messaging/stream/StubRunnerStreamConfiguration.groovy | 4 ++-- .../codearte/accurest/stubrunner/StubRunnerExecutor.groovy | 2 +- 7 files changed, 12 insertions(+), 8 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy index 62f96f3fab..12d62ae555 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy @@ -68,7 +68,7 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { - bb.addLine("""AccurestMessage response = accurestMessaging.receiveMessage("${outputMessage.sentTo}");""") + bb.addLine("""AccurestMessage response = accurestMessaging.receiveMessage("${outputMessage.sentTo.serverValue}");""") bb.addLine("""assertThat(response).isNotNull();""") outputMessage.headers?.collect { Header header ->\ processHeaderElement(bb, header.name, header.serverValue) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy index 583acc9c73..c5fba9da10 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy @@ -62,7 +62,7 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected void validateResponseCodeBlock(BlockBuilder bb) { if (outputMessage) { - bb.addLine("""def response = accurestMessaging.receiveMessage('${outputMessage.sentTo}')""") + bb.addLine("""def response = accurestMessaging.receiveMessage('${outputMessage.sentTo.serverValue}')""") bb.addLine("""assert response != null""") } else { bb.addLine('noExceptionThrown()') diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy index 2a8c96249f..10bc07fd17 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy @@ -10,7 +10,7 @@ import groovy.transform.TypeChecked @ToString(includePackage = false, includeNames = true) class OutputMessage extends Common { - String sentTo + DslProperty sentTo Headers headers DslProperty body ExecutionProperty assertThat @@ -24,6 +24,10 @@ class OutputMessage extends Common { } void sentTo(String sentTo) { + this.sentTo = new DslProperty(sentTo) + } + + void sentTo(DslProperty sentTo) { this.sentTo = sentTo } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy index 8941d4984e..d27329f5d3 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy @@ -27,7 +27,7 @@ class StubRunnerCamelConfiguration { from(it.input.messageFrom) .filter(new StubRunnerCamelPredicate(it)) .process(new StubRunnerCamelProcessor(it)) - .to(it.outputMessage.sentTo) + .to(it.outputMessage.sentTo.clientValue) } } }; diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy index a5e7159611..b5205afa30 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -38,7 +38,7 @@ class StubRunnerIntegrationConfiguration { .filter(new StubRunnerIntegrationMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) .transform(new StubRunnerIntegrationTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) if (dsl.outputMessage) { - builder = builder.channel(dsl.outputMessage.sentTo) + builder = builder.channel(dsl.outputMessage.sentTo.clientValue) } else { builder = builder.handle(new DummyMessageHandler(), "handle") } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy index bd41ea07bf..b188cf8562 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy @@ -42,7 +42,7 @@ class StubRunnerStreamConfiguration { .filter(new StubRunnerStreamMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) .transform(new StubRunnerStreamTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) if (dsl.outputMessage) { - builder = builder.channel(dsl.outputMessage.sentTo) + builder = builder.channel(dsl.outputMessage.sentTo.clientValue) } else { builder = builder.handle(new DummyMessageHandler(), "handle") } @@ -51,7 +51,7 @@ class StubRunnerStreamConfiguration { beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); channelBindingService.bindConsumer(beanFactory.getBean(dsl.input.messageFrom, MessageChannel.class), dsl.input.messageFrom) if (dsl.outputMessage) { - channelBindingService.bindProducer(beanFactory.getBean(dsl.outputMessage.sentTo, MessageChannel.class), dsl.outputMessage.sentTo) + channelBindingService.bindProducer(beanFactory.getBean(dsl.outputMessage.sentTo.clientValue, MessageChannel.class), dsl.outputMessage.sentTo.clientValue) } } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index 98f18aab2f..f558a82bd8 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -100,7 +100,7 @@ class StubRunnerExecutor implements StubFinder { } AccurestMessage message = accurestMessaging.create(groovyDsl.outputMessage.body.clientValue, groovyDsl.outputMessage.headers.asStubSideMap()) - accurestMessaging.send(message, groovyDsl.outputMessage.sentTo) + accurestMessaging.send(message, groovyDsl.outputMessage.sentTo.clientValue) } private URL returnStubUrlIfMatches(boolean condition) { From e75bbaafbcca87423aaec7a92efe4f08b2c823a7 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 17:40:02 +0200 Subject: [PATCH 564/719] Fixed NPE, added consumer producer to DSL --- .../builder/JUnitMessagingMethodBodyBuilder.groovy | 2 +- .../builder/SpockMessagingMethodBodyBuilder.groovy | 2 +- .../io/codearte/accurest/dsl/internal/Input.groovy | 14 +++++++++++++- .../accurest/dsl/internal/OutputMessage.groovy | 8 ++++++++ .../camel/StubRunnerCamelConfiguration.groovy | 4 ++-- .../StubRunnerIntegrationConfiguration.groovy | 6 +++--- .../stream/StubRunnerStreamConfiguration.groovy | 10 +++++----- .../accurest/stubrunner/StubRunnerExecutor.groovy | 4 ++-- 8 files changed, 35 insertions(+), 15 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy index 12d62ae555..fa8551cdb2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy @@ -28,7 +28,7 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { if (request.triggeredBy) { return request.triggeredBy.executionCommand } - return "accurestMessaging.send(inputMessage, \"${request.messageFrom}\")" + return "accurestMessaging.send(inputMessage, \"${request.messageFrom.serverValue}\")" } @Override diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy index c5fba9da10..e9bbb2e1db 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy @@ -26,7 +26,7 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { if (request.triggeredBy) { return request.triggeredBy.executionCommand } - return "accurestMessaging.send(inputMessage, '${request.messageFrom}')" + return "accurestMessaging.send(inputMessage, '${request.messageFrom.serverValue}')" } @Override diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Input.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Input.groovy index 8cd7fe06f4..0b833c4090 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Input.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Input.groovy @@ -10,7 +10,7 @@ import groovy.transform.TypeChecked @ToString(includePackage = false, includeNames = true) class Input extends Common { - String messageFrom + DslProperty messageFrom ExecutionProperty triggeredBy Headers messageHeaders BodyType messageBody @@ -24,7 +24,19 @@ class Input extends Common { this.messageBody = input.messageBody } + ServerDslProperty producer(Object clientValue) { + return new ServerDslProperty(clientValue) + } + + ClientDslProperty consumer(Object clientValue) { + return new ClientDslProperty(clientValue) + } + void messageFrom(String messageFrom) { + this.messageFrom = new DslProperty<>(messageFrom) + } + + void messageFrom(DslProperty messageFrom) { this.messageFrom = messageFrom } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy index 10bc07fd17..b173c6481c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy @@ -31,6 +31,14 @@ class OutputMessage extends Common { this.sentTo = sentTo } + ServerDslProperty producer(Object clientValue) { + return new ServerDslProperty(clientValue) + } + + ClientDslProperty consumer(Object clientValue) { + return new ClientDslProperty(clientValue) + } + void body(Object bodyAsValue) { this.body = new DslProperty(bodyAsValue) } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy index d27329f5d3..a00e1d6c85 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy @@ -23,8 +23,8 @@ class StubRunnerCamelConfiguration { @Override public void configure() throws Exception { Map> accurestContracts = batchStubRunner.accurestContracts - (accurestContracts.values().flatten() as Collection).findAll { it?.input?.messageFrom && it?.outputMessage?.sentTo }.each { - from(it.input.messageFrom) + (accurestContracts.values().flatten() as Collection).findAll { it?.input?.messageFrom?.clientValue && it?.outputMessage?.sentTo }.each { + from(it.input.messageFrom.clientValue) .filter(new StubRunnerCamelPredicate(it)) .process(new StubRunnerCamelProcessor(it)) .to(it.outputMessage.sentTo.clientValue) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy index b5205afa30..f4ba7902a0 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -32,12 +32,12 @@ class StubRunnerIntegrationConfiguration { Map> accurestContracts = batchStubRunner.accurestContracts accurestContracts.each { StubConfiguration key, Collection value -> String name = "${key.groupId}_${key.artifactId}" - value.findAll { it?.input?.messageFrom }.each { GroovyDsl dsl -> + value.findAll { it?.input?.messageFrom?.clientValue }.each { GroovyDsl dsl -> String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" - IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom) + IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom.clientValue) .filter(new StubRunnerIntegrationMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) .transform(new StubRunnerIntegrationTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) - if (dsl.outputMessage) { + if (dsl.outputMessage?.sentTo) { builder = builder.channel(dsl.outputMessage.sentTo.clientValue) } else { builder = builder.handle(new DummyMessageHandler(), "handle") diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy index b188cf8562..6c3508f3ea 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy @@ -36,12 +36,12 @@ class StubRunnerStreamConfiguration { Map> accurestContracts = batchStubRunner.accurestContracts accurestContracts.each { StubConfiguration key, Collection value -> String name = "${key.groupId}_${key.artifactId}" - value.findAll { it?.input?.messageFrom }.each { GroovyDsl dsl -> + value.findAll { it?.input?.messageFrom?.clientValue }.each { GroovyDsl dsl -> String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" - IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom) + IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom.clientValue) .filter(new StubRunnerStreamMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) .transform(new StubRunnerStreamTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) - if (dsl.outputMessage) { + if (dsl.outputMessage?.sentTo) { builder = builder.channel(dsl.outputMessage.sentTo.clientValue) } else { builder = builder.handle(new DummyMessageHandler(), "handle") @@ -49,8 +49,8 @@ class StubRunnerStreamConfiguration { beanFactory.initializeBean(builder.get(), flowName) beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); - channelBindingService.bindConsumer(beanFactory.getBean(dsl.input.messageFrom, MessageChannel.class), dsl.input.messageFrom) - if (dsl.outputMessage) { + channelBindingService.bindConsumer(beanFactory.getBean(dsl.input.messageFrom.clientValue, MessageChannel.class), dsl.input.messageFrom.clientValue) + if (dsl.outputMessage?.sentTo) { channelBindingService.bindProducer(beanFactory.getBean(dsl.outputMessage.sentTo.clientValue, MessageChannel.class), dsl.outputMessage.sentTo.clientValue) } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index f558a82bd8..92cb78b7ad 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -98,8 +98,8 @@ class StubRunnerExecutor implements StubFinder { if (!groovyDsl.outputMessage) { return } - AccurestMessage message = accurestMessaging.create(groovyDsl.outputMessage.body.clientValue, - groovyDsl.outputMessage.headers.asStubSideMap()) + AccurestMessage message = accurestMessaging.create(groovyDsl.outputMessage?.body?.clientValue, + groovyDsl.outputMessage?.headers?.asStubSideMap()) accurestMessaging.send(message, groovyDsl.outputMessage.sentTo.clientValue) } From f18cb39fe62d122d7e3eda7391e2425394f975c9 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 25 Apr 2016 17:49:48 +0200 Subject: [PATCH 565/719] Added consumer producer description --- .../MessagingMethodBodyBuilderSpec.groovy | 50 +++++++++++++++++++ docs/src/docs/asciidoc/contract.adoc | 12 ++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy index 1855c7b88b..22dba316f2 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.builder +import io.codearte.accurest.dsl.Accurest import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification /** @@ -375,4 +376,53 @@ then: return text.stripIndent().stripMargin().replace(' ', '').replace('\n', '').replace('\t', '').replaceAll("\\W", "") } + def "should generate tests without headers for JUnit with consumer / producer notation"() { + given: + def contractDsl = + // tag::consumer_producer[] +Accurest.make { + label 'some_label' + input { + messageFrom value(consumer('jms:output'), producer('jms:input')) + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + } + outputMessage { + sentTo $(consumer('jms:input'), producer('jms:output')) + body([ + bookName: 'foo' + ]) + } +} + // end::consumer_producer[] + MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + String expectedMsg = + ''' + // 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).isNotNull(); + DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); + assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); +''' + stripped(test) == stripped(expectedMsg) + } + } diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/docs/asciidoc/contract.adoc index eb083a9338..8778f7259b 100644 --- a/docs/src/docs/asciidoc/contract.adoc +++ b/docs/src/docs/asciidoc/contract.adoc @@ -190,4 +190,14 @@ include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/a In this case the output message will be sent to `output` if a proper message will be received on the `input` destination. In the message *publisher's* side we will generate a test that will send the input message to the defined destination. On the *consumer* side you can either send a message to the input -destination or use the `some_label` to trigger the message. \ No newline at end of file +destination or use the `some_label` to trigger the message. + +==== Consumer / Producer + +In HTTP you have a notion of `client`/`stub and `server`/`test` notation. You can use them also in messaging but we're providing also the `consumer` and `produer` methods +as presented below (note you can use either `$` or `value` methods to provide `consumer` and `producer` parts) + +[source,groovy] +---- +include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=consumer_producer] +---- \ No newline at end of file From 3255cd4407b64f0d7d8fc74679b39b6c7e181ede Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Mon, 25 Apr 2016 18:28:09 +0200 Subject: [PATCH 566/719] parametrizable stubs classifier (#14) --- .../accurest/maven/GenerateStubsMojo.groovy | 17 ++++++++++------- .../codearte/accurest/maven/PluginUnitTest.java | 8 ++++++++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy index 028ce108bc..53bd066431 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy @@ -41,6 +41,9 @@ class GenerateStubsMojo extends AbstractMojo { @Parameter(defaultValue = 'true') private boolean attachContracts + @Parameter(defaultValue = 'stubs') + private String classifier + void execute() throws MojoExecutionException, MojoFailureException { if (skip) { @@ -48,16 +51,16 @@ class GenerateStubsMojo extends AbstractMojo { return } - File stubJarFile = createStubJar(outputDirectory) - projectHelper.attachArtifact(project, 'jar', 'stubs', stubJarFile) + File stubsJarFile = createStubJar(outputDirectory) + projectHelper.attachArtifact(project, 'jar', classifier, stubsJarFile) } private File createStubJar(File stubsOutputDir) { if (!stubsOutputDir.exists()) { throw new MojoExecutionException("Stubs could not be found: $stubsOutputDir.\nPlease make sure that accurest:convert was invoked"); } - String stubArchiveName = project.getBuild().getFinalName() + "-stubs.jar"; - File stubJarFile = new File(projectBuildDirectory, stubArchiveName); + String stubArchiveName = "${project.build.finalName}-${classifier}.jar"; + File stubsJarFile = new File(projectBuildDirectory, stubArchiveName); try { if (attachContracts) { @@ -67,12 +70,12 @@ class GenerateStubsMojo extends AbstractMojo { jarArchiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN] as String[], [ACCUREST_FILE_PATTERN] as String[]); } jarArchiver.setCompress(true); - jarArchiver.setDestFile(stubJarFile); + jarArchiver.setDestFile(stubsJarFile); jarArchiver.createArchive(); } catch (Exception e) { - throw new MojoFailureException('Exception while packaging.', e); + throw new MojoFailureException("Exception while packaging ${classifier} jar.", e); } - return stubJarFile + return stubsJarFile } } diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 8f2f195b97..5ade936531 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -72,4 +72,12 @@ public class PluginUnitTest { // FIXME: add assertion for jar content } + @Test + public void shouldGenerateStubsWithCustomClassifier() throws Exception { + File basedir = resources.getBasedir("generatedStubs"); + maven.executeMojo(basedir, "generateStubs", newParameter("classifier", "foo")); + assertFilesPresent(basedir, "target/sample-project-0.1-foo.jar"); + } + + } From 45e8a053f1f9ea3be8633b4a1bba135ea5a930b1 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Mon, 25 Apr 2016 16:31:56 +0000 Subject: [PATCH 567/719] Sets project version to 0.5.11-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 902d01af3e..0b43b000e4 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.10-SNAPSHOT + 0.5.11-SNAPSHOT Accurest Maven Plugin Accurate REST Maven Plugin From ba61c3f42ddf065ee16cffed7323b9d30570268a Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 25 Apr 2016 20:39:24 +0200 Subject: [PATCH 568/719] Release version: 1.1.0-M1 [ci skip] From fe45916369680550a9c95a064571fb05fe0a6f0a Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 25 Apr 2016 20:39:24 +0200 Subject: [PATCH 569/719] Release version: 1.1.0-M1 [ci skip] From b6898c4e4a06efb81c437ded977d0085467ac5f2 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Mon, 25 Apr 2016 20:39:24 +0200 Subject: [PATCH 570/719] Release version: 1.1.0-M1 [ci skip] From a05acfa0be7381021919e22a3de56027be8fa830 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 26 Apr 2016 10:35:07 +0200 Subject: [PATCH 571/719] fix backward compatibility for stub-runner api (#243) --- .../stubrunner/BatchStubRunnerFactory.groovy | 6 ++++++ .../codearte/accurest/stubrunner/StubRunner.groovy | 14 ++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy index b57b1c37ad..a7e3412fa9 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy @@ -27,6 +27,12 @@ class BatchStubRunnerFactory { this(stubRunnerOptions, dependencies, new GrapeStubDownloader(), accurestMessaging) } + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, + Collection dependencies, + StubDownloader stubDownloader) { + this(stubRunnerOptions, dependencies, new GrapeStubDownloader(), new NoOpAccurestMessaging()) + } + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies, StubDownloader stubDownloader, diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy index 839b12c401..69d4940c4f 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -25,17 +25,15 @@ class StubRunner implements StubRunning { @Deprecated StubRunner(Arguments arguments) { - this.stubsConfiguration = arguments.stub - this.stubRunnerOptions = arguments.stubRunnerOptions - this.stubRepository = new StubRepository(new File(arguments.repositoryPath)) - AvailablePortScanner portScanner = new AvailablePortScanner(stubRunnerOptions.minPortValue, - stubRunnerOptions.maxPortValue) - this.accurestMessaging = new NoOpAccurestMessaging() - this.localStubRunner = new StubRunnerExecutor(portScanner, accurestMessaging) + this(arguments.stubRunnerOptions, arguments.repositoryPath, arguments.stub) + } + + StubRunner(StubRunnerOptions stubRunnerOptions, String repositoryPath, StubConfiguration stubsConfiguration) { + this(stubRunnerOptions, repositoryPath, stubsConfiguration, new NoOpAccurestMessaging()) } StubRunner(StubRunnerOptions stubRunnerOptions, String repositoryPath, StubConfiguration stubsConfiguration, - AccurestMessaging accurestMessaging) { + AccurestMessaging accurestMessaging) { this.stubsConfiguration = stubsConfiguration this.stubRunnerOptions = stubRunnerOptions this.stubRepository = new StubRepository(new File(repositoryPath)) From afbde780d3dcd0c6df3ff745038397aad506ab4d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 26 Apr 2016 14:18:12 +0200 Subject: [PATCH 572/719] Throws exception on missing label also will print a list of available labels for dependencies fixes #244 --- .../stubrunner/junit/AccurestRule.java | 37 +++++++------- .../camel/CamelStubRunnerSpec.groovy | 12 ++--- .../IntegrationStubRunnerSpec.groovy | 19 +++---- .../stream/StreamStubRunnerSpec.groovy | 16 +++--- .../stubrunner/BatchStubRunner.groovy | 49 ++++++++++++++++--- .../accurest/stubrunner/StubRunner.groovy | 12 ++--- .../stubrunner/StubRunnerExecutor.groovy | 20 +++++--- .../accurest/stubrunner/StubTrigger.groovy | 12 +++-- .../stubrunner/BatchStubRunnerSpec.groovy | 12 +++++ 9 files changed, 117 insertions(+), 72 deletions(-) diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index 85a8768e61..52178ecc01 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -1,18 +1,5 @@ package io.codearte.accurest.stubrunner.junit; -import java.net.URL; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - import io.codearte.accurest.dsl.GroovyDsl; import io.codearte.accurest.stubrunner.BatchStubRunner; import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; @@ -22,6 +9,18 @@ import io.codearte.accurest.stubrunner.StubFinder; import io.codearte.accurest.stubrunner.StubRunnerOptions; import io.codearte.accurest.stubrunner.util.StringUtils; import io.codearte.accurest.stubrunner.util.StubsParser; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * JUnit class rule that allows you to download the provided stubs. @@ -170,17 +169,17 @@ public class AccurestRule implements TestRule, StubFinder { } @Override - public void trigger(String ivyNotation, String labelName) { - stubFinder.trigger(ivyNotation, labelName); + public boolean trigger(String ivyNotation, String labelName) { + return stubFinder.trigger(ivyNotation, labelName); } @Override - public void trigger(String labelName) { - stubFinder.trigger(labelName); + public boolean trigger(String labelName) { + return stubFinder.trigger(labelName); } @Override - public void trigger() { - stubFinder.trigger(); + public boolean trigger() { + return stubFinder.trigger(); } } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy index fecb9fa70a..28e8053387 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -93,22 +93,18 @@ class CamelStubRunnerSpec extends Specification { receivedMessage.in.headers.get('BOOK-NAME') == 'foo' } - def 'should not run any wrong trigger when missing label is passed'() { + def 'should throw an exception when missing label is passed'() { when: stubFinder.trigger('missing label') then: - Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 100) - and: - receivedMessage == null + thrown(IllegalArgumentException) } - def 'should not run any wrong trigger when missing label and artifactid is passed'() { + def 'should throw an exception when missing label and artifactid is passed'() { when: stubFinder.trigger('some:service', 'return_book_1') then: - Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 100) - and: - receivedMessage == null + thrown(IllegalArgumentException) } def 'should trigger messages by running all triggers'() { diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy index 8f071f5bb1..6c69f17cc4 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy @@ -6,7 +6,6 @@ import io.codearte.accurest.dsl.GroovyDsl import io.codearte.accurest.messaging.AccurestMessage import io.codearte.accurest.messaging.AccurestMessaging import io.codearte.accurest.stubrunner.StubFinder -import org.springframework.beans.factory.BeanNotOfRequiredTypeException import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.test.SpringApplicationContextLoader @@ -95,24 +94,18 @@ class IntegrationStubRunnerSpec extends Specification { receivedMessage.headers.get('BOOK-NAME') == 'foo' } - def 'should not run any wrong trigger when missing label is passed'() { - given: - stubFinder.trigger('missing label') + def 'should throw exception when missing label is passed'() { when: - messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + stubFinder.trigger('missing label') then: - Exception e = thrown(RuntimeException) - e.cause.class == BeanNotOfRequiredTypeException + thrown(IllegalArgumentException) } - def 'should not run any wrong trigger when missing label and artifactid is passed'() { - given: - stubFinder.trigger('some:service', 'return_book_1') + def 'should throw exception when missing label and artifactid is passed'() { when: - messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + stubFinder.trigger('some:service', 'return_book_1') then: - Exception e = thrown(RuntimeException) - e.cause.class == BeanNotOfRequiredTypeException + thrown(IllegalArgumentException) } def 'should trigger messages by running all triggers'() { diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy index 72177a855e..1090f1c5ea 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy @@ -92,22 +92,18 @@ class StreamStubRunnerSpec extends Specification { receivedMessage.headers.get('BOOK-NAME') == 'foo' } - def 'should not run any wrong trigger when missing label is passed'() { - given: - stubFinder.trigger('missing label') + def 'should throw exception when missing label is passed'() { when: - AccurestMessage message = messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + stubFinder.trigger('missing label') then: - message == null + thrown(IllegalArgumentException) } - def 'should not run any wrong trigger when missing label and artifactid is passed'() { - given: - stubFinder.trigger('some:service', 'return_book_1') + def 'should throw exception when missing label and artifactid is passed'() { when: - AccurestMessage message = messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + stubFinder.trigger('some:service', 'return_book_1') then: - message == null + thrown(IllegalArgumentException) } def 'should trigger messages by running all triggers'() { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy index 7aff5d3a3d..16ef82b2fe 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy @@ -57,18 +57,55 @@ class BatchStubRunner implements StubRunning { } @Override - void trigger(String ivyNotation, String labelName) { - stubRunners.each { it.trigger(ivyNotation, labelName) } + boolean trigger(String ivyNotation, String labelName) { + boolean triggered = stubRunners.inject(false) { boolean acc, StubRunner stubRunner -> + boolean success = stubRunner.trigger(ivyNotation, labelName) + if (acc) { + return true + } + return success + } + if (!triggered) { + throw new IllegalArgumentException("No label with name [$labelName] for " + + "dependency [$ivyNotation] was found. Here you have the list of dependencies " + + "and their labels [${ivyToLabels()}") + } + return triggered + } + + private String ivyToLabels() { + return (getAccurestContracts().collectEntries { + [(it.key.toColonSeparatedDependencyNotation()) : it.value.collect { it.label }] + } as Map>).entrySet().collect { + "Dependency [${it.key}] has labels ${it.value}]" + }.join('\n') } @Override - void trigger(String labelName) { - stubRunners.each { it.trigger(labelName) } + boolean trigger(String labelName) { + boolean triggered = stubRunners.inject(false) { boolean acc, StubRunner stubRunner -> + boolean success = stubRunner.trigger(labelName) + if (acc) { + return true + } + return success + } + if (!triggered) { + throw new IllegalArgumentException("No label with name [$labelName] was found. " + + "Here you have the list of dependencies and their labels [${ivyToLabels()}") + } + return triggered } @Override - void trigger() { - stubRunners.each { it.trigger() } + boolean trigger() { + return stubRunners.inject(false) { boolean acc, StubRunner stubRunner -> + boolean success = stubRunner.trigger() + if (acc) { + return true + } + return success + } } @Override diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy index 69d4940c4f..91a5174775 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -75,18 +75,18 @@ class StubRunner implements StubRunning { } @Override - void trigger(String ivyNotation, String labelName) { - localStubRunner.trigger(ivyNotation, labelName) + boolean trigger(String ivyNotation, String labelName) { + return localStubRunner.trigger(ivyNotation, labelName) } @Override - void trigger(String labelName) { - localStubRunner.trigger(labelName) + boolean trigger(String labelName) { + return localStubRunner.trigger(labelName) } @Override - void trigger() { - localStubRunner.trigger() + boolean trigger() { + return localStubRunner.trigger() } private void registerShutdownHook() { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index 92cb78b7ad..20649d03ae 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -69,29 +69,35 @@ class StubRunnerExecutor implements StubFinder { } @Override - void trigger(String ivyNotationAsString, String labelName) { + boolean trigger(String ivyNotationAsString, String labelName) { Collection matchingContracts = getAccurestContracts().findAll { it.key.matches(ivyNotationAsString) }.values().flatten() as Collection - triggerForDsls(matchingContracts, labelName) + return triggerForDsls(matchingContracts, labelName) } @Override - void trigger(String labelName) { - triggerForDsls(getAccurestContracts().values().flatten() as Collection, labelName) + boolean trigger(String labelName) { + return triggerForDsls(getAccurestContracts().values().flatten() as Collection, labelName) } - private void triggerForDsls(Collection dsls, String labelName) { - dsls.findAll { it.label == labelName}.each { + private boolean triggerForDsls(Collection dsls, String labelName) { + Collection matchingDsls = dsls.findAll { it.label == labelName} + if (matchingDsls.empty) { + return false + } + matchingDsls.each { sendMessageIfApplicable(it) } + return true } @Override - void trigger() { + boolean trigger() { (getAccurestContracts().values().flatten() as Collection).each { GroovyDsl groovyDsl -> sendMessageIfApplicable(groovyDsl) } + return true } private void sendMessageIfApplicable(GroovyDsl groovyDsl) { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy index 94b900bc6d..cee1acebec 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy @@ -6,20 +6,26 @@ interface StubTrigger { * Triggers an event by a given label for a given {@code groupid:artifactid} notation. You can use only {@code artifactId} too. * * Feature related to messaging. + * + * @return true - if managed to run a trigger */ - void trigger(String ivyNotation, String labelName) + boolean trigger(String ivyNotation, String labelName) /** * Triggers an event by a given label. * * Feature related to messaging. + * + * @return true - if managed to run a trigger */ - void trigger(String labelName) + boolean trigger(String labelName) /** * Triggers all possible events. * * Feature related to messaging. + * + * @return true - if managed to run a trigger */ - void trigger() + boolean trigger() } \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy index 71935f62f9..19fbb1227e 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.stubrunner +import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification class BatchStubRunnerSpec extends Specification { @@ -22,10 +23,21 @@ class BatchStubRunnerSpec extends Specification { !batchStubRunner.findStubUrl(UNKNOWN_STUB_PATH) } + def 'should throw exception if trying to execute not available trigger'() { + given: + BatchStubRunner batchStubRunner = new BatchStubRunner(runners()) + when: + batchStubRunner.trigger('non existing label') + then: + IllegalArgumentException exception = thrown(IllegalArgumentException) + exception.message == "No label with name [non existing label] was found. Here you have the list of dependencies and their labels [Dependency [a:b:c] has labels [foo]]" + } + Collection runners() { StubRunner runner = Mock(StubRunner) runner.findStubUrl("group", "knownArtifact") >> KNOWN_STUB_URL runner.findStubUrl("group", "unknownArtifact") >> null + runner.accurestContracts >> [(new StubConfiguration('a', 'b', 'c')): [GroovyDsl.make { outputMessage { label 'foo' } }]] return [runner] } From 305452c54abd6de4ce0e19c048a859c5841e1e68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 26 Apr 2016 16:34:15 +0200 Subject: [PATCH 573/719] Feature/complex test configuration (#16) * custom imports support * add missing options to generateTests --- .../accurest/maven/GenerateTestsMojo.groovy | 29 +++++ src/site/asciidoc/complex.adoc | 38 ++++++ src/site/site.xml | 1 + .../io/codearte/accurest/maven/PluginIT.java | 14 +++ .../accurest/maven/PluginUnitTest.java | 9 ++ .../projects/complex-configuration/.gitignore | 1 + .../projects/complex-configuration/pom.xml | 112 ++++++++++++++++++ .../frauddetection/Application.java | 12 ++ .../FraudDetectionController.java | 39 ++++++ .../frauddetection/model/FraudCheck.java | 29 +++++ .../model/FraudCheckResult.java | 32 +++++ .../model/FraudCheckStatus.java | 5 + .../src/test/accurest/brokenContract.groovy | 28 +++++ .../accurest/shouldMarkClientAsFraud.groovy | 27 +++++ .../shouldMarkClientAsNotFraud.groovy | 28 +++++ .../frauddetection/BaseAccurest.java | 14 +++ .../matchers/CustomMatchers.java | 11 ++ .../src/test/accurest/greetings_ok.json | 21 ---- .../greetings_with_default_value.json | 16 --- 19 files changed, 429 insertions(+), 37 deletions(-) create mode 100644 src/site/asciidoc/complex.adoc create mode 100644 src/test/projects/complex-configuration/.gitignore create mode 100644 src/test/projects/complex-configuration/pom.xml create mode 100644 src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java create mode 100644 src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java create mode 100644 src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java create mode 100644 src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java create mode 100644 src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java create mode 100644 src/test/projects/complex-configuration/src/test/accurest/brokenContract.groovy create mode 100644 src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsFraud.groovy create mode 100644 src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy create mode 100644 src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java create mode 100644 src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java delete mode 100644 src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.json delete mode 100644 src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.json diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy index cef5361d73..c68bdc32c2 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy @@ -45,6 +45,30 @@ class GenerateTestsMojo extends AbstractMojo { @Parameter private String nameSuffixForTests + /** + * Imports that should be added to generated tests + */ + @Parameter + private String[] imports + + /** + * Static imports that should be added to generated tests + */ + @Parameter + private String[] staticImports + + /** + * Patterns that should not be taken into account for processing + */ + @Parameter + List excludedFiles + + /** + * Patterns for which Accurest should generate @Ignored tests + */ + @Parameter + List ignoredFiles + @Parameter(defaultValue = '${project}', readonly = true) private MavenProject project @@ -70,6 +94,11 @@ class GenerateTestsMojo extends AbstractMojo { config.ruleClassForTests = ruleClassForTests config.nameSuffixForTests = nameSuffixForTests + config.setImports(imports) + config.setStaticImports(staticImports) + config.setIgnoredFiles(ignoredFiles) + config.setExcludedFiles(excludedFiles) + project.addTestCompileSourceRoot(generatedTestSourcesDir.absolutePath) if (log.isInfoEnabled()) { diff --git a/src/site/asciidoc/complex.adoc b/src/site/asciidoc/complex.adoc new file mode 100644 index 0000000000..cb90a65901 --- /dev/null +++ b/src/site/asciidoc/complex.adoc @@ -0,0 +1,38 @@ +== More Complex Plugin Configuration + +Sample more complex configuration for Java Project with JUnit tests. + + +=== Project configuration for Accurest with JUnit tests and stub publishing + +[source,xml] +---- +include::../../../src/test/projects/complex-configuration/pom.xml[tags=plugin] +---- + +=== Base Test class + +[source,java] +---- +include::../../../src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java[] +---- + + +=== Sample additional matcher + +[source,java] +---- +include::../../../src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java[] +---- + +=== Sample contract using matcher + +[source,java] +---- +include::../../../src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy[] +---- + + +=== Project source code + +https://github.com/Codearte/accurest-maven-plugin/tree/master/src/test/projects/complex-configuration \ No newline at end of file diff --git a/src/site/site.xml b/src/site/site.xml index 005d021238..a05826b4f6 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -30,6 +30,7 @@ + diff --git a/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/io/codearte/accurest/maven/PluginIT.java index b1e5415683..4a4e396f46 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIT.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIT.java @@ -1,7 +1,9 @@ package io.codearte.accurest.maven; import java.io.File; +import java.util.regex.Pattern; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -55,6 +57,18 @@ public class PluginIT { .assertErrorFreeLog(); } + @Test + @Ignore("Ignored, because of bug accurest#245") + public void should_build_project_project_with_complex_configuration() throws Exception { + File basedir = resources.getBasedir("complex-configuration"); + maven.forProject(basedir) + .execute("package") + .assertErrorFreeLog() + .assertLogText("Tests run: 2, Failures: 0, Errors: 0, Skipped: 1") + .assertLogText("Running com.blogspot.toomuchcoding.frauddetection.AccurestTest") + .assertErrorFreeLog(); + } + @Test public void should_convert_Accurest_Contracts_to_WireMock_Stubs_mappings() throws Exception { File basedir = resources.getBasedir("pomless"); diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 5ade936531..47b3c659a3 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -5,6 +5,7 @@ import static io.takari.maven.testing.TestResources.assertFileContents; import static io.takari.maven.testing.TestResources.assertFilesPresent; import java.io.File; +import java.util.Arrays; import org.junit.Rule; import org.junit.Test; @@ -57,6 +58,14 @@ public class PluginUnitTest { "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestTest.java"); } + @Test + public void shouldGenerateContractTestsWithCustomImports() throws Exception { + File basedir = resources.getBasedir("basic"); + maven.executeMojo(basedir, "generateTests", newParameter("imports", "")); + assertFilesPresent(basedir, + "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestTest.java"); + } + @Test public void shouldGenerateStubs() throws Exception { File basedir = resources.getBasedir("generatedStubs"); diff --git a/src/test/projects/complex-configuration/.gitignore b/src/test/projects/complex-configuration/.gitignore new file mode 100644 index 0000000000..1de565933b --- /dev/null +++ b/src/test/projects/complex-configuration/.gitignore @@ -0,0 +1 @@ +target \ No newline at end of file diff --git a/src/test/projects/complex-configuration/pom.xml b/src/test/projects/complex-configuration/pom.xml new file mode 100644 index 0000000000..756ca7d8f1 --- /dev/null +++ b/src/test/projects/complex-configuration/pom.xml @@ -0,0 +1,112 @@ + + + 4.0.0 + + com.blogspot.toomuchcoding.frauddetection + frauddetection + 0.1.0 + + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + ch.qos.logback + logback-classic + + + + + + com.jayway.restassured + rest-assured + 2.9.0 + test + + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + test + + + com.toomuchcoding.jsonassert + jsonassert + 0.3.0 + test + + + org.assertj + assertj-core + 2.3.0 + test + + + + + + 1.8 + ${it-plugin.version} + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + io.codearte.accurest + accurest-maven-plugin + ${accurest-plugin.version} + + + + convert + generateStubs + generateTests + + + com.blogspot.toomuchcoding.frauddetection + MOCKMVC + JUNIT + stubs + Test + org.junit.rules.ErrorCollector + + com.blogspot.toomuchcoding.frauddetection.matchers.CustomMatchers.* + + + com.blogspot.toomuchcoding.frauddetection.matchers.CustomMatchers + + + broken** + + + shouldMarkClientAsFraud.groovy + + + + + + com.blogspot.toomuchcoding.frauddetection.BaseAccurest + + + + + + diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java new file mode 100644 index 0000000000..9ba071ba43 --- /dev/null +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -0,0 +1,12 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java new file mode 100644 index 0000000000..e264462cce --- /dev/null +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java @@ -0,0 +1,39 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheck; +import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckResult; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.math.BigDecimal; + +import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.FRAUD; +import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.OK; +import static org.springframework.web.bind.annotation.RequestMethod.PUT; + +@RestController +public class FraudDetectionController { + + private static final String FRAUD_SERVICE_JSON_VERSION_1 = "application/vnd.fraud.v1+json"; + private static final String NO_REASON = null; + private static final String AMOUNT_TOO_HIGH = "Amount too high"; + private static final BigDecimal MAX_AMOUNT = new BigDecimal("5000"); + + @RequestMapping( + value = "/fraudcheck", + method = PUT, + consumes = FRAUD_SERVICE_JSON_VERSION_1, + produces = FRAUD_SERVICE_JSON_VERSION_1) + public FraudCheckResult fraudCheck(@RequestBody FraudCheck fraudCheck) { + if (amountGreaterThanThreshold(fraudCheck)) { + return new FraudCheckResult(FRAUD, AMOUNT_TOO_HIGH); + } + return new FraudCheckResult(OK, NO_REASON); + } + + private boolean amountGreaterThanThreshold(FraudCheck fraudCheck) { + return MAX_AMOUNT.compareTo(fraudCheck.getLoanAmount()) < 0; + } + +} diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java new file mode 100644 index 0000000000..77471aee19 --- /dev/null +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java @@ -0,0 +1,29 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +import java.math.BigDecimal; + +public class FraudCheck { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudCheck() { + } + + public String getClientPesel() { + return clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java new file mode 100644 index 0000000000..28efc573f5 --- /dev/null +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java @@ -0,0 +1,32 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public class FraudCheckResult { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudCheckResult() { + } + + public FraudCheckResult(FraudCheckStatus fraudCheckStatus, String rejectionReason) { + this.fraudCheckStatus = fraudCheckStatus; + this.rejectionReason = rejectionReason; + } + + public FraudCheckStatus getFraudCheckStatus() { + return fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b87c365d51 --- /dev/null +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package com.blogspot.toomuchcoding.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/src/test/projects/complex-configuration/src/test/accurest/brokenContract.groovy b/src/test/projects/complex-configuration/src/test/accurest/brokenContract.groovy new file mode 100644 index 0000000000..cd810a29dc --- /dev/null +++ b/src/test/projects/complex-configuration/src/test/accurest/brokenContract.groovy @@ -0,0 +1,28 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 999 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsFraud.groovy b/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsFraud.groovy new file mode 100644 index 0000000000..44b1c08604 --- /dev/null +++ b/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsFraud.groovy @@ -0,0 +1,27 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy b/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy new file mode 100644 index 0000000000..7bc64d0dac --- /dev/null +++ b/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy @@ -0,0 +1,28 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java b/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java new file mode 100644 index 0000000000..0e7194f8ed --- /dev/null +++ b/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java @@ -0,0 +1,14 @@ +package com.blogspot.toomuchcoding.frauddetection; + +import org.junit.Before; + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; + +public class BaseAccurest { + + @Before + public void setup() { + RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()); + } + +} diff --git a/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java b/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java new file mode 100644 index 0000000000..a113e4ca37 --- /dev/null +++ b/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java @@ -0,0 +1,11 @@ +package com.blogspot.toomuchcoding.frauddetection.matchers; + +import org.junit.Assert; + +public class CustomMatchers { + + public static void assertThatRejectionReasonIsNull(String rejectionReason) { + Assert.assertNull(rejectionReason); + } + +} diff --git a/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.json b/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.json deleted file mode 100644 index 548fb8e723..0000000000 --- a/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "request" : { - "urlPath" : "/greeting", - "method" : "GET", - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - }, - "queryParameters" : { - "name" : { - "equalTo" : "Something" - } - } - }, - "response" : { - "status" : 200, - "body" : "{\"id\":1,\"content\":\"Hello, Something!\"}" - }, - "priority" : 2 -} \ No newline at end of file diff --git a/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.json b/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.json deleted file mode 100644 index e014f2ab69..0000000000 --- a/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "request" : { - "url" : "/greeting", - "method" : "GET", - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - } - }, - "response" : { - "status" : 200, - "body" : "{\"id\":1,\"content\":\"Hello, World!\"}" - }, - "priority" : 2 -} \ No newline at end of file From b1ad9820ef07cdbf3a1af98138cb6de900a4bd40 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Tue, 26 Apr 2016 14:40:33 +0000 Subject: [PATCH 574/719] Sets project version to 0.5.12-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0b43b000e4..249c90f381 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.11-SNAPSHOT + 0.5.12-SNAPSHOT Accurest Maven Plugin Accurate REST Maven Plugin From b2e6ea7c26aaaf8f071136737d5982727aab6f7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 26 Apr 2016 20:48:35 +0200 Subject: [PATCH 575/719] Fixes api change introduced in latest wiremock beta. (#246) * NoSuchMethodError: com.github.tomakehurst.wiremock.client.WireMock.get(Lcom/github/tomakehurst/wiremock/client/UrlMatchingStrategy;)Lcom/github/tomakehurst/wiremock/client/MappingBuilder; --- .../io/codearte/accurest/plugin/AccurestGradlePlugin.groovy | 2 +- .../src/test/resources/functionalTest/bootSimple/build.gradle | 2 +- .../resources/functionalTest/sampleJerseyProject/build.gradle | 2 +- .../test/resources/functionalTest/sampleProject/build.gradle | 2 +- .../test/resources/functionalTest/scenarioProject/build.gradle | 2 +- gradle.properties | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) 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 9709541e2d..1ad75e1ba1 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 @@ -28,7 +28,7 @@ class AccurestGradlePlugin implements Plugin { createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() - project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.5-beta") + project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.10-beta") project.dependencies.add("testCompile", "com.toomuchcoding.jsonassert:jsonassert:${extension.getJsonAssertVersion()}") project.dependencies.add("testCompile", "org.assertj:assertj-core:2.3.0") diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index b20f2a69eb..e550da98c6 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -43,7 +43,7 @@ dependencies { compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' compile 'com.jayway.jsonpath:json-path-assert:2.2.0' - testCompile "com.github.tomakehurst:wiremock:2.0.5-beta" + testCompile "com.github.tomakehurst:wiremock:2.0.10-beta" testCompile "org.spockframework:spock-spring:1.0-groovy-2.4" testCompile "com.jayway.restassured:rest-assured:$restAssuredVersion" testCompile "com.jayway.restassured:spring-mock-mvc:$restAssuredVersion" diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index 8cf1b6941e..3e3e107564 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -13,7 +13,7 @@ group = 'io.codearte.accurest.testprojects' ext { restAssuredVersion = '2.5.0' spockVersion = '1.0-groovy-2.4' - wiremockVersion = '2.0.5-beta' + wiremockVersion = '2.0.10-beta' accurestStubsBaseDirectory = 'src/test/resources/stubs' } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index c2fb66a1f6..606fc7ba5d 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -11,7 +11,7 @@ buildscript { ext { restAssuredVersion = '2.5.0' spockVersion = '1.0-groovy-2.4' - wiremockVersion = '2.0.5-beta' + wiremockVersion = '2.0.10-beta' accurestStubsBaseDirectory = 'src/test/resources/stubs' } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index 4d4edb4965..6b72e88a6a 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -11,7 +11,7 @@ buildscript { ext { restAssuredVersion = '2.5.0' spockVersion = '1.0-groovy-2.4' - wiremockVersion = '2.0.5-beta' + wiremockVersion = '2.0.10-beta' accurestStubsBaseDirectory = 'src/test/resources/stubs' } diff --git a/gradle.properties b/gradle.properties index 00b1483625..14988fcafe 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ nexusUsername = nexusPassword = -wiremockVersion = 2.0.5-beta +wiremockVersion = 2.0.10-beta jsonassertVersion = 0.2.2 BOM_VERSION=Brixton-1.0.0.RC1 \ No newline at end of file From 92f3eafa0e9505ea2454e8dbcea375c09f48585a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Apr 2016 12:36:34 +0200 Subject: [PATCH 576/719] Updated docs --- stub-runner/stub-runner-junit/README.adoc | 11 ++++++----- .../integration/IntegrationStubRunnerSpec.groovy | 8 ++++---- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/stub-runner/stub-runner-junit/README.adoc b/stub-runner/stub-runner-junit/README.adoc index 92aae748a3..5a778ae104 100644 --- a/stub-runner/stub-runner-junit/README.adoc +++ b/stub-runner/stub-runner-junit/README.adoc @@ -8,11 +8,12 @@ include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnit ---- After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to: -* download them -* cache them locally -* unzip them to a temporary folder -* start a WireMock server for each Maven dependency on a random port from the provided range of ports -* feed the WireMock server with all JSON files that are valid WireMock definitions + +- download them +- cache them locally +- unzip them to a temporary folder +- start a WireMock server for each Maven dependency on a random port from the provided range of ports +- feed the WireMock server with all JSON files that are valid WireMock definitions Stub Runner uses http://docs.groovy-lang.org/latest/html/documentation/grape.html[Groovy's Grape] mechanism to download the Maven dependencies. Check their http://docs.groovy-lang.org/latest/html/documentation/grape.html[docs] for more information. diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy index 6c69f17cc4..02b875af6f 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy @@ -154,7 +154,7 @@ class IntegrationStubRunnerSpec extends Specification { triggeredBy('bookReturnedTriggered()') } outputMessage { - sentTo('jms:output') + sentTo('output') body('''{ "bookName" : "foo" }''') headers { header('BOOK-NAME', 'foo') @@ -168,7 +168,7 @@ class IntegrationStubRunnerSpec extends Specification { io.codearte.accurest.dsl.GroovyDsl.make { label 'return_book_2' input { - messageFrom('jms:input') + messageFrom('input') messageBody([ bookName: 'foo' ]) @@ -177,7 +177,7 @@ class IntegrationStubRunnerSpec extends Specification { } } outputMessage { - sentTo('jms:output') + sentTo('output') body([ bookName: 'foo' ]) @@ -193,7 +193,7 @@ class IntegrationStubRunnerSpec extends Specification { io.codearte.accurest.dsl.GroovyDsl.make { label 'delete_book' input { - messageFrom('jms:delete') + messageFrom('delete') messageBody([ bookName: 'foo' ]) From 56c1f34c81e9e40ac2ecc96ab58ff3ab22a28fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Wed, 27 Apr 2016 12:52:19 +0200 Subject: [PATCH 577/719] Use concrete deps version (#17) --- pom.xml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/pom.xml b/pom.xml index 249c90f381..73cd5bbb5a 100644 --- a/pom.xml +++ b/pom.xml @@ -377,6 +377,19 @@ 4.12 test + + + + commons-io + commons-io + 2.5 + + + org.apache.commons + commons-lang3 + 3.4 + + From d6cbac309d6eaee597fc08cef10dca7f400702fb Mon Sep 17 00:00:00 2001 From: Travis CI Date: Wed, 27 Apr 2016 10:57:31 +0000 Subject: [PATCH 578/719] Sets project version to 0.5.13-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 73cd5bbb5a..4cff231981 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.12-SNAPSHOT + 0.5.13-SNAPSHOT Accurest Maven Plugin Accurate REST Maven Plugin From 2696569a854728d2ad217165c773361e92ca48b0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Apr 2016 16:39:11 +0200 Subject: [PATCH 579/719] Stub Runner Spring Boot version (#248) fixes #247 --- .../bootSimple/gradle.properties | 4 +- .../messagingProject/build.gradle | 8 +- .../messagingProject/gradle.properties | 4 +- gradle.properties | 3 +- samples/messaging-camel/build.gradle | 4 +- samples/messaging-integration/build.gradle | 6 +- samples/messaging-spring/build.gradle | 4 +- samples/messaging-stream/build.gradle | 2 +- settings.gradle | 1 + stub-runner/stub-runner-boot/README.adoc | 51 ++++++++++ stub-runner/stub-runner-boot/build.gradle | 22 +++++ .../boot/HttpStubsController.groovy | 38 ++++++++ .../stubrunner/boot/StubRunnerBoot.groovy | 15 +++ .../stubrunner/boot/TriggerController.groovy | 59 +++++++++++ .../main/resources/META-INF/spring.factories | 3 + .../stubrunner/boot/StubRunnerBootSpec.groovy | 92 ++++++++++++++++++ .../src/test/resources/application.yml | 2 + .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 +++ .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1746 bytes .../streamService-0.0.1-SNAPSHOT.pom | 9 ++ .../streamService/maven-metadata-local.xml | 12 +++ .../stubrunner/junit/AccurestRule.java | 5 + .../stub-runner-messaging-camel/build.gradle | 2 +- .../build.gradle | 4 +- .../stub-runner-messaging-stream/build.gradle | 2 +- .../stub-runner-spring-cloud/build.gradle | 2 +- stub-runner/stub-runner-spring/build.gradle | 4 +- .../stubrunner/BatchStubRunner.groovy | 16 ++- .../accurest/stubrunner/RunningStubs.groovy | 5 +- .../stubrunner/StubConfiguration.groovy | 7 +- .../accurest/stubrunner/StubRunner.groovy | 5 + .../stubrunner/StubRunnerExecutor.groovy | 9 +- .../accurest/stubrunner/StubTrigger.groovy | 7 ++ .../stubrunner/BatchStubRunnerSpec.groovy | 3 +- 34 files changed, 391 insertions(+), 31 deletions(-) create mode 100644 stub-runner/stub-runner-boot/README.adoc create mode 100644 stub-runner/stub-runner-boot/build.gradle create mode 100644 stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/HttpStubsController.groovy create mode 100644 stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBoot.groovy create mode 100644 stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/TriggerController.groovy create mode 100644 stub-runner/stub-runner-boot/src/main/resources/META-INF/spring.factories create mode 100644 stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy create mode 100644 stub-runner/stub-runner-boot/src/test/resources/application.yml create mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar create mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom create mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties index c484dce638..03c9b16bb8 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties @@ -1,4 +1,6 @@ groupId=com.ofg jacksonMapper=1.9.13 restAssuredVersion=2.4.0 -springVersion=4.1.7.RELEASE \ No newline at end of file +springVersion=4.1.7.RELEASE + +springBootVersion=1.3.3.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle index a4a2ae6524..5fffa182b2 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle @@ -46,14 +46,14 @@ repositories { 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' + compile "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" + compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" + compile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" compile fileTree(dir: messagingLibsDir, include: '*.jar') testCompile "org.spockframework:spock-spring:1.0-groovy-2.4" - testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile "ch.qos.logback:logback-classic:1.1.2" } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties index 47ede0913e..6910517f7c 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties @@ -1,4 +1,6 @@ groupId=io.codearte jacksonMapper=1.9.13 restAssuredVersion=2.9.0 -springVersion=4.2.3.RELEASE \ No newline at end of file +springVersion=4.2.3.RELEASE + +springBootVersion=1.3.3.RELEASE \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index 14988fcafe..7181615caf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,4 +4,5 @@ nexusPassword = wiremockVersion = 2.0.10-beta jsonassertVersion = 0.2.2 -BOM_VERSION=Brixton-1.0.0.RC1 \ No newline at end of file +BOM_VERSION=Brixton-1.0.0.RC1 +springBootVersion=1.3.3.RELEASE \ No newline at end of file diff --git a/samples/messaging-camel/build.gradle b/samples/messaging-camel/build.gradle index bc1c2750b3..3484906ce6 100644 --- a/samples/messaging-camel/build.gradle +++ b/samples/messaging-camel/build.gradle @@ -11,7 +11,7 @@ repositories { dependencies { compile project(':accurest-core') - compile 'org.springframework.boot:spring-boot-starter-actuator:1.3.3.RELEASE' + compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" 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' @@ -19,7 +19,7 @@ dependencies { 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.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/samples/messaging-integration/build.gradle b/samples/messaging-integration/build.gradle index d583c1e803..94be6d9087 100644 --- a/samples/messaging-integration/build.gradle +++ b/samples/messaging-integration/build.gradle @@ -11,11 +11,11 @@ repositories { 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.boot:spring-boot-starter-actuator:${springBootVersion}" + compile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" testCompile project(':accurest-messaging-root:accurest-messaging-integration') - testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/samples/messaging-spring/build.gradle b/samples/messaging-spring/build.gradle index a422f0a484..e1bb4de06e 100644 --- a/samples/messaging-spring/build.gradle +++ b/samples/messaging-spring/build.gradle @@ -11,14 +11,14 @@ repositories { dependencies { compile project(':accurest-core') - compile 'org.springframework.boot:spring-boot-starter-actuator:1.3.3.RELEASE' + compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" 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.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/samples/messaging-stream/build.gradle b/samples/messaging-stream/build.gradle index 69a151237c..5f94330b61 100644 --- a/samples/messaging-stream/build.gradle +++ b/samples/messaging-stream/build.gradle @@ -11,7 +11,7 @@ repositories { dependencies { compile project(':accurest-core') - compile 'org.springframework.boot:spring-boot-starter-actuator:1.3.3.RELEASE' + compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" compile 'org.springframework.cloud:spring-cloud-stream-binder-rabbit:1.0.0.RC2' testCompile project(':accurest-messaging-root:accurest-messaging-stream') diff --git a/settings.gradle b/settings.gradle index da50942a1e..7c598a3401 100644 --- a/settings.gradle +++ b/settings.gradle @@ -8,6 +8,7 @@ include ':accurest-messaging:accurest-messaging-camel' include ':stub-runner:stub-runner' include ':stub-runner:stub-runner-spring' +include ':stub-runner:stub-runner-boot' include ':stub-runner:stub-runner-spring-cloud' include ':stub-runner:stub-runner-junit' diff --git a/stub-runner/stub-runner-boot/README.adoc b/stub-runner/stub-runner-boot/README.adoc new file mode 100644 index 0000000000..352e073f07 --- /dev/null +++ b/stub-runner/stub-runner-boot/README.adoc @@ -0,0 +1,51 @@ +=== Stub Runner Boot + +Accurest Stub Runner Boot is a Spring Boot application that exposes REST endpoints to +trigger the messaging labels and to access started WireMock servers. + +==== How to use it? + +Just add the + +[source,groovy,indent=0] +---- +compile "io.codearte.accurest:stub-runner-boot:${accurestVersion}" +---- + +and a messaging implementation: + +[source,groovy,indent=0] +---- +// for Apache Camel +compile "io.codearte.accurest:accurest-messaging-camel:${accurestVersion}" +// for Spring Integration +compile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}" +// for Spring Cloud Stream +compile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}" +---- + +Build a fat-jar and you're ready to go! + +For the properties check the *Stub Runner Spring* section. + +==== Endpoints + +===== HTTP + +- GET `/stubs` - returns a list of all running stubs in `ivy:integer` notation +- GET `/stubs/{ivy}` - returns a port for the given `ivy` notation (when calling the endpoint `ivy` can also be `artifactId` only) + +===== Messaging + +For Messaging + +- GET `/triggers` - returns a list of all running labels in `ivy : [ label1, label2 ...]` notation +- POST `/triggers/{label}` - executes a trigger with `label` +- POST `/triggers/{ivy}/{label}` - executes a trigger with `label` for the given `ivy` notation (when calling the endpoint `ivy` can also be `artifactId` only) + +==== Example + +[source,groovy,indent=0] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy[tags=boot_usage] +---- \ No newline at end of file diff --git a/stub-runner/stub-runner-boot/build.gradle b/stub-runner/stub-runner-boot/build.gradle new file mode 100644 index 0000000000..a10236151b --- /dev/null +++ b/stub-runner/stub-runner-boot/build.gradle @@ -0,0 +1,22 @@ +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +dependencies { + compile project(':stub-runner-root:stub-runner-spring') + compile "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" + + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile project(':stub-runner-root:stub-runner-messaging-root:stub-runner-messaging-stream') + testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/HttpStubsController.groovy b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/HttpStubsController.groovy new file mode 100644 index 0000000000..9a4806edc9 --- /dev/null +++ b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/HttpStubsController.groovy @@ -0,0 +1,38 @@ +package io.codearte.accurest.stubrunner.boot + +import io.codearte.accurest.stubrunner.StubRunning +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +/** + * @author Marcin Grzejszczak + */ +@RestController +@RequestMapping("/stubs") +class HttpStubsController { + + private final StubRunning stubRunning + + @Autowired + HttpStubsController(StubRunning stubRunning) { + this.stubRunning = stubRunning + } + + @RequestMapping + Map stubs() { + return stubRunning.runStubs().toIvyToPortMapping() + } + + @RequestMapping(path = "/{ivy:.*}") + ResponseEntity stub(@PathVariable String ivy) { + Integer port = stubRunning.runStubs().getPort(ivy) + if (port) { + return ResponseEntity.ok(port) + } + return new ResponseEntity(HttpStatus.NOT_FOUND) + } +} diff --git a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBoot.groovy b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBoot.groovy new file mode 100644 index 0000000000..d3ec34a69e --- /dev/null +++ b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBoot.groovy @@ -0,0 +1,15 @@ +package io.codearte.accurest.stubrunner.boot + +import org.springframework.boot.SpringApplication +import org.springframework.boot.autoconfigure.SpringBootApplication + +/** + * @author Marcin Grzejszczak + */ +@SpringBootApplication +class StubRunnerBoot { + + static void main(String[] args) { + SpringApplication.run(StubRunnerBoot.class, args); + } +} diff --git a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/TriggerController.groovy b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/TriggerController.groovy new file mode 100644 index 0000000000..7bb1a002f7 --- /dev/null +++ b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/TriggerController.groovy @@ -0,0 +1,59 @@ +package io.codearte.accurest.stubrunner.boot + +import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.StubFinder +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.HttpStatus +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +import static org.springframework.web.bind.annotation.RequestMethod.GET +import static org.springframework.web.bind.annotation.RequestMethod.POST + +/** + * @author Marcin Grzejszczak + */ +@RestController +@RequestMapping("/triggers") +@Slf4j +class TriggerController { + + private final StubFinder stubFinder + + @Autowired + TriggerController(StubFinder stubFinder) { + this.stubFinder = stubFinder + } + + @RequestMapping(method = POST, path = "/{label:.*}") + ResponseEntity>> trigger(@PathVariable String label) { + return respond(label) { + stubFinder.trigger(label) + } + } + + @RequestMapping(method = POST, path = "/{ivyNotation:.*}/{label:.*}") + ResponseEntity>> triggerByArtifact(@PathVariable String ivyNotation, @PathVariable String label) { + return respond(label) { + stubFinder.trigger(ivyNotation, label) + } + } + + @RequestMapping(method = GET) + Map> labels() { + return stubFinder.labels() + } + + private ResponseEntity>> respond(String label, Closure closure) { + try { + closure() + return ResponseEntity.ok().body() + } catch (Exception e) { + log.debug("Exception occurred while trying to return [$label] label", e) + return new ResponseEntity>>(stubFinder.labels(), HttpStatus.NOT_FOUND) + } + } + +} diff --git a/stub-runner/stub-runner-boot/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-boot/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..1f6ec12f3e --- /dev/null +++ b/stub-runner/stub-runner-boot/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration diff --git a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy b/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy new file mode 100644 index 0000000000..2c7f041e89 --- /dev/null +++ b/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy @@ -0,0 +1,92 @@ +package io.codearte.accurest.stubrunner.boot + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import groovy.json.JsonSlurper +import io.codearte.accurest.stubrunner.StubRunning +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 + */ +// tag::boot_usage[] +@ContextConfiguration(classes = StubRunnerBoot, loader = SpringApplicationContextLoader) +class StubRunnerBootSpec extends Specification { + + @Autowired StubRunning stubRunning + + def setup() { + RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning), + new TriggerController(stubRunning)) + } + + def 'should return a list of running stub servers in "ivy:port" notation'() { + when: + String response = RestAssuredMockMvc.get('/stubs').body.asString() + then: + def root = new JsonSlurper().parseText(response) + root.'io.codearte.accurest.stubs:streamService:stubs' instanceof Integer + } + + def 'should return a port on which a [#stubId] stub is running'() { + when: + def response = RestAssuredMockMvc.get("/stubs/${stubId}") + then: + response.statusCode == 200 + response.body.as(Integer) > 0 + where: + stubId << ['io.codearte.accurest.stubs:streamService:stubs', 'io.codearte.accurest.stubs:streamService', 'streamService'] + } + + def 'should return 404 when missing stub was called'() { + when: + def response = RestAssuredMockMvc.get("/stubs/a:b:c:d") + then: + response.statusCode == 404 + } + + def 'should return a list of messaging labels that can be triggered'() { + when: + String response = RestAssuredMockMvc.get('/triggers').body.asString() + then: + response == '''{"io.codearte.accurest.stubs:streamService:stubs":["delete_book","return_book_1","return_book_2"]}''' + } + + def 'should trigger a messaging label'() { + given: + StubRunning stubRunning = Mock() + RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning), new TriggerController(stubRunning)) + when: + def response = RestAssuredMockMvc.post("/triggers/delete_book") + then: + response.statusCode == 200 + and: + 1 * stubRunning.trigger('delete_book') + } + + def 'should trigger a messaging label for a stub with [#stubId] ivy notation'() { + given: + StubRunning stubRunning = Mock() + RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning), new TriggerController(stubRunning)) + when: + def response = RestAssuredMockMvc.post("/triggers/$stubId/delete_book") + then: + response.statusCode == 200 + and: + 1 * stubRunning.trigger(stubId, 'delete_book') + where: + stubId << ['io.codearte.accurest.stubs:streamService:stubs', 'io.codearte.accurest.stubs:streamService', 'streamService'] + } + + def 'should return when trigger is missing'() { + when: + def response = RestAssuredMockMvc.post("/triggers/missing_label") + then: + response.statusCode == 404 + response.body.asString() == '''{"io.codearte.accurest.stubs:streamService:stubs":["delete_book","return_book_1","return_book_2"]}''' + } +// end::boot_usage[] + +} diff --git a/stub-runner/stub-runner-boot/src/test/resources/application.yml b/stub-runner/stub-runner-boot/src/test/resources/application.yml new file mode 100644 index 0000000000..154bfe1b6a --- /dev/null +++ b/stub-runner/stub-runner-boot/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo/repository/ +stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService \ No newline at end of file diff --git a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..bad844ba2a --- /dev/null +++ b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + streamService + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..86c61d52ec4b9571f84240dc880daa2e9e5f5b71 GIT binary patch literal 1746 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJwREYr^0ql^9WtID{d1|?MEQiV35J8Cn-Na zJ1DiJv?wn%#ZWK3C_lffGBkvffjM}xRJbn?msW5yFtWU0W?%plroF!0O%4JM=U=an z*mH(UwdCzI5m~3!4|=PuXZ|qUxSLJs-}kb$dB%Ip^P{@5gEY1tjkxx8$;BHHGwt?e zE&5(lc3HvtiT8o3$i(xGi|2lc2y=<8Y-rf}ID6AP7961ES=3gdP0N#N2%2wI|U9La*jX!q(RaC(+5Y9PgfcBZ3DHgq-FmR zWAvPN|JzN?y$AZ5FPj&CoqwGl6n~H~i2{bnd$}npyMf_h#YkM37$JvA3@|)GF~g*_ z*B=xnN6)`r{=tmx>B8jgi|PelEsbtjW3_b0>l5#!Jbv6Q4qw6NXwW{>{Qcf|*F-7kF%T)__5$Z$tq9dMOLv*$5$!1-ViU9XS-^z{K3m zw=Nygy&0l$souP^NlvURE&cwNCDBG4b_?3J&9y1I(6;to<)Y^?$Il*Yc)D6ZOlr$g zlMKTLTNR~J6n`DJXe|-toB6OW+TX9%dDE|-(ng!D+;v^5Y#R=jYUaBLD(Tf9v~6-c zKT~s;&Xkmb#jZQGo*qB>M3v8AG5>MCrb(UEOzVob2ZnO#9{t3I$lzLNB>`GS%S|jO z$jnPG24^%zCJ|=bXL*rE(CSWgY zSRsWCT0w(s8)n8uw(TX*Qf%%;whfVufwqCNF&^76a{{t$Y`~Hbmu=|z0%#W~UtqBd omUghEIB-A$)6QQ + + 4.0.0 + io.codearte.accurest.stubs + streamService + 0.0.1-SNAPSHOT + pom + diff --git a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml new file mode 100644 index 0000000000..dc32790f53 --- /dev/null +++ b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + streamService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index 52178ecc01..7f29aaab71 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -182,4 +182,9 @@ public class AccurestRule implements TestRule, StubFinder { public boolean trigger() { return stubFinder.trigger(); } + + @Override + public Map> labels() { + return stubFinder.labels(); + } } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle index 31a1bf7460..d2c9ee5d07 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle @@ -18,7 +18,7 @@ dependencies { testCompile 'org.apache.camel:camel-jms:2.17.0' testCompile 'org.apache.activemq:activemq-camel:5.12.1' testCompile 'org.apache.activemq:activemq-pool:5.12.1' - testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle index 89699fedfe..fa82813497 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle @@ -14,8 +14,8 @@ dependencies { compile project(':accurest-messaging-root:accurest-messaging-integration') compile 'org.springframework.integration:spring-integration-java-dsl:[1.1.2.RELEASE,)' - testCompile 'org.springframework.boot:spring-boot-starter-integration:1.3.3.RELEASE' - testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle index 20d6bac9f4..661f96ced1 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle @@ -15,7 +15,7 @@ dependencies { compile 'org.springframework.integration:spring-integration-java-dsl:[1.1.2.RELEASE,)' testCompile 'org.springframework.cloud:spring-cloud-stream-test-support:1.0.0.RC2' - testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/stub-runner/stub-runner-spring-cloud/build.gradle b/stub-runner/stub-runner-spring-cloud/build.gradle index 6b394afa9a..08e64bfd9c 100644 --- a/stub-runner/stub-runner-spring-cloud/build.gradle +++ b/stub-runner/stub-runner-spring-cloud/build.gradle @@ -14,7 +14,7 @@ dependencies { testCompile 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery:1.0.0.RC1' testCompile 'org.apache.curator:curator-test:2.9.1' testCompile 'io.reactivex:rxjava:1.1.1' - testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile "org.springframework:spring-web:4.2.5.RELEASE" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') diff --git a/stub-runner/stub-runner-spring/build.gradle b/stub-runner/stub-runner-spring/build.gradle index f05eb40a0d..a020e5d80d 100644 --- a/stub-runner/stub-runner-spring/build.gradle +++ b/stub-runner/stub-runner-spring/build.gradle @@ -11,8 +11,8 @@ dependencies { } testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - testCompile 'org.springframework.boot:spring-boot-starter:1.3.3.RELEASE' - testCompile 'org.springframework.boot:spring-boot-starter-test:1.3.3.RELEASE' + testCompile "org.springframework.boot:spring-boot-starter:${springBootVersion}" + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy index 16ef82b2fe..c2c20567dd 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy @@ -51,7 +51,7 @@ class BatchStubRunner implements StubRunning { @Override Map> getAccurestContracts() { return stubRunners.inject([:]) { Map> map, StubRunner stubRunner -> - map.putAll(stubRunner.accurestContracts) + map.putAll(stubRunner.accurestContracts ?: [:]) return map } as Map> } @@ -74,9 +74,7 @@ class BatchStubRunner implements StubRunning { } private String ivyToLabels() { - return (getAccurestContracts().collectEntries { - [(it.key.toColonSeparatedDependencyNotation()) : it.value.collect { it.label }] - } as Map>).entrySet().collect { + return labels().entrySet().collect { "Dependency [${it.key}] has labels ${it.value}]" }.join('\n') } @@ -108,6 +106,16 @@ class BatchStubRunner implements StubRunning { } } + @Override + Map> labels() { + return stubRunners.inject([:]) { Map> map, StubRunner stubRunner -> + if (stubRunner) { + map.putAll(stubRunner.labels() ?: [:]) + } + return map + } as Map> + } + @Override void close() throws IOException { stubRunners.each { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy index 6c1d683fba..1483b81926 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy @@ -2,7 +2,6 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode - /** * Structure representing executed stubs. Contains the configuration of each stub * together with the port on which its executed. @@ -68,6 +67,10 @@ class RunningStubs { return namesAndPorts.keySet().collect { it.artifactId } as Set } + Map toIvyToPortMapping() { + return namesAndPorts.collectEntries { [(it.key.toColonSeparatedDependencyNotation()) : it.value] } as Map + } + @Override String toString() { return namesAndPorts.collect { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy index a4eea495dd..fa22eae5a7 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy @@ -4,7 +4,6 @@ import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import io.codearte.accurest.stubrunner.util.StringUtils - /** * Represents a configuration of a single stub. The stub can be described * by groupId:artifactId:classifier notation @@ -76,4 +75,10 @@ public class StubConfiguration { } return [splitString[0], splitString[1]] as String[] } + + + @Override + public String toString() { + return toColonSeparatedDependencyNotation() + } } \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy index 91a5174775..6f7a458c5d 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -89,6 +89,11 @@ class StubRunner implements StubRunning { return localStubRunner.trigger() } + @Override + Map> labels() { + return localStubRunner.labels() + } + private void registerShutdownHook() { Runnable stopAllServers = { this.close() } Runtime.runtime.addShutdownHook(new Thread(stopAllServers)) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index 20649d03ae..c7c0fe1dd7 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -82,7 +82,7 @@ class StubRunnerExecutor implements StubFinder { } private boolean triggerForDsls(Collection dsls, String labelName) { - Collection matchingDsls = dsls.findAll { it.label == labelName} + Collection matchingDsls = dsls.findAll { it.label == labelName } if (matchingDsls.empty) { return false } @@ -100,6 +100,13 @@ class StubRunnerExecutor implements StubFinder { return true } + @Override + Map> labels() { + return getAccurestContracts().collectEntries { + [(it.key.toColonSeparatedDependencyNotation()) : it.value.collect { it.label }] + } as Map> + } + private void sendMessageIfApplicable(GroovyDsl groovyDsl) { if (!groovyDsl.outputMessage) { return diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy index cee1acebec..bd5ec1e30e 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy @@ -28,4 +28,11 @@ interface StubTrigger { * @return true - if managed to run a trigger */ boolean trigger() + + /** + * Returns a mapping of ivy notation of a dependency to all the labels it has. + * + * Feature related to messaging. + */ + Map> labels() } \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy index 19fbb1227e..0013801aa8 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy @@ -1,6 +1,5 @@ package io.codearte.accurest.stubrunner -import io.codearte.accurest.dsl.GroovyDsl import spock.lang.Specification class BatchStubRunnerSpec extends Specification { @@ -37,7 +36,7 @@ class BatchStubRunnerSpec extends Specification { StubRunner runner = Mock(StubRunner) runner.findStubUrl("group", "knownArtifact") >> KNOWN_STUB_URL runner.findStubUrl("group", "unknownArtifact") >> null - runner.accurestContracts >> [(new StubConfiguration('a', 'b', 'c')): [GroovyDsl.make { outputMessage { label 'foo' } }]] + runner.labels() >> ['a:b:c' : ['foo']] return [runner] } From 6d4885fd66a675446929c10abbfe95bd206b3808 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Apr 2016 16:40:46 +0200 Subject: [PATCH 580/719] Updated docs --- docs/src/docs/asciidoc/stubrunner.adoc | 1 + stub-runner/stub-runner-boot/README.adoc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index e62bb68312..81d5f211a8 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -36,6 +36,7 @@ Accurest comes with a new structure of modules ---- include::../../../../stub-runner/stub-runner/README.adoc[] +include::../../../../stub-runner/stub-runner-boot/README.adoc[] include::../../../../stub-runner/stub-runner-junit/README.adoc[] include::../../../../stub-runner/stub-runner-spring/README.adoc[] include::../../../../stub-runner/stub-runner-spring-cloud/README.adoc[] diff --git a/stub-runner/stub-runner-boot/README.adoc b/stub-runner/stub-runner-boot/README.adoc index 352e073f07..db79ca1d9f 100644 --- a/stub-runner/stub-runner-boot/README.adoc +++ b/stub-runner/stub-runner-boot/README.adoc @@ -1,5 +1,7 @@ === Stub Runner Boot +WARNING: Feature available since {messaging_version} + Accurest Stub Runner Boot is a Spring Boot application that exposes REST endpoints to trigger the messaging labels and to access started WireMock servers. From 5f2c37868dd5cff2fdcc0e87650f4da625e333ba Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Apr 2016 16:44:53 +0200 Subject: [PATCH 581/719] Updated docs --- docs/src/docs/asciidoc/stubrunner.adoc | 3 ++- stub-runner/stub-runner/README.adoc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index 81d5f211a8..c5a0a1d6be 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -1,4 +1,4 @@ -== Stub Runner for HTTP +== Stub Runner One of the issues that you could have encountered while using Accurest was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). The same takes place in terms of client side generation for messaging. @@ -30,6 +30,7 @@ Accurest comes with a new structure of modules ---- └── stub-runner ├── stub-runner + ├── stub-runner-boot ├── stub-runner-junit ├── stub-runner-spring └── stub-runner-spring-cloud diff --git a/stub-runner/stub-runner/README.adoc b/stub-runner/stub-runner/README.adoc index d6dd566c1f..af37e01bfc 100644 --- a/stub-runner/stub-runner/README.adoc +++ b/stub-runner/stub-runner/README.adoc @@ -1,4 +1,4 @@ -=== Stub Runner core +=== Stub Runner Core Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of http://martinfowler.com/articles/consumerDrivenContracts.html[Consumer Driven Contracts]. From da1723ba4e29ff1e670b72deb14af82a472db17d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Apr 2016 22:44:58 +0200 Subject: [PATCH 582/719] Added possibility to pass a fixed port to a dependency (#250) fixes #213 --- stub-runner/stub-runner-junit/README.adoc | 35 ++++++++++ .../stubrunner/junit/AccurestRule.java | 66 ++++++++++++------ .../AccurestRuleCustomPortJUnitTest.java | 68 +++++++++++++++++++ .../spring/StubRunnerConfiguration.java | 2 +- .../stubrunner/BatchStubRunnerFactory.groovy | 2 +- .../accurest/stubrunner/StubRunner.groovy | 2 +- .../stubrunner/StubRunnerExecutor.groovy | 15 ++-- .../stubrunner/StubRunnerOptions.groovy | 38 +++++++++++ .../stubrunner/util/StubsParser.groovy | 37 ++++++++-- .../stubrunner/StubRunnerExecutorSpec.groovy | 15 +++- 10 files changed, 246 insertions(+), 34 deletions(-) create mode 100644 stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java diff --git a/stub-runner/stub-runner-junit/README.adoc b/stub-runner/stub-runner-junit/README.adoc index 5a778ae104..8a512100ac 100644 --- a/stub-runner/stub-runner-junit/README.adoc +++ b/stub-runner/stub-runner-junit/README.adoc @@ -41,3 +41,38 @@ include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnit Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. +==== Providing fixed ports + +You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API. + +===== System properties + +You can provide the stubs to download via the `stubrunner.stubs.ids` system property. They follow the following pattern: + +[source,java,indent=0] +---- +groupId:artifactId:classifier:port +---- + +`classifier` and `port` are optional. + +* If you don't provide the `classifier` then the default one will be taken. +* If you don't provide the `port` then a random one will be picked + +==== Fluent API + +When using the `AccurestRule` you can add a stub to download and then pass the port for the last downloaded stub. + +[source,java,indent=0] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java[tags=classrule_with_port] +---- + +You can see that for this example the following test is valid: + +[source,java,indent=0] +---- +include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java[tags=test_with_port] +---- + + diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index 7f29aaab71..ab31e7ff74 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -1,5 +1,17 @@ package io.codearte.accurest.stubrunner.junit; +import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + import io.codearte.accurest.dsl.GroovyDsl; import io.codearte.accurest.stubrunner.BatchStubRunner; import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; @@ -9,18 +21,6 @@ import io.codearte.accurest.stubrunner.StubFinder; import io.codearte.accurest.stubrunner.StubRunnerOptions; import io.codearte.accurest.stubrunner.util.StringUtils; import io.codearte.accurest.stubrunner.util.StubsParser; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import java.net.URL; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; /** * JUnit class rule that allows you to download the provided stubs. @@ -30,7 +30,7 @@ import java.util.Set; public class AccurestRule implements TestRule, StubFinder { private static final String DELIMITER = ":"; - private Set stubs = new HashSet(); + private LinkedList stubs = new LinkedList<>(); private StubRunnerOptions stubRunnerOptions = defaultStubRunnerOptions(); private BatchStubRunner stubFinder; @@ -63,7 +63,7 @@ public class AccurestRule implements TestRule, StubFinder { if (StringUtils.hasText(stubsToDownload)) { Collections.addAll(stubs, stubsToDownload.split(",")); } - return new StubRunnerOptions(minPort, maxPort, repoRoot, workOffline, stubSuffix); + return new StubRunnerOptions(minPort, maxPort, repoRoot, workOffline, stubSuffix, stubsToDownload); } /** @@ -112,7 +112,7 @@ public class AccurestRule implements TestRule, StubFinder { * Group Id, artifact Id and classifier of a single stub to download */ public AccurestRule downloadStub(String groupId, String artifactId, String classifier) { - stubs.add(groupId + DELIMITER + artifactId + DELIMITER + classifier); + addStub(groupId + DELIMITER + artifactId + DELIMITER + classifier); return this; } @@ -120,7 +120,7 @@ public class AccurestRule implements TestRule, StubFinder { * Group Id, artifact Id of a single stub to download. Default classifier will be picked. */ public AccurestRule downloadStub(String groupId, String artifactId) { - stubs.add(groupId + DELIMITER + artifactId); + addStub(groupId + DELIMITER + artifactId); return this; } @@ -128,7 +128,7 @@ public class AccurestRule implements TestRule, StubFinder { * Ivy notation of a single stub to download. */ public AccurestRule downloadStub(String ivyNotation) { - stubs.add(ivyNotation); + addStub(ivyNotation); return this; } @@ -136,7 +136,7 @@ public class AccurestRule implements TestRule, StubFinder { * Stubs to download in Ivy notations */ public AccurestRule downloadStubs(String... ivyNotations) { - stubs.addAll(Arrays.asList(ivyNotations)); + addStub(Arrays.asList(ivyNotations)); return this; } @@ -144,7 +144,16 @@ public class AccurestRule implements TestRule, StubFinder { * Stubs to download in Ivy notations */ public AccurestRule downloadStubs(List ivyNotations) { - stubs.addAll(ivyNotations); + addStub(ivyNotations); + return this; + } + + /** + * Appends port to last added stub + */ + public AccurestRule withPort(Integer port) { + String lastStub = stubs.peekLast(); + addPort(lastStub + DELIMITER + port); return this; } @@ -187,4 +196,23 @@ public class AccurestRule implements TestRule, StubFinder { public Map> labels() { return stubFinder.labels(); } + + private void addStub(String notation) { + if(StubsParser.hasPort(notation)) { + addPort(notation); + stubs.add(StubsParser.ivyFromStringWithPort(notation)); + } else { + stubs.add(notation); + } + } + + private void addStub(List notations) { + for (String notation : notations) { + addStub(notation); + } + } + + private void addPort(String notation) { + stubRunnerOptions.putStubIdsToPortMapping(StubsParser.fromStringWithPort(notation)); + } } diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java new file mode 100644 index 0000000000..ef05510e74 --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java @@ -0,0 +1,68 @@ +package io.codearte.accurest.stubrunner.junit; + +import java.io.InputStream; +import java.net.URI; + +import org.apache.commons.io.IOUtils; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public class AccurestRuleCustomPortJUnitTest { + + @BeforeClass + @AfterClass + public static void setupProps() { + System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); + System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); + } + + // tag::classrule_with_port[] + @ClassRule public static AccurestRule rule = new AccurestRule() + .repoRoot(repoRoot()) + .downloadStub("io.codearte.accurest.stubs", "loanIssuance") + .withPort(12345) + .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:12346"); + // end::classrule_with_port[] + + @Test + public void should_start_wiremock_servers() throws Exception { + // expect: 'WireMocks are running' + then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")); + then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull(); + // and: + then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); + then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue(); + then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue(); + // and: 'Stubs were registered' + then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); + then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); + // and: 'The port is fixed' + // tag::test_with_port[] + then(rule.findStubUrl("loanIssuance")).isEqualTo(URI.create("http://localhost:12345").toURL()); + then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL()); + // end::test_with_port[] + } + + private static String repoRoot() { + try { + return AccurestRuleCustomPortJUnitTest.class.getResource("/m2repo/repository/").toURI().toString(); + } catch (Exception e) { + return ""; + } + } + + private String httpGet(String url) throws Exception { + try(InputStream stream = URI.create(url).toURL().openStream()) { + return IOUtils.toString(stream); + } + } +} diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java index a375442b2c..44f959d210 100644 --- a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java +++ b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java @@ -48,7 +48,7 @@ public class StubRunnerConfiguration { @Value("${stubrunner.work-offline:false}") boolean workOffline, @Value("${stubrunner.stubs.ids:}") String stubs) throws IOException { StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue, maxPortValue, uriStringOrEmpty(stubRepositoryRoot), - stubRepositoryRoot == null || workOffline, stubsSuffix); + stubRepositoryRoot == null || workOffline, stubsSuffix, stubs); Set dependencies = StubsParser.fromString(stubs, stubsSuffix); BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, dependencies, accurestMessaging != null ? accurestMessaging : new NoOpAccurestMessaging()).buildBatchStubRunner(); diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy index a7e3412fa9..9b1a03929d 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy @@ -30,7 +30,7 @@ class BatchStubRunnerFactory { BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies, StubDownloader stubDownloader) { - this(stubRunnerOptions, dependencies, new GrapeStubDownloader(), new NoOpAccurestMessaging()) + this(stubRunnerOptions, dependencies, stubDownloader, new NoOpAccurestMessaging()) } BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy index 6f7a458c5d..c525646c5e 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy @@ -46,7 +46,7 @@ class StubRunner implements StubRunning { @Override RunningStubs runStubs() { registerShutdownHook() - return localStubRunner.runStubs(stubRepository, stubsConfiguration) + return localStubRunner.runStubs(stubRunnerOptions,stubRepository, stubsConfiguration) } @Override diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index c7c0fe1dd7..0f30354e36 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -28,8 +28,8 @@ class StubRunnerExecutor implements StubFinder { this.accurestMessaging = new NoOpAccurestMessaging() } - RunningStubs runStubs(StubRepository repository, StubConfiguration stubConfiguration) { - startStubServers(stubConfiguration, repository) + RunningStubs runStubs(StubRunnerOptions stubRunnerOptions, StubRepository repository, StubConfiguration stubConfiguration) { + startStubServers(stubRunnerOptions, stubConfiguration, repository) RunningStubs runningCollaborators = new RunningStubs([(stubServer.stubConfiguration): stubServer.port]) log.info("All stubs are now running [${runningCollaborators.toString()}") @@ -120,11 +120,16 @@ class StubRunnerExecutor implements StubFinder { return condition ? stubServer.stubUrl : null } - private void startStubServers(StubConfiguration stubConfiguration, StubRepository repository) { + private void startStubServers(StubRunnerOptions stubRunnerOptions, StubConfiguration stubConfiguration, StubRepository repository) { List mappings = repository.getProjectDescriptors() Collection contracts = repository.accurestContracts - stubServer = portScanner.tryToExecuteWithFreePort { int availablePort -> - return new StubServer(availablePort, stubConfiguration, mappings, contracts).start() + Integer port = stubRunnerOptions.port(stubConfiguration) + if (port) { + stubServer = new StubServer(port, stubConfiguration, mappings, contracts).start() + } else { + stubServer = portScanner.tryToExecuteWithFreePort { int availablePort -> + return new StubServer(availablePort, stubConfiguration, mappings, contracts).start() + } } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy index 8e6b3d7cd0..9343f59e81 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.transform.ToString +import io.codearte.accurest.stubrunner.util.StubsParser /** * Technical options related to running StubRunner @@ -30,11 +31,26 @@ class StubRunnerOptions { */ boolean workOffline = false + /** + * colon separated list of ids to the desired port + */ + Map stubIdsToPortMapping = [:] + /** * stub definition suffix */ String stubsClassifier = "stubs" + StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, + boolean workOffline, String stubsClassifier, String stubIdsToPortMapping) { + this.minPortValue = minPortValue + this.maxPortValue = maxPortValue + this.stubRepositoryRoot = stubRepositoryRoot + this.workOffline = workOffline + this.stubsClassifier = stubsClassifier + this.stubIdsToPortMapping = stubIdsWithPortsFromString(stubIdsToPortMapping) + } + StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, boolean workOffline, String stubsClassifier) { this.minPortValue = minPortValue @@ -49,4 +65,26 @@ class StubRunnerOptions { } StubRunnerOptions() {} + + Map stubIdsWithPortsFromString(String stubIdsToPortMapping) { + return stubIdsToPortMapping.split(',').collectEntries { String entry -> + return StubsParser.fromStringWithPort(entry) + } + } + + Integer port(StubConfiguration stubConfiguration) { + return stubIdsToPortMapping[stubConfiguration] + } + + void setStubIdsToPortMapping(Map stubIdsToPortMapping) { + this.stubIdsToPortMapping = stubIdsToPortMapping + } + + void putStubIdsToPortMapping(Map stubIdsToPortMapping) { + this.stubIdsToPortMapping.putAll(stubIdsToPortMapping) + } + + void setStubIdsToPortMapping(String stubIdsToPortMapping) { + this.stubIdsToPortMapping = stubIdsWithPortsFromString(stubIdsToPortMapping) + } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy index 9749dec904..ae06a9bfe2 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy @@ -25,14 +25,41 @@ class StubsParser { * "a:b,c:d:e" */ static Set fromString(String list, String defaultClassifier) { - return list.split(',').findAll { it }.collect { String string -> - new StubConfiguration(string, defaultClassifier) - } as Set + def splitList = list.split(',').findAll { it } + return fromString(splitList, defaultClassifier) } static Set fromString(Collection collection, String defaultClassifier) { - return collection.findAll { it }.collect { String string -> - new StubConfiguration(string, defaultClassifier) + return collection.findAll { it }.collect { String entry -> + def splitEntry = entry.split(':') + if (splitEntry.last().isInteger()) { + String id = entry - ":${splitEntry.last()}" + new StubConfiguration(id, defaultClassifier) + } + new StubConfiguration(entry, defaultClassifier) } as Set } + + static Map fromStringWithPort(String notation) { + def splitEntry = notation.split(':') + if (!splitEntry.last().isInteger()) { + return [:] + } + Integer port = splitEntry.last().toInteger() + String id = notation - ":${splitEntry.last()}" + return [(new StubConfiguration(id)): port] + } + + static String ivyFromStringWithPort(String notation) { + def splitEntry = notation.split(':') + if (!splitEntry.last().isInteger()) { + return '' + } + return notation - ":${splitEntry.last()}" + } + + static boolean hasPort(String notation) { + def splitEntry = notation.split(':') + return splitEntry.last().isInteger() + } } \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy index 8548ea38c4..fc30f2978e 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy @@ -11,6 +11,7 @@ class StubRunnerExecutorSpec extends Specification { private AvailablePortScanner portScanner private StubRepository repository private StubConfiguration stub = new StubConfiguration("group:artifact", "stubs") + private StubRunnerOptions stubRunnerOptions = new StubRunnerOptions() def setup() { portScanner = new AvailablePortScanner(MIN_PORT, MAX_PORT) @@ -21,7 +22,7 @@ class StubRunnerExecutorSpec extends Specification { given: StubRunnerExecutor executor = new StubRunnerExecutor(portScanner) when: - executor.runStubs(repository, stub) + executor.runStubs(stubRunnerOptions, repository, stub) then: executor.findStubUrl("group", "artifact") == EXPECTED_STUB_URL and: @@ -36,9 +37,19 @@ class StubRunnerExecutorSpec extends Specification { given: StubRunnerExecutor executor = new StubRunnerExecutor(portScanner) when: - executor.runStubs(repository, stub) + executor.runStubs(stubRunnerOptions, repository, stub) then: !executor.findStubUrl("unkowngroup", "unknownartifact") } + def 'should start a stub on a given port'() { + given: + StubRunnerExecutor executor = new StubRunnerExecutor(portScanner) + stubRunnerOptions.setStubIdsToPortMapping('group:artifact:12345,someotherartifact:123') + when: + executor.runStubs(stubRunnerOptions, repository, stub) + then: + executor.findStubUrl("group", "artifact") == 'http://localhost:12345'.toURL() + } + } From 6871dec2fa09e9163e5b07f512e6bde23b77be8c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Apr 2016 22:51:29 +0200 Subject: [PATCH 583/719] Updated docs --- docs/src/docs/asciidoc/stubrunner.adoc | 16 +++++++++++++++- stub-runner/stub-runner-junit/README.adoc | 17 ++--------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index c5a0a1d6be..a053d396a4 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -56,4 +56,18 @@ Some of the properties that are repetitive can be set using system properties or |stubrunner.stubs.classifier|stubs| Default classifier for the stub artifacts| |stubrunner.work-offline|false| If true then will not contact any remote repositories to download stubs| |stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| -|====================== \ No newline at end of file +|====================== + +===== Stub runner stubs ids + +You can provide the stubs to download via the `stubrunner.stubs.ids` system property. They follow the following pattern: + +[source,java,indent=0] +---- +groupId:artifactId:classifier:port +---- + +`classifier` and `port` are optional. + +* If you don't provide the `classifier` then the default one will be taken. +* If you don't provide the `port` then a random one will be picked \ No newline at end of file diff --git a/stub-runner/stub-runner-junit/README.adoc b/stub-runner/stub-runner-junit/README.adoc index 8a512100ac..a4e3d5636d 100644 --- a/stub-runner/stub-runner-junit/README.adoc +++ b/stub-runner/stub-runner-junit/README.adoc @@ -43,21 +43,8 @@ Check the *Common properties for JUnit and Spring* for more information on how t ==== Providing fixed ports -You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API. - -===== System properties - -You can provide the stubs to download via the `stubrunner.stubs.ids` system property. They follow the following pattern: - -[source,java,indent=0] ----- -groupId:artifactId:classifier:port ----- - -`classifier` and `port` are optional. - -* If you don't provide the `classifier` then the default one will be taken. -* If you don't provide the `port` then a random one will be picked +You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of +JUnit rule. ==== Fluent API From 8a3b1fbcc4589a994e33fa697420d4ca1088ac84 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Apr 2016 22:55:47 +0200 Subject: [PATCH 584/719] Updated docs --- docs/src/docs/asciidoc/stubrunner.adoc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index a053d396a4..6c21f1a464 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -70,4 +70,6 @@ groupId:artifactId:classifier:port `classifier` and `port` are optional. * If you don't provide the `classifier` then the default one will be taken. -* If you don't provide the `port` then a random one will be picked \ No newline at end of file +* If you don't provide the `port` then a random one will be picked + +Where `port` means the port of the WireMock server. \ No newline at end of file From 632753efb21e1dbd8f4f83bb80d0bb80a5f45eae Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 27 Apr 2016 22:56:36 +0200 Subject: [PATCH 585/719] Updated docs --- docs/src/docs/asciidoc/stubrunner.adoc | 2 +- stub-runner/stub-runner-junit/README.adoc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index 6c21f1a464..d36d427e5a 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -58,7 +58,7 @@ Some of the properties that are repetitive can be set using system properties or |stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| |====================== -===== Stub runner stubs ids +==== Stub runner stubs ids You can provide the stubs to download via the `stubrunner.stubs.ids` system property. They follow the following pattern: diff --git a/stub-runner/stub-runner-junit/README.adoc b/stub-runner/stub-runner-junit/README.adoc index a4e3d5636d..4b96939426 100644 --- a/stub-runner/stub-runner-junit/README.adoc +++ b/stub-runner/stub-runner-junit/README.adoc @@ -12,7 +12,7 @@ After that rule gets executed Stub Runner connects to your Maven repository and - download them - cache them locally - unzip them to a temporary folder -- start a WireMock server for each Maven dependency on a random port from the provided range of ports +- start a WireMock server for each Maven dependency on a random port from the provided range of ports / provided port - feed the WireMock server with all JSON files that are valid WireMock definitions Stub Runner uses http://docs.groovy-lang.org/latest/html/documentation/grape.html[Groovy's Grape] mechanism to download the Maven dependencies. From e87456382fa9d15126fb8459b1b57cdbbb5f7732 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 09:01:03 +0200 Subject: [PATCH 586/719] Fixed Stream config --- .../stub-runner-messaging-stream/build.gradle | 1 + .../StubRunnerStreamConfiguration.groovy | 67 ------------------- .../StubRunnerStreamMessageSelector.groovy | 1 + .../main/resources/META-INF/spring.factories | 3 - .../stream/StreamStubRunnerSpec.groovy | 4 ++ 5 files changed, 6 insertions(+), 70 deletions(-) delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle index 661f96ced1..273a830498 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle @@ -11,6 +11,7 @@ repositories { dependencies { compile project(':stub-runner-root:stub-runner-spring') + compile project(':stub-runner-root:stub-runner-messaging-root:stub-runner-messaging-integration') compile project(':accurest-messaging-root:accurest-messaging-stream') compile 'org.springframework.integration:spring-integration-java-dsl:[1.1.2.RELEASE,)' diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy deleted file mode 100644 index 6c3508f3ea..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy +++ /dev/null @@ -1,67 +0,0 @@ -package io.codearte.accurest.stubrunner.messaging.stream - -import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.stubrunner.BatchStubRunner -import io.codearte.accurest.stubrunner.StubConfiguration -import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration -import org.springframework.beans.factory.config.AutowireCapableBeanFactory -import org.springframework.cloud.stream.annotation.EnableBinding -import org.springframework.cloud.stream.binding.ChannelBindingService -import org.springframework.context.Lifecycle -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.context.annotation.Import -import org.springframework.integration.dsl.FilterEndpointSpec -import org.springframework.integration.dsl.GenericEndpointSpec -import org.springframework.integration.dsl.IntegrationFlowBuilder -import org.springframework.integration.dsl.IntegrationFlows -import org.springframework.messaging.Message -import org.springframework.messaging.MessageChannel - -/** - * Spring Cloud Stream configuration that iterates over the downloaded Groovy DSLs - * and registers a flow for each DSL. - * - * @author Marcin Grzejszczak - */ -@Configuration -@Import(StubRunnerConfiguration) -@EnableBinding -@CompileStatic -class StubRunnerStreamConfiguration { - - @Bean - FlowRegistrar flowRegistrar(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner, ChannelBindingService channelBindingService) { - Map> accurestContracts = batchStubRunner.accurestContracts - accurestContracts.each { StubConfiguration key, Collection value -> - String name = "${key.groupId}_${key.artifactId}" - value.findAll { it?.input?.messageFrom?.clientValue }.each { GroovyDsl dsl -> - String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" - IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom.clientValue) - .filter(new StubRunnerStreamMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) - .transform(new StubRunnerStreamTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) - if (dsl.outputMessage?.sentTo) { - builder = builder.channel(dsl.outputMessage.sentTo.clientValue) - } else { - builder = builder.handle(new DummyMessageHandler(), "handle") - } - beanFactory.initializeBean(builder.get(), flowName) - beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); - beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); - channelBindingService.bindConsumer(beanFactory.getBean(dsl.input.messageFrom.clientValue, MessageChannel.class), dsl.input.messageFrom.clientValue) - if (dsl.outputMessage?.sentTo) { - channelBindingService.bindProducer(beanFactory.getBean(dsl.outputMessage.sentTo.clientValue, MessageChannel.class), dsl.outputMessage.sentTo.clientValue) - } - } - } - return new FlowRegistrar() - } - - @CompileStatic - private static class DummyMessageHandler { - void handle(Message message) {} - } - - static class FlowRegistrar {} -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy index 628f423cf4..d32339b504 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy @@ -13,6 +13,7 @@ import org.springframework.integration.core.MessageSelector import org.springframework.messaging.Message import java.util.regex.Pattern + /** * Passes through a message that matches the one defined in the DSL * diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 7b69d1b85a..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.stubrunner.messaging.stream.StubRunnerStreamConfiguration diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy index 1090f1c5ea..722f41a36b 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy @@ -9,6 +9,9 @@ import io.codearte.accurest.stubrunner.StubFinder import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.stream.annotation.EnableBinding +import org.springframework.cloud.stream.messaging.Sink +import org.springframework.cloud.stream.messaging.Source import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration import org.springframework.test.context.ContextConfiguration @@ -22,6 +25,7 @@ import java.util.concurrent.TimeUnit @ComponentScan @EnableAutoConfiguration @ContextConfiguration(classes = StreamStubRunnerSpec, loader = SpringApplicationContextLoader) +@EnableBinding([Sink, Source]) class StreamStubRunnerSpec extends Specification { @Autowired StubFinder stubFinder From 10284c42209720a20af01d731cd8b763f76e02f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Thu, 28 Apr 2016 10:00:22 +0200 Subject: [PATCH 587/719] Fix for scanning files in strange directories (#245) * Fix for scanning files in strange directories * readded ugly code --- .../accurest/file/ContractFileScanner.groovy | 9 +++++---- .../accurest/file/ContractFileScannerSpec.groovy | 16 ++++++++++++++++ .../strange_[3.3.3]_directory/02_login.groovy | 0 .../bar/03_login.groovy | 0 .../foo/01_login.groovy | 0 5 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 accurest-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy create mode 100644 accurest-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy create mode 100644 accurest-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy index 0e898ba30e..5e125f0f31 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy @@ -24,14 +24,15 @@ class ContractFileScanner { ContractFileScanner(File baseDir, Set excluded, Set ignored) { this.baseDir = baseDir - excludeMatchers = processPatterns(excluded, baseDir) - ignoreMatchers = processPatterns(ignored, baseDir) + excludeMatchers = processPatterns(excluded) + ignoreMatchers = processPatterns(ignored) } - private Set processPatterns(Set patterns, baseDir) { + private Set processPatterns(Set patterns) { FileSystem fileSystem = FileSystems.getDefault() return patterns.collect({ - String syntaxAndPattern = MATCH_PREFIX + baseDir.toString() + File.separator + it + String syntaxAndPattern = MATCH_PREFIX + '**' + File.separator + it + // FIXME: This looks strange, need to be checked on windows if (SystemUtils.IS_OS_WINDOWS) { syntaxAndPattern = syntaxAndPattern.replace("\\", "\\\\") } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy index 30a5def61c..c699a2a3a1 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy @@ -28,6 +28,22 @@ class ContractFileScannerSpec extends Specification { ignoredSet.ignored == [true] } + def "should find contract files in strange directories"() { + given: + File baseDir = new File(this.getClass().getResource("/strange_[3.3.3]_directory").toURI()) + Set excluded = ["foo/**"] as Set + Set ignored = ["bar/**"] as Set + ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored) + when: + ListMultimap result = scanner.findContracts() + then: + result.entries().size() == 2 + and: + Collection ignoredSet = result.get(baseDir.toPath().resolve("bar")) + ignoredSet.size() == 1 + ignoredSet.ignored == [true] + } + def "should find contracts group in scenario"() { given: File baseDir = new File(this.getClass().getResource("/directory/with/scenario").toURI()) diff --git a/accurest-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy b/accurest-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy b/accurest-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy new file mode 100644 index 0000000000..e69de29bb2 diff --git a/accurest-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy b/accurest-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy new file mode 100644 index 0000000000..e69de29bb2 From 4e421b99357e685ed79ce42ced0649d2715399f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Thu, 28 Apr 2016 10:09:58 +0200 Subject: [PATCH 588/719] Fix/depedency mess (#249) --- .../functionalTest/bootSimple/build.gradle | 1 - .../accurest-messaging-camel/build.gradle | 4 ++-- .../accurest-messaging-core/build.gradle | 2 +- .../accurest-messaging-integration/build.gradle | 4 ++-- .../accurest-messaging-stream/build.gradle | 4 ++-- build.gradle | 17 ++++++----------- .../build.gradle | 3 ++- .../stub-runner-messaging-stream/build.gradle | 2 +- stub-runner/stub-runner-spring/build.gradle | 2 +- 9 files changed, 17 insertions(+), 22 deletions(-) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index e550da98c6..602bb14cc8 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -40,7 +40,6 @@ dependencies { compile "org.springframework:spring-web:$springVersion" compile "org.springframework:spring-context-support:$springVersion" compile "org.codehaus.groovy:groovy-all:2.4.5" - compile 'com.fasterxml.jackson.core:jackson-databind:2.4.4' compile 'com.jayway.jsonpath:json-path-assert:2.2.0' testCompile "com.github.tomakehurst:wiremock:2.0.10-beta" diff --git a/accurest-messaging/accurest-messaging-camel/build.gradle b/accurest-messaging/accurest-messaging-camel/build.gradle index ed24c577eb..5d9f3d0e8a 100644 --- a/accurest-messaging/accurest-messaging-camel/build.gradle +++ b/accurest-messaging/accurest-messaging-camel/build.gradle @@ -11,6 +11,6 @@ repositories { 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,)' + compile 'org.apache.camel:camel-spring:2.9.0' + compile 'org.slf4j:slf4j-api:1.6.0' } \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-core/build.gradle b/accurest-messaging/accurest-messaging-core/build.gradle index f63ffbeb9b..8415bec8c7 100644 --- a/accurest-messaging/accurest-messaging-core/build.gradle +++ b/accurest-messaging/accurest-messaging-core/build.gradle @@ -3,6 +3,6 @@ repositories { } dependencies { - compile 'com.fasterxml.jackson.core:jackson-databind:[2.4.4,)' + compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0' compile 'javax.inject:javax.inject:1' } \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-integration/build.gradle b/accurest-messaging/accurest-messaging-integration/build.gradle index b29adf4789..11d8395096 100644 --- a/accurest-messaging/accurest-messaging-integration/build.gradle +++ b/accurest-messaging/accurest-messaging-integration/build.gradle @@ -11,6 +11,6 @@ repositories { 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,)' + compile 'org.springframework:spring-messaging:4.2.5.RELEASE' + compile 'org.slf4j:slf4j-api:1.6.0' } \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-stream/build.gradle b/accurest-messaging/accurest-messaging-stream/build.gradle index 7cf3543d4f..2b54f7ba96 100644 --- a/accurest-messaging/accurest-messaging-stream/build.gradle +++ b/accurest-messaging/accurest-messaging-stream/build.gradle @@ -11,7 +11,7 @@ repositories { dependencies { compile project(':accurest-messaging-root:accurest-messaging-core') - compile 'org.springframework.cloud:spring-cloud-stream:[1.0.0.RC2,)' + compile 'org.springframework.cloud:spring-cloud-stream:1.0.0.RC2' // for MessageCollector - compile 'org.springframework.cloud:spring-cloud-stream-test-support:[1.0.0.RC2,)' + compile 'org.springframework.cloud:spring-cloud-stream-test-support:1.0.0.RC2' } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 0b99857e57..f1c73c4719 100644 --- a/build.gradle +++ b/build.gradle @@ -88,17 +88,12 @@ subprojects { project(':accurest-core') { dependencies { - compile 'org.slf4j:slf4j-api:[1.6.0,)' - compile 'org.codehaus.plexus:plexus-utils:[3.0.0,)' - compile 'commons-io:commons-io:[2.0,)' - compile 'org.apache.commons:commons-lang3:[3.3,)' - compile 'com.google.code.gson:gson:2.3.1' - compile 'com.fasterxml.jackson.core:jackson-databind:2.4.5' - compile 'asm:asm:3.3.1' + compile 'org.slf4j:slf4j-api:1.6.0' + compile 'commons-io:commons-io:2.0' + compile 'org.apache.commons:commons-lang3:3.3' compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile "com.toomuchcoding.jsonassert:jsonassert:$jsonassertVersion" - compile 'org.assertj:assertj-core:2.3.0' - compile localGroovy() + compile 'org.codehaus.groovy:groovy-all:2.4.4' testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' testCompile project(':accurest-testing-utils') @@ -117,8 +112,8 @@ project(':accurest-testing-utils') { project(':accurest-converters') { dependencies { compile project(':accurest-core') - compile 'org.apache.commons:commons-lang3:[3.0,)' - compile 'commons-io:commons-io:[2.0,)' + compile 'org.apache.commons:commons-lang3:3.0' + compile 'commons-io:commons-io:2.0' compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger testCompile "com.github.tomakehurst:wiremock:$wiremockVersion" testCompile 'org.hamcrest:hamcrest-all:1.3' diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle index fa82813497..63718ffa16 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle @@ -12,7 +12,8 @@ repositories { dependencies { compile project(':stub-runner-root:stub-runner-spring') compile project(':accurest-messaging-root:accurest-messaging-integration') - compile 'org.springframework.integration:spring-integration-java-dsl:[1.1.2.RELEASE,)' + compile 'org.springframework.integration:spring-integration-java-dsl:1.1.2.RELEASE' + compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0' testCompile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle index 273a830498..bedc78b2dc 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle @@ -13,7 +13,7 @@ dependencies { compile project(':stub-runner-root:stub-runner-spring') compile project(':stub-runner-root:stub-runner-messaging-root:stub-runner-messaging-integration') compile project(':accurest-messaging-root:accurest-messaging-stream') - compile 'org.springframework.integration:spring-integration-java-dsl:[1.1.2.RELEASE,)' + compile 'org.springframework.integration:spring-integration-java-dsl:1.1.2.RELEASE' testCompile 'org.springframework.cloud:spring-cloud-stream-test-support:1.0.0.RC2' testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" diff --git a/stub-runner/stub-runner-spring/build.gradle b/stub-runner/stub-runner-spring/build.gradle index a020e5d80d..9bb990e658 100644 --- a/stub-runner/stub-runner-spring/build.gradle +++ b/stub-runner/stub-runner-spring/build.gradle @@ -4,7 +4,7 @@ dependencies { compile project(':stub-runner-root:stub-runner') compile localGroovy() - compile 'org.springframework:spring-context:[3.0.0.RELEASE,)' + compile 'org.springframework:spring-context:3.0.0.RELEASE' testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') From 0a7f484655917c34ebb30e2dcde71802a97d5663 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 11:44:24 +0200 Subject: [PATCH 589/719] Fixing deps (#251) --- .../accurest-messaging-camel/build.gradle | 2 +- .../accurest-messaging-integration/build.gradle | 2 +- .../accurest-messaging-stream/build.gradle | 4 ++-- build.gradle | 14 ++++++++++++++ gradle.properties | 7 ++++++- samples/messaging-camel/build.gradle | 6 +++--- samples/messaging-spring/build.gradle | 2 +- samples/messaging-stream/build.gradle | 4 ++-- .../stub-runner-messaging-camel/build.gradle | 7 ++++--- .../stub-runner-messaging-integration/build.gradle | 2 +- .../stub-runner-messaging-stream/build.gradle | 6 ++++-- stub-runner/stub-runner-spring-cloud/build.gradle | 8 ++++---- stub-runner/stub-runner-spring/build.gradle | 2 +- 13 files changed, 44 insertions(+), 22 deletions(-) diff --git a/accurest-messaging/accurest-messaging-camel/build.gradle b/accurest-messaging/accurest-messaging-camel/build.gradle index 5d9f3d0e8a..f43e73d0b4 100644 --- a/accurest-messaging/accurest-messaging-camel/build.gradle +++ b/accurest-messaging/accurest-messaging-camel/build.gradle @@ -11,6 +11,6 @@ repositories { dependencies { compile project(':accurest-messaging-root:accurest-messaging-core') - compile 'org.apache.camel:camel-spring:2.9.0' + compile "org.apache.camel:camel-spring:${camelVersion}" compile 'org.slf4j:slf4j-api:1.6.0' } \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-integration/build.gradle b/accurest-messaging/accurest-messaging-integration/build.gradle index 11d8395096..f2ed07c88c 100644 --- a/accurest-messaging/accurest-messaging-integration/build.gradle +++ b/accurest-messaging/accurest-messaging-integration/build.gradle @@ -11,6 +11,6 @@ repositories { dependencies { compile project(':accurest-messaging-root:accurest-messaging-core') - compile 'org.springframework:spring-messaging:4.2.5.RELEASE' + compile "org.springframework:spring-messaging:${springVersion}" compile 'org.slf4j:slf4j-api:1.6.0' } \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-stream/build.gradle b/accurest-messaging/accurest-messaging-stream/build.gradle index 2b54f7ba96..4f8c9c7344 100644 --- a/accurest-messaging/accurest-messaging-stream/build.gradle +++ b/accurest-messaging/accurest-messaging-stream/build.gradle @@ -11,7 +11,7 @@ repositories { dependencies { compile project(':accurest-messaging-root:accurest-messaging-core') - compile 'org.springframework.cloud:spring-cloud-stream:1.0.0.RC2' + compile "org.springframework.cloud:spring-cloud-stream:${springStreamVersion}" // for MessageCollector - compile 'org.springframework.cloud:spring-cloud-stream-test-support:1.0.0.RC2' + compile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" } \ No newline at end of file diff --git a/build.gradle b/build.gradle index f1c73c4719..73d3214e83 100644 --- a/build.gradle +++ b/build.gradle @@ -185,6 +185,20 @@ project(':accurest-gradle-plugin') { uploadArchives.dependsOn { funcTest } } +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}") + } + } + } + } +} + // REMOVE AFTER https://issues.gradle.org/browse/GRADLE-3433 IS FIXED buildscript { repositories { diff --git a/gradle.properties b/gradle.properties index 7181615caf..bcac24ddd5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,4 +5,9 @@ wiremockVersion = 2.0.10-beta jsonassertVersion = 0.2.2 BOM_VERSION=Brixton-1.0.0.RC1 -springBootVersion=1.3.3.RELEASE \ No newline at end of file +springBootVersion=1.3.3.RELEASE +springVersion=4.2.5.RELEASE +springIntegrationDslVersion=1.1.2.RELEASE +springStreamVersion=1.0.0.RC2 +springCloudVersion=1.1.0.RC2 +camelVersion=2.17.0 \ No newline at end of file diff --git a/samples/messaging-camel/build.gradle b/samples/messaging-camel/build.gradle index 3484906ce6..f358dbffd4 100644 --- a/samples/messaging-camel/build.gradle +++ b/samples/messaging-camel/build.gradle @@ -12,11 +12,11 @@ repositories { dependencies { compile project(':accurest-core') compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" - compile 'org.apache.camel:camel-spring-boot-starter:2.17.0' - compile 'org.apache.camel:camel-jms:2.17.0' + compile "org.apache.camel:camel-spring-boot-starter:${camelVersion}" + compile "org.apache.camel:camel-jms:${camelVersion}" 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' + compile "org.apache.camel:camel-jackson:${camelVersion}" testCompile project(':accurest-messaging-root:accurest-messaging-camel') testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" diff --git a/samples/messaging-spring/build.gradle b/samples/messaging-spring/build.gradle index e1bb4de06e..c38355e1cf 100644 --- a/samples/messaging-spring/build.gradle +++ b/samples/messaging-spring/build.gradle @@ -12,7 +12,7 @@ repositories { dependencies { compile project(':accurest-core') compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" - compile 'org.springframework:spring-jms:4.2.3.RELEASE' + compile "org.springframework:spring-jms:${springVersion}" compile 'org.apache.activemq:activemq-broker:5.12.1' compile 'org.apache.activemq:activemq-pool:5.12.1' diff --git a/samples/messaging-stream/build.gradle b/samples/messaging-stream/build.gradle index 5f94330b61..54779d6866 100644 --- a/samples/messaging-stream/build.gradle +++ b/samples/messaging-stream/build.gradle @@ -12,10 +12,10 @@ repositories { dependencies { compile project(':accurest-core') compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" - compile 'org.springframework.cloud:spring-cloud-stream-binder-rabbit:1.0.0.RC2' + compile "org.springframework.cloud:spring-cloud-stream-binder-rabbit:${springStreamVersion}" testCompile project(':accurest-messaging-root:accurest-messaging-stream') - testCompile 'org.springframework.cloud:spring-cloud-stream-test-support:1.0.0.RC2' + testCompile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle index d2c9ee5d07..0c284fdd5b 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle @@ -12,10 +12,11 @@ repositories { dependencies { compile project(':stub-runner-root:stub-runner-spring') compile project(':accurest-messaging-root:accurest-messaging-camel') - compile 'org.apache.camel:camel-spring-boot-starter:2.17.0' - compile 'org.apache.camel:camel-jackson:2.17.0' + compile "org.apache.camel:camel-spring-boot-starter:${camelVersion}" + compile "org.apache.camel:camel-jackson:${camelVersion}" - testCompile 'org.apache.camel:camel-jms:2.17.0' + testCompile "org.springframework:spring-beans:${springVersion}" + testCompile "org.apache.camel:camel-jms:${camelVersion}" testCompile 'org.apache.activemq:activemq-camel:5.12.1' testCompile 'org.apache.activemq:activemq-pool:5.12.1' testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle index 63718ffa16..f8b8a8277d 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle @@ -12,7 +12,7 @@ repositories { dependencies { compile project(':stub-runner-root:stub-runner-spring') compile project(':accurest-messaging-root:accurest-messaging-integration') - compile 'org.springframework.integration:spring-integration-java-dsl:1.1.2.RELEASE' + compile "org.springframework.integration:spring-integration-java-dsl:${springIntegrationDslVersion}" compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0' testCompile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle index bedc78b2dc..6886c2201d 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle @@ -13,9 +13,11 @@ dependencies { compile project(':stub-runner-root:stub-runner-spring') compile project(':stub-runner-root:stub-runner-messaging-root:stub-runner-messaging-integration') compile project(':accurest-messaging-root:accurest-messaging-stream') - compile 'org.springframework.integration:spring-integration-java-dsl:1.1.2.RELEASE' + compile "org.springframework.integration:spring-integration-java-dsl:${springIntegrationDslVersion}" - testCompile 'org.springframework.cloud:spring-cloud-stream-test-support:1.0.0.RC2' + testCompile "org.springframework:spring-context:${springVersion}" + testCompile "org.springframework:spring-beans:${springVersion}" + testCompile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') diff --git a/stub-runner/stub-runner-spring-cloud/build.gradle b/stub-runner/stub-runner-spring-cloud/build.gradle index 08e64bfd9c..7e3bc4a9a2 100644 --- a/stub-runner/stub-runner-spring-cloud/build.gradle +++ b/stub-runner/stub-runner-spring-cloud/build.gradle @@ -3,19 +3,19 @@ dependencies { compile localGroovy() // TODO: should be compile only - compile 'org.springframework.cloud:spring-cloud-starter:1.1.0.RC2' - compile 'org.springframework.cloud:spring-cloud-starter-ribbon:1.1.0.RC1' + compile "org.springframework.cloud:spring-cloud-starter:${springCloudVersion}" + compile "org.springframework.cloud:spring-cloud-starter-ribbon:${springCloudVersion}" testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - testCompile 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery:1.0.0.RC1' + testCompile 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery:1.0.0.RC2' testCompile 'org.apache.curator:curator-test:2.9.1' testCompile 'io.reactivex:rxjava:1.1.1' testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - testCompile "org.springframework:spring-web:4.2.5.RELEASE" + testCompile "org.springframework:spring-web:${springVersion}" testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') } diff --git a/stub-runner/stub-runner-spring/build.gradle b/stub-runner/stub-runner-spring/build.gradle index 9bb990e658..acb0432826 100644 --- a/stub-runner/stub-runner-spring/build.gradle +++ b/stub-runner/stub-runner-spring/build.gradle @@ -4,7 +4,7 @@ dependencies { compile project(':stub-runner-root:stub-runner') compile localGroovy() - compile 'org.springframework:spring-context:3.0.0.RELEASE' + compile "org.springframework:spring-context:${springVersion}" testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { exclude(group: 'org.codehaus.groovy') From 99875748c0f795b75f73462eeef5e07c9c09f924 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 12:08:45 +0200 Subject: [PATCH 590/719] Stream uses destinations then channels fixes #252 --- .../stream/AccurestStreamMessaging.java | 30 +++++-- .../stubrunner/boot/StubRunnerBootSpec.groovy | 8 +- .../stub-runner-messaging-stream/README.adoc | 23 ++++-- .../stub-runner-messaging-stream/build.gradle | 1 - .../StubRunnerStreamConfiguration.groovy | 78 ++++++++++++++++++ .../main/resources/META-INF/spring.factories | 3 + .../stream/StreamStubRunnerSpec.groovy | 26 +++--- .../src/test/resources/application.yml | 11 ++- .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 1746 -> 1756 bytes 9 files changed, 148 insertions(+), 32 deletions(-) create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java index a300178cc0..4fd456e637 100644 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java +++ b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java @@ -1,19 +1,20 @@ package io.codearte.accurest.messaging.stream; -import java.util.Map; -import java.util.concurrent.TimeUnit; - +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.config.BindingProperties; +import org.springframework.cloud.stream.config.ChannelBindingServiceProperties; import org.springframework.cloud.stream.test.binder.MessageCollector; import org.springframework.context.ApplicationContext; import org.springframework.messaging.Message; import org.springframework.messaging.MessageChannel; -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; -import io.codearte.accurest.messaging.AccurestMessaging; +import java.util.Map; +import java.util.concurrent.TimeUnit; /** * @author Marcin Grzejszczak @@ -43,7 +44,7 @@ public class AccurestStreamMessaging implements AccurestMessaging> message, String destination) { try { - MessageChannel messageChannel = context.getBean(destination, MessageChannel.class); + MessageChannel messageChannel = context.getBean(resolvedDestination(destination), MessageChannel.class); messageChannel.send(message.convert()); } catch (Exception e) { log.error("Exception occurred while trying to send a message [" + message + "] " + @@ -56,7 +57,7 @@ public class AccurestStreamMessaging implements AccurestMessaging> receiveMessage(String destination, long timeout, TimeUnit timeUnit) { try { - MessageChannel messageChannel = context.getBean(destination, MessageChannel.class); + MessageChannel messageChannel = context.getBean(resolvedDestination(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 " + @@ -65,6 +66,19 @@ public class AccurestStreamMessaging implements AccurestMessaging entry : channelBindingServiceProperties.getBindings().entrySet()) { + if (entry.getValue().getDestination().equals(destination)) { + log.debug("Found a channel named [{}] with destination [{}]", entry.getKey(), destination); + return entry.getKey(); + } + } + log.debug("No destination named [{}] was found. Assuming that the destination equals the channel name", destination); + return resolvedDestination; + } + @Override public AccurestMessage> receiveMessage(String destination) { return receiveMessage(destination, 5, TimeUnit.SECONDS); diff --git a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy b/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy index 2c7f041e89..18653638ac 100644 --- a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy +++ b/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy @@ -5,6 +5,8 @@ import groovy.json.JsonSlurper import io.codearte.accurest.stubrunner.StubRunning import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.stream.annotation.EnableBinding +import org.springframework.context.annotation.Configuration import org.springframework.test.context.ContextConfiguration import spock.lang.Specification @@ -12,7 +14,9 @@ import spock.lang.Specification * @author Marcin Grzejszczak */ // tag::boot_usage[] -@ContextConfiguration(classes = StubRunnerBoot, loader = SpringApplicationContextLoader) +@ContextConfiguration(classes = [StubRunnerBootSpec, StubRunnerBoot], loader = SpringApplicationContextLoader) +@EnableBinding +@Configuration class StubRunnerBootSpec extends Specification { @Autowired StubRunning stubRunning @@ -87,6 +91,6 @@ class StubRunnerBootSpec extends Specification { response.statusCode == 404 response.body.asString() == '''{"io.codearte.accurest.stubs:streamService:stubs":["delete_book","return_book_1","return_book_2"]}''' } -// end::boot_usage[] } +// end::boot_usage[] diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc index 2201ae5f98..aa9af8950d 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc @@ -1,12 +1,13 @@ -:input_name: input -:output_name: output - === Stub Runner Messaging Stream Accurest Stub Runner's messaging module gives you an easy way to integrate with Spring Stream. For the provided artifacts it will automatically download the stubs and register the required routes. +WARNING: In Stub Runner's integration with Stream the `messageFrom` or `sentTo` Strings are resolved +first as a `destination` of a channel, and then if there is no such `destination` it's resolved as a +channel name. + ==== Adding it to the project To use it you have to add the following dependency to your project (example for Gradle): @@ -67,16 +68,24 @@ and number *2* include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] ---- +and the following Spring configuration: + +[source,yaml] +---- +include::src/test/resources/application.yml[] +---- + + ===== Scenario 1 (no input message) -So as to trigger a message via the `return_book_1` label we'll use the `StubTigger` interface as follows +So as to trigger a message via the `return_book_1` label we'll use the `StubTrigger` interface as follows [source,groovy] ---- include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger,indent=0] ---- -Next we'll want to listen to the output of the message sent to `{output_name}` +Next we'll want to listen to the output of the message sent to a channel whose `destination` is `returnBook` [source,groovy] ---- @@ -92,14 +101,14 @@ include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/Stream ===== Scenario 2 (output triggered by input) -Since the route is set for you it's enough to just send a message to the `{output_name}` destination. +Since the route is set for you it's enough to just send a message to the `bookStorage` `destination`. [source,groovy] ---- include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_send,indent=0] ---- -Next we'll want to listen to the output of the message sent to `{output_name}` +Next we'll want to listen to the output of the message sent to `returnBook` [source,groovy] ---- diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle index 6886c2201d..b03e790ea4 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle @@ -11,7 +11,6 @@ repositories { dependencies { compile project(':stub-runner-root:stub-runner-spring') - compile project(':stub-runner-root:stub-runner-messaging-root:stub-runner-messaging-integration') compile project(':accurest-messaging-root:accurest-messaging-stream') compile "org.springframework.integration:spring-integration-java-dsl:${springIntegrationDslVersion}" diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy new file mode 100644 index 0000000000..41813d1789 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy @@ -0,0 +1,78 @@ +package io.codearte.accurest.stubrunner.messaging.stream + +import groovy.transform.CompileStatic +import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.stubrunner.BatchStubRunner +import io.codearte.accurest.stubrunner.StubConfiguration +import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.config.AutowireCapableBeanFactory +import org.springframework.cloud.stream.config.BindingProperties +import org.springframework.cloud.stream.config.ChannelBindingServiceProperties +import org.springframework.context.Lifecycle +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Import +import org.springframework.integration.dsl.FilterEndpointSpec +import org.springframework.integration.dsl.GenericEndpointSpec +import org.springframework.integration.dsl.IntegrationFlowBuilder +import org.springframework.integration.dsl.IntegrationFlows +import org.springframework.messaging.Message +/** + * Spring Cloud Stream configuration that iterates over the downloaded Groovy DSLs + * and registers a flow for each DSL. + * + * @author Marcin Grzejszczak + */ +@Configuration +@Import(StubRunnerConfiguration) +@CompileStatic +class StubRunnerStreamConfiguration { + + private static final Logger log = LoggerFactory.getLogger(StubRunnerStreamConfiguration) + + @Bean + FlowRegistrar flowRegistrar(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner) { + Map> accurestContracts = batchStubRunner.accurestContracts + accurestContracts.each { StubConfiguration key, Collection value -> + String name = "${key.groupId}_${key.artifactId}" + value.findAll { it?.input?.messageFrom?.clientValue }.each { GroovyDsl dsl -> + String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" + String from = resolvedDestination(beanFactory, dsl.input.messageFrom.clientValue) + IntegrationFlowBuilder builder = IntegrationFlows.from(from) + .filter(new StubRunnerStreamMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) + .transform(new StubRunnerStreamTransformer(dsl), { GenericEndpointSpec e -> e.id("${flowName}.transformer") }) + if (dsl.outputMessage?.sentTo) { + builder = builder.channel(resolvedDestination(beanFactory, dsl.outputMessage.sentTo.clientValue)) + } else { + builder = builder.handle(new DummyMessageHandler(), "handle") + } + beanFactory.initializeBean(builder.get(), flowName) + beanFactory.getBean("${flowName}.filter", Lifecycle.class).start(); + beanFactory.getBean("${flowName}.transformer", Lifecycle.class).start(); + } + } + return new FlowRegistrar() + } + + private String resolvedDestination(AutowireCapableBeanFactory context, String destination) { + ChannelBindingServiceProperties channelBindingServiceProperties = context.getBean(ChannelBindingServiceProperties.class); + String resolvedDestination = destination; + for (Map.Entry entry : channelBindingServiceProperties.getBindings().entrySet()) { + if (entry.getValue().getDestination().equals(destination)) { + log.debug("Found a channel named [{}] with destination [{}]", entry.getKey(), destination); + return entry.getKey(); + } + } + log.debug("No destination named [{}] was found. Assuming that the destination equals the channel name", destination); + return resolvedDestination; + } + + @CompileStatic + private static class DummyMessageHandler { + void handle(Message message) {} + } + + static class FlowRegistrar {} +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..7b69d1b85a --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +io.codearte.accurest.stubrunner.messaging.stream.StubRunnerStreamConfiguration diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy index 722f41a36b..0233009851 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy @@ -33,17 +33,17 @@ class StreamStubRunnerSpec extends Specification { def setup() { // ensure that message were taken from the queue - messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + messaging.receiveMessage('returnBook', 100, TimeUnit.MILLISECONDS) } def 'should download the stub and register a route for it'() { when: // tag::client_send[] - messaging.send(new BookReturned('foo'), [sample: 'header'], 'input') + messaging.send(new BookReturned('foo'), [sample: 'header'], 'bookStorage') // end::client_send[] then: // tag::client_receive[] - AccurestMessage receivedMessage = messaging.receiveMessage('output') + AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') // end::client_receive[] and: // tag::client_receive_message[] @@ -60,7 +60,7 @@ class StreamStubRunnerSpec extends Specification { // end::client_trigger[] then: // tag::client_trigger_receive[] - AccurestMessage receivedMessage = messaging.receiveMessage('output') + AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') // end::client_trigger_receive[] and: // tag::client_trigger_message[] @@ -76,7 +76,7 @@ class StreamStubRunnerSpec extends Specification { stubFinder.trigger('io.codearte.accurest.stubs:streamService', 'return_book_1') // end::trigger_group_artifact[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('output') + AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -89,7 +89,7 @@ class StreamStubRunnerSpec extends Specification { stubFinder.trigger('streamService', 'return_book_1') // end::trigger_artifact[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('output') + AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -116,7 +116,7 @@ class StreamStubRunnerSpec extends Specification { stubFinder.trigger() // end::trigger_all[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('output') + AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -134,9 +134,9 @@ class StreamStubRunnerSpec extends Specification { def 'should not trigger a message that does not match input'() { when: - messaging.send(new BookReturned('not_matching'), [wrong: 'header_value'], 'input') + messaging.send(new BookReturned('not_matching'), [wrong: 'header_value'], 'bookStorage') then: - AccurestMessage receivedMessage = messaging.receiveMessage('output', 100, TimeUnit.MILLISECONDS) + AccurestMessage receivedMessage = messaging.receiveMessage('returnBook', 100, TimeUnit.MILLISECONDS) and: receivedMessage == null } @@ -156,7 +156,7 @@ class StreamStubRunnerSpec extends Specification { triggeredBy('bookReturnedTriggered()') } outputMessage { - sentTo('jms:output') + sentTo('returnBook') body('''{ "bookName" : "foo" }''') headers { header('BOOK-NAME', 'foo') @@ -170,7 +170,7 @@ class StreamStubRunnerSpec extends Specification { io.codearte.accurest.dsl.GroovyDsl.make { label 'return_book_2' input { - messageFrom('jms:input') + messageFrom('bookStorage') messageBody([ bookName: 'foo' ]) @@ -179,7 +179,7 @@ class StreamStubRunnerSpec extends Specification { } } outputMessage { - sentTo('jms:output') + sentTo('returnBook') body([ bookName: 'foo' ]) @@ -195,7 +195,7 @@ class StreamStubRunnerSpec extends Specification { io.codearte.accurest.dsl.GroovyDsl.make { label 'delete_book' input { - messageFrom('jms:delete') + messageFrom('delete') messageBody([ bookName: 'foo' ]) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml index 154bfe1b6a..e83bb967d7 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml @@ -1,2 +1,11 @@ stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService \ No newline at end of file +stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService + +spring: + cloud: + stream: + bindings: + output: + destination: returnBook + input: + destination: bookStorage \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar index 86c61d52ec4b9571f84240dc880daa2e9e5f5b71..79d37267a7ee83102cfdc309ae5a55aa0f550b44 100644 GIT binary patch delta 634 zcmcb_dxv+z9YF>T2GO`V9`iT)9^Jyg!0?q}G9#1PB@F-9gSVIGwS1GFClKFf8W)Twp-uZ zU9Nl7RCCI$B%Rk)mojqJ_{iTky;#0)SLOuSPpS!f*KByc;G$oZj`pH;HjW2weKd|d zKl5ttM-efe{z{;e!+tWU(Uw-{r;6bz?&KDcn$_> zpntu*4elKVdc|cDlSzFm(2F&g-fZ;#b~Vze!0DoHH}+rU--IQD%-l$ zbGypQfF=L)CUsQ_wAj8mcjlZ=YhoX(!AixH%6pyxRyrd5+l4;fTYp9^g7@EHM0rW_o?9J+A4~ks0hz;;&WRhbBMKM|^0b^c+ zK>{ewzyM@2G&H_uoE*ohH2EDXuOKM&P|TUk!=}R|zzkF%HQ9z)U~&qZ1Ea{~rEKbK I9xNae0M2sqMgRZ+ delta 618 zcmcb^dx>|#9RUswhOnK}JVF=lird7%!0>V68nGj^sv;B5J1(C4B_hlvwz8pN>*MTA^Nd&DUgp@VHIucX z?tVy8$Wi$YjztY?85f`2wOXWi;#skDHuvZW4f-FYR(tFeIB>{0{`8XuMf*=597R4| zWz@F~)Vh+E{YQ+^bKd=LH#PSj=xe@gUi@|bb^ZWvW)=|!2B0USfS!CWH$`PP(34h- z6W^*$)@0(Xj{*8J6w{}zz5XDd9zFkh`3Ez$rwfy}FRB-KwKTeAjn&c}uTQ*_^7wJL zID7@4qe1&j^Y?q>T@(FSi&71qRNm9PqNcNjgTL#=#r)&GpQQdSKhAPK;KzasC96D* z7g@zN9bdKVZO>oh&Zy7U??g`qGtA-H+`nhxB7VKcXJ?!}7W3#-yY$5y2iL_PQ~ty> zwQTB|5_g7Kr^6J^)XosOZc|aV!dO{r)*-#68x7OB5`I}^f14in?@->PCtEtMUpzNy z?eAXMxXl90rc4;oIyscp$pI9vXmJ|g&B!Fjj4g;57&I6pfPuxpzzD<*jV~D)ChIaw oPX53uDhLWT6oV#J20KP~0)&Kwi From 172007f25883edd34fe433154999ebc39f63c0c5 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 13:10:08 +0200 Subject: [PATCH 591/719] Fixed contracts of different types in the same folder fixes #253 --- .../accurest/SingleTestGenerator.groovy | 6 +-- .../RequestProcessingMethodBodyBuilder.groovy | 2 +- .../accurest/SingleTestGeneratorSpec.groovy | 44 +++++++++++++++++++ .../messagingProject/build.gradle | 3 +- .../repository/mappings/a_foo.groovy | 10 +++++ .../IntegrationMessagingApplication.groovy | 8 ++++ .../samples/book/MessagingBaseSpec.groovy | 6 +++ .../samples/book/MessagingBaseTest.java | 7 +++ 8 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 86a7bd47de..678331c5eb 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -66,7 +66,7 @@ class SingleTestGenerator { boolean conditionalImportsAdded = false contracts.each { ParsedDsl key, TestType value -> if (!conditionalImportsAdded) { - if (value == TestType.HTTP) { + if (contracts.values().contains(TestType.HTTP)) { if (configProperties.testMode == TestMode.JAXRSCLIENT) { clazz.addStaticImport('javax.ws.rs.client.Entity.*') if (configProperties.targetFramework == TestFramework.JUNIT) { @@ -79,7 +79,7 @@ class SingleTestGenerator { } } if (configProperties.targetFramework == TestFramework.JUNIT) { - if (value == TestType.HTTP && configProperties.testMode == TestMode.MOCKMVC) { + if (contracts.values().contains(TestType.HTTP) && configProperties.testMode == TestMode.MOCKMVC) { clazz.addImport('com.jayway.restassured.module.mockmvc.specification.MockMvcRequestSpecification') clazz.addImport('com.jayway.restassured.response.ResponseOptions') } @@ -89,7 +89,7 @@ class SingleTestGenerator { if (configProperties.ruleClassForTests) { clazz.addImport('org.junit.Rule').addRule(configProperties.ruleClassForTests) } - if (value == TestType.MESSAGING) { + if (contracts.values().contains(TestType.MESSAGING)) { addMessagingRelatedEntries(clazz) } conditionalImportsAdded = true diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/RequestProcessingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/RequestProcessingMethodBodyBuilder.groovy index 6f8232c68e..c26e09ab08 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/RequestProcessingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/RequestProcessingMethodBodyBuilder.groovy @@ -38,7 +38,7 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { @Override protected boolean hasGivenSection() { - return request.headers || request.body + return true } protected boolean allowedQueryParameter(QueryParameter param) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy index 853ec184cf..6fbcac3f45 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy @@ -85,5 +85,49 @@ class SingleTestGeneratorSpec extends Specification { SPOCK | ['import static javax.ws.rs.client.Entity.*;'] } + def "should work if there is messaging and rest in one folder #testFramework"() { + given: + File secondFile = tmpFolder.newFile() + secondFile.write(""" + io.codearte.accurest.dsl.GroovyDsl.make { + label 'some_label' + input { + messageFrom('delete') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + assertThat('bookWasDeleted()') + } + } + """) + and: + AccurestConfigProperties properties = new AccurestConfigProperties(); + properties.targetFramework = testFramework + Contract contract = new Contract(file.toPath(), true, 1, 2) + contract.ignored >> true + contract.order >> 2 + and: + Contract contract2 = new Contract(secondFile.toPath(), true, 1, 2) + contract2.ignored >> true + contract2.order >> 2 + and: + SingleTestGenerator testGenerator = new SingleTestGenerator(properties) + + when: + String clazz = testGenerator.buildClass([contract, contract2], "test", "test") + + then: + classStrings.each { clazz.contains(it) } + clazz.contains('@Inject AccurestMessaging') + + where: + testFramework | classStrings + JUNIT | jUnitClassStrings + SPOCK | spockClassStrings + } + } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle index 5fffa182b2..8b476c9267 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle @@ -55,6 +55,7 @@ dependencies { testCompile "org.spockframework:spock-spring:1.0-groovy-2.4" testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" testCompile "ch.qos.logback:logback-classic:1.1.2" + testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' // needed if you're going to use Spring MockMvc } accurest { @@ -109,4 +110,4 @@ test { testLogging { exceptionFormat = 'full' } -} \ No newline at end of file +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy new file mode 100644 index 0000000000..6de37631ef --- /dev/null +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy @@ -0,0 +1,10 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + request { + url '/foo' + method 'GET' + } + response { + status 200 + body 'bar' + } +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/IntegrationMessagingApplication.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/IntegrationMessagingApplication.groovy index 820ec8f52e..ed28a54b59 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/IntegrationMessagingApplication.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/IntegrationMessagingApplication.groovy @@ -3,11 +3,19 @@ package io.codearte.accurest.samples.book import org.springframework.boot.SpringApplication import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.context.annotation.ImportResource +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController @SpringBootApplication +@RestController @ImportResource("classpath*:integration-context.xml") class IntegrationMessagingApplication { + @RequestMapping("/foo") + String foo() { + return "bar" + } + static void main(String[] args) { SpringApplication.run(IntegrationMessagingApplication.class, args) } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy index 8d25db00f6..0beb893d51 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy @@ -4,6 +4,8 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader import org.springframework.test.context.ContextConfiguration import spock.lang.Specification +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc + /** * @author Marcin Grzejszczak */ @@ -15,6 +17,10 @@ abstract class MessagingBaseSpec extends Specification { @Autowired BookService bookService @Autowired BookListener bookListener + def setup() { + RestAssuredMockMvc.standaloneSetup(new IntegrationMessagingApplication()) + } + void bookReturnedTriggered() { bookService.returnBook(new BookReturned("foo")) } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java index c5ee6bf196..47634cbf37 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java +++ b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java @@ -2,10 +2,12 @@ package io.codearte.accurest.samples.book; import org.assertj.core.api.Assertions; import org.junit.runner.RunWith; +import org.junit.Before; 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; +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; /** * @author Marcin Grzejszczak @@ -19,6 +21,11 @@ public abstract class MessagingBaseTest { @Autowired BookService bookService; @Autowired BookListener bookListener; + @Before + public void setup() { + RestAssuredMockMvc.standaloneSetup(new IntegrationMessagingApplication()); + } + public void bookReturnedTriggered() { bookService.returnBook(new BookReturned("foo")); } From dfa486c21e4fea869ae1aa48eacc6d6888b4ae88 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 14:01:45 +0200 Subject: [PATCH 592/719] Fixed the boot tests --- .../accurest/stubrunner/boot/StubRunnerBootSpec.groovy | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy b/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy index 18653638ac..ccb8daf018 100644 --- a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy +++ b/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy @@ -55,7 +55,8 @@ class StubRunnerBootSpec extends Specification { when: String response = RestAssuredMockMvc.get('/triggers').body.asString() then: - response == '''{"io.codearte.accurest.stubs:streamService:stubs":["delete_book","return_book_1","return_book_2"]}''' + def root = new JsonSlurper().parseText(response) + root.'io.codearte.accurest.stubs:streamService:stubs'.containsAll(["delete_book","return_book_1","return_book_2"]) } def 'should trigger a messaging label'() { @@ -89,7 +90,8 @@ class StubRunnerBootSpec extends Specification { def response = RestAssuredMockMvc.post("/triggers/missing_label") then: response.statusCode == 404 - response.body.asString() == '''{"io.codearte.accurest.stubs:streamService:stubs":["delete_book","return_book_1","return_book_2"]}''' + def root = new JsonSlurper().parseText(response.body.asString()) + root.'io.codearte.accurest.stubs:streamService:stubs'.containsAll(["delete_book","return_book_1","return_book_2"]) } } From 7df31ed6308f30aeb778d784e11cb85261d1ef88 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 28 Apr 2016 14:04:40 +0200 Subject: [PATCH 593/719] Release version: 1.1.0-M2 [ci skip] From 31e96c1e489a9ec71df2625d7bd1081a8e3eeb7b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 28 Apr 2016 14:04:40 +0200 Subject: [PATCH 594/719] Release version: 1.1.0-M2 [ci skip] From 90881742b30460d0fbb51e011e338962097486f8 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 28 Apr 2016 14:04:40 +0200 Subject: [PATCH 595/719] Release version: 1.1.0-M2 [ci skip] From 0cbe232919ea2752c21afadd0710d63d9c0cc3e1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 15:23:45 +0200 Subject: [PATCH 596/719] Fixed docs --- docs/src/docs/asciidoc/stubrunner.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index d36d427e5a..1c149f8ab4 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -37,9 +37,13 @@ Accurest comes with a new structure of modules ---- include::../../../../stub-runner/stub-runner/README.adoc[] + include::../../../../stub-runner/stub-runner-boot/README.adoc[] + include::../../../../stub-runner/stub-runner-junit/README.adoc[] + include::../../../../stub-runner/stub-runner-spring/README.adoc[] + include::../../../../stub-runner/stub-runner-spring-cloud/README.adoc[] From 6563cf797a370d497f73d7a1d02b37f4d86385d0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 15:31:49 +0200 Subject: [PATCH 597/719] Updated docs --- stub-runner/stub-runner-boot/README.adoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stub-runner/stub-runner-boot/README.adoc b/stub-runner/stub-runner-boot/README.adoc index db79ca1d9f..bf3246974c 100644 --- a/stub-runner/stub-runner-boot/README.adoc +++ b/stub-runner/stub-runner-boot/README.adoc @@ -19,11 +19,11 @@ and a messaging implementation: [source,groovy,indent=0] ---- // for Apache Camel -compile "io.codearte.accurest:accurest-messaging-camel:${accurestVersion}" +compile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}" // for Spring Integration -compile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}" +compile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}" // for Spring Cloud Stream -compile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}" +compile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}" ---- Build a fat-jar and you're ready to go! From 0468287e96dcc8daf6a5e29094bde881531023c1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 15:34:13 +0200 Subject: [PATCH 598/719] Updated docs --- stub-runner/stub-runner-boot/README.adoc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stub-runner/stub-runner-boot/README.adoc b/stub-runner/stub-runner-boot/README.adoc index bf3246974c..78cb519824 100644 --- a/stub-runner/stub-runner-boot/README.adoc +++ b/stub-runner/stub-runner-boot/README.adoc @@ -5,6 +5,9 @@ WARNING: Feature available since {messaging_version} Accurest Stub Runner Boot is a Spring Boot application that exposes REST endpoints to trigger the messaging labels and to access started WireMock servers. +One of the usecases is to run some smoke (end to end) tests on a deployed application. You can read + more about this in the http://toomuchcoding.com/blog/2015/09/27/microservice-deployment/["Microservice Deployment" article at Too Much Coding blog.] + ==== How to use it? Just add the From 910731f649a0f02946963d63a689448f1c3d6caf Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 15:40:26 +0200 Subject: [PATCH 599/719] Updated docs --- docs/src/docs/asciidoc/stubrunner.adoc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index 1c149f8ab4..78d0b68fd6 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -51,15 +51,15 @@ include::../../../../stub-runner/stub-runner-spring-cloud/README.adoc[] Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values: -[width="60%",frame="topbot",options="header"] +[frame="topbot",options="header"] |====================== -| Property name | Default value | Description | -|stubrunner.port.range.min|10000| Minimal value of a port for a started WireMock with stubs| -|stubrunner.port.range.max|15000| Minimal value of a port for a started WireMock with stubs| -|stubrunner.stubs.repository.root|| Maven repo url. If blank then will call the local maven repo| -|stubrunner.stubs.classifier|stubs| Default classifier for the stub artifacts| -|stubrunner.work-offline|false| If true then will not contact any remote repositories to download stubs| -|stubrunner.stubs|| Comma separated list of Ivy notation of stubs to download| +| Property name | Default value | Description +|stubrunner.port.range.min|10000| Minimal value of a port for a started WireMock with stubs +|stubrunner.port.range.max|15000| Minimal value of a port for a started WireMock with stubs +|stubrunner.stubs.repository.root|| Maven repo url. If blank then will call the local maven repo +|stubrunner.stubs.classifier|stubs| Default classifier for the stub artifacts +|stubrunner.work-offline|false| If true then will not contact any remote repositories to download stubs +|stubrunner.stubs.ids|| Comma separated list of Ivy notation of stubs to download |====================== ==== Stub runner stubs ids From 9fcbaab8be195c51c1df3c130b88e0b773f54138 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 18:47:40 +0200 Subject: [PATCH 600/719] Added ConditionalOnMissingBeans for Spring Boot app --- .../noop/NoOpAccurestMessageBuilder.java | 8 +++--- .../stubrunner/boot/StubRunnerConfig.groovy | 28 +++++++++++++++++++ 2 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerConfig.groovy diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java index 50cb34fffa..eadbc73b02 100644 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java +++ b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java @@ -1,21 +1,21 @@ package io.codearte.accurest.messaging.noop; +import java.util.Map; + 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; + return new NoOpAccurestMessage(); } @Override public AccurestMessage create(Object o) { - return null; + return new NoOpAccurestMessage(); } } diff --git a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerConfig.groovy b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerConfig.groovy new file mode 100644 index 0000000000..d0352a2624 --- /dev/null +++ b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerConfig.groovy @@ -0,0 +1,28 @@ +package io.codearte.accurest.stubrunner.boot + +import io.codearte.accurest.messaging.AccurestMessageBuilder +import io.codearte.accurest.messaging.AccurestMessaging +import io.codearte.accurest.messaging.noop.NoOpAccurestMessageBuilder +import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +/** + * @author Marcin Grzejszczak + */ +@Configuration +class StubRunnerConfig { + + @Bean + @ConditionalOnMissingBean + AccurestMessaging noOpAccurestMessaging() { + return new NoOpAccurestMessaging() + } + + @Bean + @ConditionalOnMissingBean + AccurestMessageBuilder noOpAccurestMessageBuilder() { + return new NoOpAccurestMessageBuilder() + } +} From 6a1eefb9537ebc068d1329c496cedc17ae8a8812 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Thu, 28 Apr 2016 21:19:59 +0200 Subject: [PATCH 601/719] accurest update to 1.1.0-M1 - messaging support! (#15) --- README.md | 4 ++-- pom.xml | 35 ++++++----------------------------- src/site/site.xml | 2 +- 3 files changed, 9 insertions(+), 32 deletions(-) diff --git a/README.md b/README.md index b785869107..bb88497011 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ [![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest/maven.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) -Accurate REST Maven Plugin +Accurest Maven Plugin ==== Documentation --- -* [Accurest Wiki](http://codearte.github.io/accurest/) +* [Accurest Documentation](http://codearte.github.io/accurest/) * [Accurest Maven Plugin Documentation Site](http://codearte.github.io/accurest-maven-plugin/plugin-info.html) diff --git a/pom.xml b/pom.xml index 4cff231981..991577dbc3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,10 +6,10 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.5.13-SNAPSHOT + 0.6.0-SNAPSHOT Accurest Maven Plugin - Accurate REST Maven Plugin + Accurest Maven Plugin https://github.com/Codearte/accurest-maven-plugin @@ -35,7 +35,7 @@ UTF-8 UTF-8 - 1.0.6 + 1.1.0-M2 1.1.0 @@ -137,7 +137,7 @@ io.takari.maven.plugins takari-lifecycle-plugin - 1.11.12 + 1.12.0 true @@ -264,17 +264,6 @@ stub-runner ${accurest.version} - - com.github.tomakehurst - wiremock - 2.0.8-beta - - - - org.codehaus.groovy - groovy-all - 2.4.6 - org.eclipse.aether @@ -355,13 +344,13 @@ io.takari.maven.plugins takari-plugin-testing - 2.8.0 + 2.9.0 test io.takari.maven.plugins takari-plugin-integration-testing - 2.8.0 + 2.9.0 pom test @@ -378,18 +367,6 @@ test - - - commons-io - commons-io - 2.5 - - - org.apache.commons - commons-lang3 - 3.4 - - diff --git a/src/site/site.xml b/src/site/site.xml index a05826b4f6..c8806a32eb 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -33,7 +33,7 @@ - + From 5a23d9a7b5a3f39b4b6329f741a05e800ed78505 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Thu, 28 Apr 2016 19:25:09 +0000 Subject: [PATCH 602/719] Sets project version to 0.6.1-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 991577dbc3..5745f7d7f5 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.0-SNAPSHOT + 0.6.1-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From 4d9efc2865b0af615785506fac890972ccb94632 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 28 Apr 2016 22:17:35 +0200 Subject: [PATCH 603/719] Bumped up JSON Assert to 0.4.1 --- .../accurest/util/DelegatingJsonVerifiable.java | 14 ++++++++++++++ gradle.properties | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index dae53a5fc1..3009f01207 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -65,6 +65,15 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { return verifiable; } + @Override + public MethodBufferingJsonVerifiable field(String... strings) { + MethodBufferingJsonVerifiable verifiable = null; + for (String string : strings) { + verifiable = verifiable == null ? field(string) : verifiable.field(string); + } + return verifiable; + } + @Override public MethodBufferingJsonVerifiable array(Object value) { DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.array(value), methodsBuffer); @@ -227,4 +236,9 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { ", methodsBuffer=" + methodsBuffer + '}'; } + + @Override + public T read(Class aClass) { + return delegate.read(aClass); + } } diff --git a/gradle.properties b/gradle.properties index bcac24ddd5..89ebc51c18 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.10-beta -jsonassertVersion = 0.2.2 +jsonassertVersion = 0.4.1 BOM_VERSION=Brixton-1.0.0.RC1 springBootVersion=1.3.3.RELEASE From 467fd230f22df60aa83be52c10a28c94b9640f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Thu, 28 Apr 2016 22:36:49 +0200 Subject: [PATCH 604/719] fixed stubs layout and added information to MANIFEST file (#18) --- pom.xml | 7 ++++- .../accurest/maven/ConvertMojo.groovy | 5 ++-- .../accurest/maven/GenerateStubsMojo.groovy | 28 +++++++++++++++---- .../accurest/maven/PluginUnitTest.java | 9 ++++++ .../basic/src/test/accurest/Messaging.groovy | 23 +++++++++++++++ .../projects/complex-configuration/pom.xml | 4 +-- src/test/projects/spring-boot-groovy/pom.xml | 2 +- src/test/projects/spring-boot-java/pom.xml | 4 +-- 8 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 src/test/projects/basic/src/test/accurest/Messaging.groovy diff --git a/pom.xml b/pom.xml index 5745f7d7f5..ca6cc99c61 100644 --- a/pom.xml +++ b/pom.xml @@ -271,7 +271,12 @@ ${aetherVersion} provided - + + com.toomuchcoding.jsonassert + jsonassert + 0.3.0 + test + org.apache.maven.shared maven-filtering diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy index 9820d50781..5b57bc6865 100644 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -57,7 +57,7 @@ class ConvertMojo extends AbstractMojo { AccurestConfigProperties config = new AccurestConfigProperties() config.contractsDslDir = insideProject ? contractsDirectory : source - config.stubsOutputDir = insideProject ? new File(outputDirectory, 'mappings') : destination + config.stubsOutputDir = insideProject ? new File(outputDirectory, 'mappings') : destination log.info('Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings') log.info(" Accurest contracts directory: ${config.contractsDslDir}") @@ -72,8 +72,7 @@ class ConvertMojo extends AbstractMojo { Resource testResource = new Resource(directory: contractsDirectory.absolutePath) MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution([testResource], - new File(outputDirectory, 'contracts'), project, 'UTF-8', - [], [], mavenSession); + new File(outputDirectory, 'accurest'), project, 'UTF-8', [], [], mavenSession); mavenResourcesExecution.injectProjectBuildFilters = false mavenResourcesExecution.overwrite = true mavenResourcesExecution.includeEmptyDirs = false diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy index 53bd066431..d8e7769e63 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy @@ -1,6 +1,7 @@ package io.codearte.accurest.maven import groovy.transform.CompileStatic +import org.apache.maven.model.Plugin import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException @@ -12,6 +13,7 @@ import org.apache.maven.project.MavenProject import org.apache.maven.project.MavenProjectHelper import org.codehaus.plexus.archiver.Archiver import org.codehaus.plexus.archiver.jar.JarArchiver +import org.codehaus.plexus.archiver.jar.Manifest @Mojo(name = 'generateStubs', defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true) @CompileStatic @@ -36,7 +38,7 @@ class GenerateStubsMojo extends AbstractMojo { private MavenProject project @Component(role = Archiver.class, hint = "jar") - private JarArchiver jarArchiver; + private JarArchiver archiver; @Parameter(defaultValue = 'true') private boolean attachContracts @@ -64,18 +66,32 @@ class GenerateStubsMojo extends AbstractMojo { try { if (attachContracts) { - jarArchiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN, ACCUREST_FILE_PATTERN] as String[], [] as String[]); + archiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN, ACCUREST_FILE_PATTERN] as String[], [] as String[]); } else { log.info("Skipping attaching accurest contracts") - jarArchiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN] as String[], [ACCUREST_FILE_PATTERN] as String[]); + archiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN] as String[], [ACCUREST_FILE_PATTERN] as String[]); } - jarArchiver.setCompress(true); - jarArchiver.setDestFile(stubsJarFile); - jarArchiver.createArchive(); + archiver.setCompress(true); + archiver.setDestFile(stubsJarFile); + archiver.addConfiguredManifest(createManifest()); + archiver.createArchive(); } catch (Exception e) { throw new MojoFailureException("Exception while packaging ${classifier} jar.", e); } return stubsJarFile } + private Manifest createManifest() { + Manifest manifest = new Manifest(); + Plugin accurestMavenPlugin = project.getBuildPlugins().find { it.artifactId == 'accurest-maven-plugin' } + manifest.addConfiguredAttribute(new Manifest.Attribute("Accurest-Maven-Plugin-Version", accurestMavenPlugin.version)); + if (accurestMavenPlugin.getDependencies()) { + String accurestVersion = accurestMavenPlugin.getDependencies().find { + it.artifactId == 'accurest-core' + }.version + manifest.addConfiguredAttribute(new Manifest.Attribute("Accurest-Version", accurestVersion)); + } + return manifest + } + } diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java index 47b3c659a3..d174e26a8e 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java @@ -2,6 +2,7 @@ package io.codearte.accurest.maven; import static io.takari.maven.testing.TestMavenRuntime.newParameter; import static io.takari.maven.testing.TestResources.assertFileContents; +import static io.takari.maven.testing.TestResources.assertFilesNotPresent; import static io.takari.maven.testing.TestResources.assertFilesPresent; import java.io.File; @@ -26,6 +27,7 @@ public class PluginUnitTest { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "convert"); assertFilesPresent(basedir, "target/accurest/mappings/Sample.json"); + assertFilesNotPresent(basedir, "target/accurest/mappings/Messaging.json"); } @Test @@ -35,6 +37,13 @@ public class PluginUnitTest { assertFilesPresent(basedir, "target/accurest/mappings/Sample.json"); } + @Test + public void shouldCopyContracts() throws Exception { + File basedir = resources.getBasedir("basic"); + maven.executeMojo(basedir, "convert"); + assertFilesPresent(basedir, "target/accurest/accurest/Sample.groovy"); + assertFilesPresent(basedir, "target/accurest/accurest/Messaging.groovy"); + } @Test public void shouldGenerateWireMockStubsInSelectedLocation() throws Exception { File basedir = resources.getBasedir("basic"); diff --git a/src/test/projects/basic/src/test/accurest/Messaging.groovy b/src/test/projects/basic/src/test/accurest/Messaging.groovy new file mode 100644 index 0000000000..43b8b41c06 --- /dev/null +++ b/src/test/projects/basic/src/test/accurest/Messaging.groovy @@ -0,0 +1,23 @@ +import io.codearte.accurest.dsl.GroovyDsl + +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') + } + } +} \ No newline at end of file diff --git a/src/test/projects/complex-configuration/pom.xml b/src/test/projects/complex-configuration/pom.xml index 756ca7d8f1..32eed3c57e 100644 --- a/src/test/projects/complex-configuration/pom.xml +++ b/src/test/projects/complex-configuration/pom.xml @@ -45,13 +45,13 @@ com.toomuchcoding.jsonassert jsonassert - 0.3.0 + 0.4.1 test org.assertj assertj-core - 2.3.0 + 2.4.0 test diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index f833504383..ac52188ed6 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -46,7 +46,7 @@ com.toomuchcoding.jsonassert jsonassert - 0.3.0 + 0.4.1 test diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index db9953406d..ecda0561c2 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -45,13 +45,13 @@ com.toomuchcoding.jsonassert jsonassert - 0.3.0 + 0.4.1 test org.assertj assertj-core - 2.3.0 + 2.4.0 test From cfc89ff5191413818428e41489be8f2a925ccb59 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Thu, 28 Apr 2016 20:41:39 +0000 Subject: [PATCH 605/719] Sets project version to 0.6.2-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ca6cc99c61..973313ab06 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.1-SNAPSHOT + 0.6.2-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From 5076429eab9877aae6edd3cb870a05114ab4e7a8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 29 Apr 2016 11:44:06 +0200 Subject: [PATCH 606/719] Grab -> Aether (#255) --- gradle.properties | 3 +- .../stubs/streamService/maven-metadata.xml | 12 ++ stub-runner/stub-runner-junit/README.adoc | 4 +- .../fraudDetectionServer/maven-metadata.xml | 12 ++ .../stubs/loanIssuance/maven-metadata.xml | 12 ++ .../stubs/camelService/maven-metadata.xml | 12 ++ .../integrationService/maven-metadata.xml | 12 ++ .../stubs/streamService/maven-metadata.xml | 12 ++ .../spring/StubRunnerConfiguration.java | 27 +-- stub-runner/stub-runner/build.gradle | 6 + .../stubrunner/AetherStubDownloader.groovy | 106 +++++++++++ .../stubrunner/AvailablePortScanner.groovy | 2 +- .../stubrunner/BatchStubRunnerFactory.groovy | 10 +- .../stubrunner/GrapeStubDownloader.groovy | 172 ------------------ 14 files changed, 209 insertions(+), 193 deletions(-) create mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml create mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata.xml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata.xml create mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy diff --git a/gradle.properties b/gradle.properties index 89ebc51c18..d4ffd5d33d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,4 +10,5 @@ springVersion=4.2.5.RELEASE springIntegrationDslVersion=1.1.2.RELEASE springStreamVersion=1.0.0.RC2 springCloudVersion=1.1.0.RC2 -camelVersion=2.17.0 \ No newline at end of file +camelVersion=2.17.0 +aetherVersion=1.1.0 \ No newline at end of file diff --git a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml new file mode 100644 index 0000000000..dc32790f53 --- /dev/null +++ b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + streamService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-junit/README.adoc b/stub-runner/stub-runner-junit/README.adoc index 4b96939426..d55abedcef 100644 --- a/stub-runner/stub-runner-junit/README.adoc +++ b/stub-runner/stub-runner-junit/README.adoc @@ -15,8 +15,8 @@ After that rule gets executed Stub Runner connects to your Maven repository and - start a WireMock server for each Maven dependency on a random port from the provided range of ports / provided port - feed the WireMock server with all JSON files that are valid WireMock definitions -Stub Runner uses http://docs.groovy-lang.org/latest/html/documentation/grape.html[Groovy's Grape] mechanism to download the Maven dependencies. -Check their http://docs.groovy-lang.org/latest/html/documentation/grape.html[docs] for more information. +Stub Runner uses https://wiki.eclipse.org/Aether[Eclipse Aether] mechanism to download the Maven dependencies. +Check their https://wiki.eclipse.org/Aether[docs] for more information. Since the `AccurestRule` implements the `StubFinder` it allows you to find the started stubs: diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml new file mode 100644 index 0000000000..d4ab9afc83 --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml new file mode 100644 index 0000000000..bf14a1ad21 --- /dev/null +++ b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + loanIssuance + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062111 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata.xml new file mode 100644 index 0000000000..e71db595a7 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + camelService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata.xml new file mode 100644 index 0000000000..b93b655f1f --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + integrationService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml new file mode 100644 index 0000000000..dc32790f53 --- /dev/null +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml @@ -0,0 +1,12 @@ + + + io.codearte.accurest.stubs + streamService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java index 44f959d210..973a4468ef 100644 --- a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java +++ b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java @@ -1,23 +1,24 @@ package io.codearte.accurest.stubrunner.spring; -import java.io.IOException; -import java.util.Set; - +import io.codearte.accurest.messaging.AccurestMessaging; +import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging; +import io.codearte.accurest.stubrunner.AetherStubDownloader; +import io.codearte.accurest.stubrunner.BatchStubRunner; +import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; +import io.codearte.accurest.stubrunner.StubConfiguration; +import io.codearte.accurest.stubrunner.StubDownloader; +import io.codearte.accurest.stubrunner.StubRunner; +import io.codearte.accurest.stubrunner.StubRunnerOptions; +import io.codearte.accurest.stubrunner.StubRunning; +import io.codearte.accurest.stubrunner.util.StubsParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; -import io.codearte.accurest.messaging.AccurestMessaging; -import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging; -import io.codearte.accurest.stubrunner.BatchStubRunner; -import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; -import io.codearte.accurest.stubrunner.StubConfiguration; -import io.codearte.accurest.stubrunner.StubRunner; -import io.codearte.accurest.stubrunner.StubRunnerOptions; -import io.codearte.accurest.stubrunner.StubRunning; -import io.codearte.accurest.stubrunner.util.StubsParser; +import java.io.IOException; +import java.util.Set; /** * Configuration that initializes a {@link BatchStubRunner} that runs {@link StubRunner} instance for each stub @@ -26,6 +27,7 @@ import io.codearte.accurest.stubrunner.util.StubsParser; public class StubRunnerConfiguration { @Autowired(required = false) AccurestMessaging accurestMessaging; + @Autowired(required = false) StubDownloader stubDownloader; /** * Bean that initializes stub runners, runs them and on shutdown closes them. Upon its instantiation @@ -51,6 +53,7 @@ public class StubRunnerConfiguration { stubRepositoryRoot == null || workOffline, stubsSuffix, stubs); Set dependencies = StubsParser.fromString(stubs, stubsSuffix); BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, dependencies, + stubDownloader != null ? stubDownloader : new AetherStubDownloader(stubRunnerOptions), accurestMessaging != null ? accurestMessaging : new NoOpAccurestMessaging()).buildBatchStubRunner(); // TODO: Consider running it in a separate thread batchStubRunner.runStubs(); diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index 158628c06b..6fa7593cd3 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -11,6 +11,12 @@ dependencies { compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile 'javax.servlet:javax.servlet-api:3.1.0' compile 'args4j:args4j:2.32' + compile "org.eclipse.aether:aether-api:${aetherVersion}" + compile "org.eclipse.aether:aether-impl:${aetherVersion}" + compile "org.eclipse.aether:aether-transport-file:${aetherVersion}" + compile "org.eclipse.aether:aether-transport-http:${aetherVersion}" + compile "org.eclipse.aether:aether-connector-basic:${aetherVersion}" + compile 'org.apache.maven:maven-aether-provider:3.3.9' if (rootProject.hasProperty("fatJar")) runtime 'ch.qos.logback:logback-classic:1.1.3' diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy new file mode 100644 index 0000000000..03c2880ca2 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy @@ -0,0 +1,106 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import org.apache.maven.repository.internal.MavenRepositorySystemUtils +import org.eclipse.aether.DefaultRepositorySystemSession +import org.eclipse.aether.RepositorySystem +import org.eclipse.aether.RepositorySystemSession +import org.eclipse.aether.artifact.Artifact +import org.eclipse.aether.artifact.DefaultArtifact +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory +import org.eclipse.aether.impl.DefaultServiceLocator +import org.eclipse.aether.repository.LocalRepository +import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.resolution.ArtifactRequest +import org.eclipse.aether.resolution.ArtifactResult +import org.eclipse.aether.resolution.VersionRangeRequest +import org.eclipse.aether.resolution.VersionRangeResult +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory +import org.eclipse.aether.spi.connector.transport.TransporterFactory +import org.eclipse.aether.transport.file.FileTransporterFactory +import org.eclipse.aether.transport.http.HttpTransporterFactory +import org.eclipse.aether.version.Version + +import static io.codearte.accurest.stubrunner.util.ZipCategory.unzipTo +import static java.nio.file.Files.createTempDirectory + +/** + * @author Mariusz Smykula + */ +@CompileStatic +@Slf4j +class AetherStubDownloader implements StubDownloader { + + private static final String MAVEN_LOCAL_REPOSITORY_LOCATION = 'maven.repo.local' + private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest' + private static final String ARTIFACT_EXTENSION = 'jar' + private static final String ARTIFACT_VERSION = '(0,]' + + private final List remoteRepos + private final RepositorySystem repositorySystem + private final RepositorySystemSession session + + AetherStubDownloader(RepositorySystem repositorySystem, List repositories, RepositorySystemSession session) { + this.remoteRepos = repositories + this.repositorySystem = repositorySystem ?: newRepositorySystem() + this.session = session ?: newSession(this.repositorySystem) + } + + AetherStubDownloader(StubRunnerOptions stubRunnerOptions) { + this.remoteRepos = remoteRepositories(stubRunnerOptions) + this.repositorySystem = newRepositorySystem() + this.session = newSession(this.repositorySystem) + } + + private List remoteRepositories(StubRunnerOptions stubRunnerOptions) { + return [new RemoteRepository.Builder("remote", "default", stubRunnerOptions.stubRepositoryRoot).build()] + } + + private RepositorySystem newRepositorySystem() { + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator() + locator.addService(RepositoryConnectorFactory, BasicRepositoryConnectorFactory) + locator.addService(TransporterFactory, FileTransporterFactory) + locator.addService(TransporterFactory, HttpTransporterFactory) + return locator.getService(RepositorySystem) + } + + private RepositorySystemSession newSession(RepositorySystem system) { + DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); + LocalRepository localRepo = new LocalRepository(System.getProperty(MAVEN_LOCAL_REPOSITORY_LOCATION, "${System.getProperty("user.home")}/.m2/repository")); + session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); + return session; + } + + @Override + public File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { + Version highestVersion = resolveArtifactVersion(stubsGroup, stubsModule, classifier); + log.info("Resolved highest version is $highestVersion") + if (!highestVersion) { + log.warn("Stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] not found in [$stubRepositoryRoot]") + return null + } + Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, highestVersion.toString()) + ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos) + log.info("Resolving artifact $artifact from $remoteRepos") + ArtifactResult result = repositorySystem.resolveArtifact(session, request) + log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}") + return unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) + } + + private Version resolveArtifactVersion(String stubsGroup, String stubsModule, String classifier) { + Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, ARTIFACT_VERSION) + VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, remoteRepos, null); + VersionRangeResult rangeResult = repositorySystem.resolveVersionRange(session, versionRangeRequest); + return rangeResult.highestVersion; + } + + private static File unpackStubJarToATemporaryFolder(URI stubJarUri) { + File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(ACCUREST_TEMP_DIR_PREFIX).toFile() + tmpDirWhereStubsWillBeUnzipped.deleteOnExit() + log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") + unzipTo(new File(stubJarUri), tmpDirWhereStubsWillBeUnzipped) + return tmpDirWhereStubsWillBeUnzipped + } + +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy index db17ee7baa..36251d4524 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy @@ -55,7 +55,7 @@ class AvailablePortScanner { try { socket = new ServerSocket(portToScan) } finally { - socket.close() + socket?.close() } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy index 9b1a03929d..6563028f91 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy @@ -19,23 +19,23 @@ class BatchStubRunnerFactory { private final AccurestMessaging accurestMessaging BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies) { - this(stubRunnerOptions, dependencies, new GrapeStubDownloader(), new NoOpAccurestMessaging()) + this(stubRunnerOptions, dependencies, new AetherStubDownloader(stubRunnerOptions), new NoOpAccurestMessaging()) } BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies, AccurestMessaging accurestMessaging) { - this(stubRunnerOptions, dependencies, new GrapeStubDownloader(), accurestMessaging) + this(stubRunnerOptions, dependencies, new AetherStubDownloader(stubRunnerOptions), accurestMessaging) } BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies, - StubDownloader stubDownloader) { + StubDownloader stubDownloader) { this(stubRunnerOptions, dependencies, stubDownloader, new NoOpAccurestMessaging()) } BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, - Collection dependencies, - StubDownloader stubDownloader, + Collection dependencies, + StubDownloader stubDownloader, AccurestMessaging accurestMessaging) { this.stubRunnerOptions = stubRunnerOptions this.dependencies = dependencies diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy deleted file mode 100644 index 638cadef84..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GrapeStubDownloader.groovy +++ /dev/null @@ -1,172 +0,0 @@ -package io.codearte.accurest.stubrunner - -import groovy.grape.Grape -import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.util.StringUtils -import io.codearte.accurest.stubrunner.util.ZipCategory - -import static java.nio.file.Files.createTempDirectory - -/** - * Downloads stubs from an external repository and unpacks them locally - */ -@Slf4j -class GrapeStubDownloader implements StubDownloader { - - private static final String LATEST_MODULE = '*' - private static final String REPOSITORY_NAME = 'dependency-repository' - private static final String STUB_RUNNER_TEMP_DIR_PREFIX = 'stub-runner' - private static final String GRAPE_CONFIG = 'grape.config' - private static final String STUB_RUNNER_GRAPE_CONFIG = "accurest.stubrunner.grape.config" - - /** - * Downloads stubs from an external repository and unpacks them locally. - * Depending on the switch either uses only local repository to check for - * stub presence. - * - * @param workOffline -flag that defines whether only local cache should be used - * @param stubRepositoryRoot - address of the repo from which deps should be grabbed - * @param stubsGroup - group name of the jar containing stubs - * @param stubsModule - artifact id with a classifier name of the jar containing stubs - * @return file where the stubs where unpacked - */ - File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String - stubsModule, String classifier) { - log.warn("Downloading stubs for group [$stubsGroup], module [$stubsModule], " + - "classifier [$classifier] from repository [$stubRepositoryRoot]") - URI stubJarUri = findGrabbedStubJars(workOffline, stubRepositoryRoot, stubsGroup, stubsModule, classifier) - if (!stubJarUri) { - log.warn("Failed to download stubs for group [$stubsGroup] artifactId [$stubsModule] and " + - "classifier [$classifier] from repository [$stubRepositoryRoot]") - return null - } - File unzippedStubsDir = unpackStubJarToATemporaryFolder(stubJarUri) - unzippedStubsDir.deleteOnExit() - Thread.addShutdownHook { - unzippedStubsDir.deleteDir() - } - return unzippedStubsDir - } - - private File unpackStubJarToATemporaryFolder(URI stubJarUri) { - File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(STUB_RUNNER_TEMP_DIR_PREFIX).toFile() - tmpDirWhereStubsWillBeUnzipped.deleteOnExit() - log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") - use(ZipCategory) { - new File(stubJarUri).unzipTo(tmpDirWhereStubsWillBeUnzipped) - } - return tmpDirWhereStubsWillBeUnzipped - } - - private URI findGrabbedStubJars(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { - Map depToGrab = [group: stubsGroup, module: stubsModule, classifier: classifier, version: LATEST_MODULE, transitive: false] - String accurestStubrunnerGrapePath = System.getProperty(STUB_RUNNER_GRAPE_CONFIG, getDefaultAccurestGrapeConfigPath()) - initializeAccurestGrapeIfAbsent(accurestStubrunnerGrapePath) - String oldGrapeConfig = System.getProperty(GRAPE_CONFIG) - try { - System.setProperty(GRAPE_CONFIG, accurestStubrunnerGrapePath) - log.info("Setting default grapes path to [$accurestStubrunnerGrapePath]") - if (StringUtils.hasText(stubRepositoryRoot)) { - return buildResolver(workOffline).resolveDependency(stubRepositoryRoot, depToGrab) - } - log.warn("No repository passed so will try to resolve dependencies from local Maven Repo") - return buildResolver(true).resolveDependency(stubRepositoryRoot, depToGrab) - } finally { - restoreOldGrapeConfigIfApplicable(oldGrapeConfig) - } - } - - private DependencyResolver buildResolver(boolean workOffline) { - return workOffline ? new LocalOnlyDependencyResolver() : new RemoteDependencyResolver() - } - - private void initializeAccurestGrapeIfAbsent(String accurestGrapePath) { - File accurestGrape = new File(accurestGrapePath) - if (!accurestGrape.exists()) { - accurestGrape.parentFile.mkdirs() - accurestGrape.createNewFile() - accurestGrape.text = GrapeStubDownloader.class.getResource('/accurestStubrunnerGrapeConfig.xml').text - } - } - - private void restoreOldGrapeConfigIfApplicable(String oldGrapeConfig) { - if (oldGrapeConfig) { - System.setProperty(GRAPE_CONFIG, oldGrapeConfig) - } - } - - private String getDefaultAccurestGrapeConfigPath() { - return "${System.getProperty('user.home')}/.accurest/accurestStubrunnerGrapeConfig.xml" - } - - /** - * Dependency resolver providing {@link URI} to remote dependencies. - */ - @Slf4j - private class RemoteDependencyResolver extends DependencyResolver { - - URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { - try { - return doResolveRemoteDependency(stubRepositoryRoot, depToGrab) - } catch (UnknownHostException e) { - failureHandler(stubRepositoryRoot, "unknown host error -> ${e.message}", e) - } catch (Exception e) { - failureHandler(stubRepositoryRoot, "connection error -> ${e.message}", e) - } - } - - private URI doResolveRemoteDependency(String stubRepositoryRoot, Map depToGrab) { - Grape.addResolver(name: REPOSITORY_NAME, root: stubRepositoryRoot) - log.info("Resolving dependency ${depToGrab} location in remote repository...") - return resolveDependencyLocation(depToGrab) - } - - private void failureHandler(String stubRepository, String reason, Exception cause) { - log.warn("Unable to resolve dependency in stub repository [$stubRepository]. Reason: [$reason]", cause) - } - - } - - /** - * Dependency resolver that first checks if a dependency is available in the local repository. - * If not, it will try to provide {@link URI} from the remote repository. - * - * @see RemoteDependencyResolver - */ - @Slf4j - private class LocalOnlyDependencyResolver extends DependencyResolver { - - URI resolveDependency(String stubRepositoryRoot, Map depToGrab) { - try { - log.info("Resolving dependency ${depToGrab} location in local repository...") - return resolveDependencyLocation(depToGrab) - } catch (Exception e) { //Grape throws ordinary RuntimeException - log.warn("Unable to find dependency $depToGrab in local repository, trying $stubRepositoryRoot") - log.debug("Unable to find dependency $depToGrab in local repository: ${e.getClass()}: ${e.message}") - return null - } - } - } - - /** - * Base class of dependency resolvers providing {@link URI} to required dependency. - */ - abstract class DependencyResolver { - - /** - * Returns {@link URI} to a dependency. - * - * @param stubRepositoryRoot root of the repository where the dependency should be found - * @param depToGrab parameters describing dependency to search for - * - * @return {@link URI} to dependency - */ - abstract URI resolveDependency(String stubRepositoryRoot, Map depToGrab) - - URI resolveDependencyLocation(Map depToGrab) { - return Grape.resolve([classLoader: new GroovyClassLoader()], depToGrab).first() - } - - } - -} From 9ca171b8fba87f949a4dd71b245b286de093bcf8 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 29 Apr 2016 12:20:35 +0200 Subject: [PATCH 607/719] Release version: 1.1.0-M3 [ci skip] From 1cb15cd4e18639b0a8845f6f052bf25fbe2f3b47 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 29 Apr 2016 12:20:35 +0200 Subject: [PATCH 608/719] Release version: 1.1.0-M3 [ci skip] From db800d6a0707de2eccc6cd07fe74ba1f71472fb6 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 29 Apr 2016 12:20:35 +0200 Subject: [PATCH 609/719] Release version: 1.1.0-M3 [ci skip] From d4135bb802184208684915b3ba165d3f7d9c21f4 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 29 Apr 2016 15:46:35 +0200 Subject: [PATCH 610/719] Fixed missing offline mode for aether --- docs/src/docs/asciidoc/stubrunner.adoc | 2 +- .../accurest/stubrunner/AetherStubDownloader.groovy | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index 78d0b68fd6..e42aeb54c4 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -56,7 +56,7 @@ Some of the properties that are repetitive can be set using system properties or | Property name | Default value | Description |stubrunner.port.range.min|10000| Minimal value of a port for a started WireMock with stubs |stubrunner.port.range.max|15000| Minimal value of a port for a started WireMock with stubs -|stubrunner.stubs.repository.root|| Maven repo url. If blank then will call the local maven repo +|stubrunner.stubs.repository.root|| Comma separated list of Maven repo urls. If blank then will call the local maven repo |stubrunner.stubs.classifier|stubs| Default classifier for the stub artifacts |stubrunner.work-offline|false| If true then will not contact any remote repositories to download stubs |stubrunner.stubs.ids|| Comma separated list of Ivy notation of stubs to download diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy index 03c2880ca2..15e36801be 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy @@ -54,7 +54,12 @@ class AetherStubDownloader implements StubDownloader { } private List remoteRepositories(StubRunnerOptions stubRunnerOptions) { - return [new RemoteRepository.Builder("remote", "default", stubRunnerOptions.stubRepositoryRoot).build()] + if (stubRunnerOptions.workOffline || !stubRunnerOptions.stubRepositoryRoot) { + return [] + } + return stubRunnerOptions.stubRepositoryRoot.split(',').collect { String repo -> + new RemoteRepository.Builder("remote", "default", repo).build() + } } private RepositorySystem newRepositorySystem() { @@ -82,7 +87,7 @@ class AetherStubDownloader implements StubDownloader { } Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, highestVersion.toString()) ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos) - log.info("Resolving artifact $artifact from $remoteRepos") + log.info("Resolving artifact $artifact from ${remoteRepos?:'local maven repo'}") ArtifactResult result = repositorySystem.resolveArtifact(session, request) log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}") return unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) From 6e128c65da40a438d52ff208485ccdb674995df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Fri, 29 Apr 2016 18:52:15 +0200 Subject: [PATCH 611/719] accurest 1.1.0-M3 and simplified configuration with (#19) --- pom.xml | 2 +- .../accurest/maven/ConvertMojo.groovy | 2 +- .../io/codearte/accurest/maven/RunMojo.groovy | 3 +- .../resources/META-INF/plexus/components.xml | 27 ++++++ .../io/codearte/accurest/maven/PluginIT.java | 14 ++++ src/test/projects/plugin-extension/pom.xml | 84 +++++++++++++++++++ .../src/main/java/hello/Application.java | 12 +++ .../src/main/java/hello/Greeting.java | 20 +++++ .../main/java/hello/GreetingController.java | 19 +++++ .../src/test/accurest/greetings_ok.groovy | 21 +++++ .../greetings_with_default_value.groovy | 17 ++++ .../src/test/java/hello/BaseAccurest.java | 13 +++ 12 files changed, 231 insertions(+), 3 deletions(-) create mode 100644 src/main/resources/META-INF/plexus/components.xml create mode 100644 src/test/projects/plugin-extension/pom.xml create mode 100644 src/test/projects/plugin-extension/src/main/java/hello/Application.java create mode 100644 src/test/projects/plugin-extension/src/main/java/hello/Greeting.java create mode 100644 src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java create mode 100644 src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy create mode 100644 src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy create mode 100644 src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java diff --git a/pom.xml b/pom.xml index 973313ab06..c91f974ed6 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ UTF-8 UTF-8 - 1.1.0-M2 + 1.1.0-M3 1.1.0 diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy index 5b57bc6865..0b245842af 100644 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy @@ -57,7 +57,7 @@ class ConvertMojo extends AbstractMojo { AccurestConfigProperties config = new AccurestConfigProperties() config.contractsDslDir = insideProject ? contractsDirectory : source - config.stubsOutputDir = insideProject ? new File(outputDirectory, 'mappings') : destination + config.stubsOutputDir = insideProject ? new File(outputDirectory, 'mappings') : destination log.info('Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings') log.info(" Accurest contracts directory: ${config.contractsDslDir}") diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index a6b67e4939..7dd0381ef3 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -10,11 +10,12 @@ import org.apache.maven.plugin.MojoExecutionException import org.apache.maven.plugin.MojoFailureException import org.apache.maven.plugins.annotations.Mojo import org.apache.maven.plugins.annotations.Parameter +import org.apache.maven.plugins.annotations.ResolutionScope import org.eclipse.aether.RepositorySystemSession import javax.inject.Inject -@Mojo(name = 'run', requiresProject = false) +@Mojo(name = 'run', requiresProject = false, requiresDependencyResolution = ResolutionScope.RUNTIME) @CompileStatic class RunMojo extends AbstractMojo { diff --git a/src/main/resources/META-INF/plexus/components.xml b/src/main/resources/META-INF/plexus/components.xml new file mode 100644 index 0000000000..a0ace0cd0e --- /dev/null +++ b/src/main/resources/META-INF/plexus/components.xml @@ -0,0 +1,27 @@ + + + + + org.apache.maven.lifecycle.Lifecycle + org.apache.maven.lifecycle.Lifecycle + accurest + + accurest + + accurest-not-used-phase + + + + io.codearte.accurest:accurest-maven-plugin:${project.version}:convert + + + io.codearte.accurest:accurest-maven-plugin:${project.version}:generateTests + + + io.codearte.accurest:accurest-maven-plugin:${project.version}:generateStubs + + + + + + \ No newline at end of file diff --git a/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/io/codearte/accurest/maven/PluginIT.java index 4a4e396f46..268090b57a 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIT.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIT.java @@ -57,6 +57,20 @@ public class PluginIT { .assertErrorFreeLog(); } + @Test + public void should_build_project_with_plugin_extension() throws Exception { + File basedir = resources.getBasedir("plugin-extension"); + maven.forProject(basedir) + .execute("package") + .assertErrorFreeLog() + .assertLogText("Generating server tests source code for Accurest contract verification") + .assertLogText("Generated 1 test classes.") + .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") + .assertLogText("Creating new json") + .assertLogText("Running io.codearte.accurest.tests.AccurestTest") + .assertErrorFreeLog(); + } + @Test @Ignore("Ignored, because of bug accurest#245") public void should_build_project_project_with_complex_configuration() throws Exception { diff --git a/src/test/projects/plugin-extension/pom.xml b/src/test/projects/plugin-extension/pom.xml new file mode 100644 index 0000000000..cebe6bce3e --- /dev/null +++ b/src/test/projects/plugin-extension/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + org.springframework + gs-rest-service + 0.1.0 + + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + ch.qos.logback + logback-classic + + + + + + com.jayway.restassured + rest-assured + 2.9.0 + test + + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + test + + + com.toomuchcoding.jsonassert + jsonassert + 0.4.1 + test + + + org.assertj + assertj-core + 2.4.0 + test + + + + + + 1.8 + ${it-plugin.version} + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + io.codearte.accurest + accurest-maven-plugin + ${accurest-plugin.version} + true + + hello.BaseAccurest + + + + + + diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Application.java b/src/test/projects/plugin-extension/src/main/java/hello/Application.java new file mode 100644 index 0000000000..5abd411428 --- /dev/null +++ b/src/test/projects/plugin-extension/src/main/java/hello/Application.java @@ -0,0 +1,12 @@ +package hello; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java b/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java new file mode 100644 index 0000000000..5d10b59b77 --- /dev/null +++ b/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java @@ -0,0 +1,20 @@ +package hello; + +public class Greeting { + + private final long id; + private final String content; + + public Greeting(long id, String content) { + this.id = id; + this.content = content; + } + + public long getId() { + return id; + } + + public String getContent() { + return content; + } +} diff --git a/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java b/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java new file mode 100644 index 0000000000..e356ab2b10 --- /dev/null +++ b/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java @@ -0,0 +1,19 @@ +package hello; + +import java.util.concurrent.atomic.AtomicLong; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GreetingController { + + private static final String template = "Hello, %s!"; + private final AtomicLong counter = new AtomicLong(); + + @RequestMapping("/greeting") + public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { + return new Greeting(counter.incrementAndGet(), + String.format(template, name)); + } +} diff --git a/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy b/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy new file mode 100644 index 0000000000..0ffb665f6e --- /dev/null +++ b/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy @@ -0,0 +1,21 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'GET' + urlPath('/greeting') { + queryParameters { + parameter 'name': 'Something' + } + } + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, Something!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy b/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy new file mode 100644 index 0000000000..2c5c32f159 --- /dev/null +++ b/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy @@ -0,0 +1,17 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'GET' + url('/greeting') + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, World!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java b/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java new file mode 100644 index 0000000000..d3bf7124e2 --- /dev/null +++ b/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java @@ -0,0 +1,13 @@ +package hello; + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; +import org.junit.Before; + +public class BaseAccurest { + + @Before + public void setup() { + RestAssuredMockMvc.standaloneSetup(new GreetingController()); + } + +} From 12173325d38eca1bc5597e518e2eb9fe44d73d06 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 29 Apr 2016 18:55:44 +0200 Subject: [PATCH 612/719] simplified config [skip ci] --- .../io/codearte/accurest/maven/PluginIT.java | 14 ---- src/test/projects/plugin-extension/pom.xml | 84 ------------------- .../src/main/java/hello/Application.java | 12 --- .../src/main/java/hello/Greeting.java | 20 ----- .../main/java/hello/GreetingController.java | 19 ----- .../src/test/accurest/greetings_ok.groovy | 21 ----- .../greetings_with_default_value.groovy | 17 ---- .../src/test/java/hello/BaseAccurest.java | 13 --- src/test/projects/spring-boot-groovy/pom.xml | 11 +-- src/test/projects/spring-boot-java/pom.xml | 10 +-- 10 files changed, 2 insertions(+), 219 deletions(-) delete mode 100644 src/test/projects/plugin-extension/pom.xml delete mode 100644 src/test/projects/plugin-extension/src/main/java/hello/Application.java delete mode 100644 src/test/projects/plugin-extension/src/main/java/hello/Greeting.java delete mode 100644 src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java delete mode 100644 src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy delete mode 100644 src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy delete mode 100644 src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java diff --git a/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/io/codearte/accurest/maven/PluginIT.java index 268090b57a..4a4e396f46 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIT.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIT.java @@ -57,20 +57,6 @@ public class PluginIT { .assertErrorFreeLog(); } - @Test - public void should_build_project_with_plugin_extension() throws Exception { - File basedir = resources.getBasedir("plugin-extension"); - maven.forProject(basedir) - .execute("package") - .assertErrorFreeLog() - .assertLogText("Generating server tests source code for Accurest contract verification") - .assertLogText("Generated 1 test classes.") - .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") - .assertLogText("Creating new json") - .assertLogText("Running io.codearte.accurest.tests.AccurestTest") - .assertErrorFreeLog(); - } - @Test @Ignore("Ignored, because of bug accurest#245") public void should_build_project_project_with_complex_configuration() throws Exception { diff --git a/src/test/projects/plugin-extension/pom.xml b/src/test/projects/plugin-extension/pom.xml deleted file mode 100644 index cebe6bce3e..0000000000 --- a/src/test/projects/plugin-extension/pom.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - 4.0.0 - - org.springframework - gs-rest-service - 0.1.0 - - - org.springframework.boot - spring-boot-starter-parent - 1.3.3.RELEASE - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-test - test - - - ch.qos.logback - logback-classic - - - - - - com.jayway.restassured - rest-assured - 2.9.0 - test - - - com.jayway.restassured - spring-mock-mvc - 2.9.0 - test - - - com.toomuchcoding.jsonassert - jsonassert - 0.4.1 - test - - - org.assertj - assertj-core - 2.4.0 - test - - - - - - 1.8 - ${it-plugin.version} - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - io.codearte.accurest - accurest-maven-plugin - ${accurest-plugin.version} - true - - hello.BaseAccurest - - - - - - diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Application.java b/src/test/projects/plugin-extension/src/main/java/hello/Application.java deleted file mode 100644 index 5abd411428..0000000000 --- a/src/test/projects/plugin-extension/src/main/java/hello/Application.java +++ /dev/null @@ -1,12 +0,0 @@ -package hello; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -@SpringBootApplication -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java b/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java deleted file mode 100644 index 5d10b59b77..0000000000 --- a/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java +++ /dev/null @@ -1,20 +0,0 @@ -package hello; - -public class Greeting { - - private final long id; - private final String content; - - public Greeting(long id, String content) { - this.id = id; - this.content = content; - } - - public long getId() { - return id; - } - - public String getContent() { - return content; - } -} diff --git a/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java b/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java deleted file mode 100644 index e356ab2b10..0000000000 --- a/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java +++ /dev/null @@ -1,19 +0,0 @@ -package hello; - -import java.util.concurrent.atomic.AtomicLong; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class GreetingController { - - private static final String template = "Hello, %s!"; - private final AtomicLong counter = new AtomicLong(); - - @RequestMapping("/greeting") - public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { - return new Greeting(counter.incrementAndGet(), - String.format(template, name)); - } -} diff --git a/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy b/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy deleted file mode 100644 index 0ffb665f6e..0000000000 --- a/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy +++ /dev/null @@ -1,21 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'GET' - urlPath('/greeting') { - queryParameters { - parameter 'name': 'Something' - } - } - headers { - header 'Content-Type': 'application/json' - } - } - response { - status 200 - body( - id: 1, - content: "Hello, Something!" - ) - } -} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy b/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy deleted file mode 100644 index 2c5c32f159..0000000000 --- a/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy +++ /dev/null @@ -1,17 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'GET' - url('/greeting') - headers { - header 'Content-Type': 'application/json' - } - } - response { - status 200 - body( - id: 1, - content: "Hello, World!" - ) - } -} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java b/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java deleted file mode 100644 index d3bf7124e2..0000000000 --- a/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java +++ /dev/null @@ -1,13 +0,0 @@ -package hello; - -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; -import org.junit.Before; - -public class BaseAccurest { - - @Before - public void setup() { - RestAssuredMockMvc.standaloneSetup(new GreetingController()); - } - -} diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index ac52188ed6..00e820a69f 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -69,21 +69,12 @@ io.codearte.accurest accurest-maven-plugin ${accurest-plugin.version} - - - - convert - generateStubs - generateTests - - - + true hello.BaseAccurest SPOCK - org.codehaus.gmavenplus gmavenplus-plugin diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index ecda0561c2..cebe6bce3e 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -73,15 +73,7 @@ io.codearte.accurest accurest-maven-plugin ${accurest-plugin.version} - - - - convert - generateStubs - generateTests - - - + true hello.BaseAccurest From c4e3a23a5eb4d36929ca7e02041d75f40edff861 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 29 Apr 2016 18:59:55 +0200 Subject: [PATCH 613/719] next version [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c91f974ed6..17972667b2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.2-SNAPSHOT + 0.6.3-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From 91876690ea9d681d26a3dba90b71626a90a1a0a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Fri, 29 Apr 2016 20:36:18 +0200 Subject: [PATCH 614/719] aetherdownloader moved to accurest-core (#20) --- .../stubrunner/AetherStubDownloader.groovy | 67 ------------------- .../AetherStubDownloaderFactory.groovy | 1 + src/test/projects/spring-boot-groovy/pom.xml | 3 +- 3 files changed, 2 insertions(+), 69 deletions(-) delete mode 100644 src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy deleted file mode 100644 index d6f58f59f9..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloader.groovy +++ /dev/null @@ -1,67 +0,0 @@ -package io.codearte.accurest.maven.stubrunner - -import groovy.transform.CompileStatic -import groovy.transform.PackageScope -import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.StubDownloader -import org.eclipse.aether.RepositorySystem -import org.eclipse.aether.RepositorySystemSession -import org.eclipse.aether.artifact.Artifact -import org.eclipse.aether.artifact.DefaultArtifact -import org.eclipse.aether.repository.RemoteRepository -import org.eclipse.aether.resolution.ArtifactRequest -import org.eclipse.aether.resolution.ArtifactResult -import org.eclipse.aether.resolution.VersionRangeRequest -import org.eclipse.aether.resolution.VersionRangeResult -import org.eclipse.aether.version.Version - -import static io.codearte.accurest.stubrunner.util.ZipCategory.unzipTo -import static java.nio.file.Files.createTempDirectory - -@PackageScope -@CompileStatic -@Slf4j -class AetherStubDownloader implements StubDownloader { - - private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest' - private static final String ARTIFACT_EXTENSION = 'jar' - private static final String ARTIFACT_VERSION = '(0,]' - - private final List remoteRepos - private final RepositorySystem repositorySystem - private final RepositorySystemSession session - - AetherStubDownloader(RepositorySystem repositorySystem, List repositories, RepositorySystemSession session) { - this.remoteRepos = repositories - this.repositorySystem = repositorySystem - this.session = session - } - - @Override - public File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { - Version highestVersion = resolveArtifactVersion(stubsGroup, stubsModule, classifier); - log.info("Resolving highest version is $highestVersion") - Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, highestVersion.toString()) - ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos) - log.info("Resolving artifact $artifact from $remoteRepos") - ArtifactResult result = repositorySystem.resolveArtifact(session, request) - log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}") - return unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) - } - - private Version resolveArtifactVersion(String stubsGroup, String stubsModule, String classifier) { - Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, ARTIFACT_VERSION) - VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, remoteRepos, null); - VersionRangeResult rangeResult = repositorySystem.resolveVersionRange(session, versionRangeRequest); - return rangeResult.highestVersion; - } - - private static File unpackStubJarToATemporaryFolder(URI stubJarUri) { - File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(ACCUREST_TEMP_DIR_PREFIX).toFile() - tmpDirWhereStubsWillBeUnzipped.deleteOnExit() - log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") - unzipTo(new File(stubJarUri), tmpDirWhereStubsWillBeUnzipped) - return tmpDirWhereStubsWillBeUnzipped - } - -} diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy index 10fa5461e8..2ec9a2d231 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.maven.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j +import io.codearte.accurest.stubrunner.AetherStubDownloader import org.apache.maven.project.MavenProject import org.eclipse.aether.RepositorySystem import org.eclipse.aether.RepositorySystemSession diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index 00e820a69f..4df8f23a89 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -48,9 +48,8 @@ jsonassert 0.4.1 test - - + From ccd3a367a2bd9e560fc191991aa71c21f2620e94 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Fri, 29 Apr 2016 18:40:13 +0000 Subject: [PATCH 615/719] Sets project version to 0.6.4-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 17972667b2..25d7038f66 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.3-SNAPSHOT + 0.6.4-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From 479cadd4fd81662fddec6a7a092e31b361ebd0cc Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Fri, 29 Apr 2016 21:07:26 +0200 Subject: [PATCH 616/719] plugin version - remove warning [ci skip] --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 25d7038f66..8379e978e3 100644 --- a/pom.xml +++ b/pom.xml @@ -217,6 +217,7 @@ org.apache.maven.plugins maven-site-plugin + 3.5.1 true From 8de4d742fe57b97c01e87437687d7e6712732ef2 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Fri, 29 Apr 2016 22:22:29 +0200 Subject: [PATCH 617/719] Added possibility to pass version (#258) fixes #257 --- docs/src/docs/asciidoc/stubrunner.adoc | 7 +- .../stubrunner/boot/StubRunnerBootSpec.groovy | 16 ++-- .../stubrunner/junit/AccurestRule.java | 23 +++++- .../junit/AccurestRuleSysPropsSpec.groovy | 43 ----------- .../src/test/resources/application.yml | 2 +- .../src/test/resources/application.yml | 2 +- stub-runner/stub-runner/README.adoc | 4 +- .../stubrunner/AetherStubDownloader.groovy | 70 ++++++++++++----- .../accurest/stubrunner/RunningStubs.groovy | 18 +---- .../stubrunner/StubConfiguration.groovy | 77 ++++++++++++++++--- .../accurest/stubrunner/StubDownloader.groovy | 9 +++ .../stubrunner/StubRunnerExecutor.groovy | 2 +- .../stubrunner/StubRunnerFactory.groovy | 11 +-- .../stubrunner/RunningStubsSpec.groovy | 32 +++++--- .../stubrunner/StubConfigurationSpec.groovy | 21 +++++ .../stubrunner/StubRunnerExecutorSpec.groovy | 7 +- .../stubrunner/StubRunnerFactorySpec.groovy | 3 +- 17 files changed, 223 insertions(+), 124 deletions(-) delete mode 100644 stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubConfigurationSpec.groovy diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/docs/asciidoc/stubrunner.adoc index e42aeb54c4..06aea3f697 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/docs/asciidoc/stubrunner.adoc @@ -68,12 +68,13 @@ You can provide the stubs to download via the `stubrunner.stubs.ids` system prop [source,java,indent=0] ---- -groupId:artifactId:classifier:port +groupId:artifactId:version:classifier:port ---- -`classifier` and `port` are optional. +`version`, `classifier` and `port` are optional. -* If you don't provide the `classifier` then the default one will be taken. * If you don't provide the `port` then a random one will be picked +* If you don't provide the `classifier` then the default one will be taken. +* If you don't provide the `version` then the `+` will be passed and the latest one will be downloaded Where `port` means the port of the WireMock server. \ No newline at end of file diff --git a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy b/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy index ccb8daf018..5a02291f2b 100644 --- a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy +++ b/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy @@ -26,12 +26,12 @@ class StubRunnerBootSpec extends Specification { new TriggerController(stubRunning)) } - def 'should return a list of running stub servers in "ivy:port" notation'() { + def 'should return a list of running stub servers in "full ivy:port" notation'() { when: String response = RestAssuredMockMvc.get('/stubs').body.asString() then: def root = new JsonSlurper().parseText(response) - root.'io.codearte.accurest.stubs:streamService:stubs' instanceof Integer + root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs' instanceof Integer } def 'should return a port on which a [#stubId] stub is running'() { @@ -41,7 +41,11 @@ class StubRunnerBootSpec extends Specification { response.statusCode == 200 response.body.as(Integer) > 0 where: - stubId << ['io.codearte.accurest.stubs:streamService:stubs', 'io.codearte.accurest.stubs:streamService', 'streamService'] + stubId << ['io.codearte.accurest.stubs:streamService:+:stubs', + 'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs', + 'io.codearte.accurest.stubs:streamService:+', + 'io.codearte.accurest.stubs:streamService', + 'streamService'] } def 'should return 404 when missing stub was called'() { @@ -51,12 +55,12 @@ class StubRunnerBootSpec extends Specification { response.statusCode == 404 } - def 'should return a list of messaging labels that can be triggered'() { + def 'should return a list of messaging labels that can be triggered when version and classifier are passed'() { when: String response = RestAssuredMockMvc.get('/triggers').body.asString() then: def root = new JsonSlurper().parseText(response) - root.'io.codearte.accurest.stubs:streamService:stubs'.containsAll(["delete_book","return_book_1","return_book_2"]) + root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"]) } def 'should trigger a messaging label'() { @@ -91,7 +95,7 @@ class StubRunnerBootSpec extends Specification { then: response.statusCode == 404 def root = new JsonSlurper().parseText(response.body.asString()) - root.'io.codearte.accurest.stubs:streamService:stubs'.containsAll(["delete_book","return_book_1","return_book_2"]) + root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"]) } } diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index ab31e7ff74..75ba7705ab 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -29,6 +29,7 @@ import io.codearte.accurest.stubrunner.util.StubsParser; */ public class AccurestRule implements TestRule, StubFinder { private static final String DELIMITER = ":"; + public static final String LATEST_VERSION = "+"; private LinkedList stubs = new LinkedList<>(); private StubRunnerOptions stubRunnerOptions = defaultStubRunnerOptions(); @@ -109,10 +110,26 @@ public class AccurestRule implements TestRule, StubFinder { } /** - * Group Id, artifact Id and classifier of a single stub to download + * Group Id, artifact Id, version and classifier of a single stub to download */ - public AccurestRule downloadStub(String groupId, String artifactId, String classifier) { - addStub(groupId + DELIMITER + artifactId + DELIMITER + classifier); + public AccurestRule downloadStub(String groupId, String artifactId, String version, String classifier) { + addStub(groupId + DELIMITER + artifactId + DELIMITER + version + DELIMITER + classifier); + return this; + } + + /** + * Group Id, artifact Id and classifier of a single stub to download in the latest version + */ + public AccurestRule downloadLatestStub(String groupId, String artifactId, String classifier) { + addStub(groupId + DELIMITER + artifactId + DELIMITER + LATEST_VERSION + DELIMITER + classifier); + return this; + } + + /** + * Group Id, artifact Id and version of a single stub to download + */ + public AccurestRule downloadStub(String groupId, String artifactId, String version) { + addStub(groupId + DELIMITER + artifactId + DELIMITER + version); return this; } diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy deleted file mode 100644 index 00e4065198..0000000000 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSysPropsSpec.groovy +++ /dev/null @@ -1,43 +0,0 @@ -package io.codearte.accurest.stubrunner.junit - -import org.junit.AfterClass -import org.junit.BeforeClass -import org.junit.ClassRule -import spock.lang.Shared -import spock.lang.Specification - -/** - * @author Marcin Grzejszczak - */ -class AccurestRuleSysPropsSpec extends Specification { - - @BeforeClass - void setProps() { - System.properties.setProperty("stubrunner.stubs.repository.root", AccurestRuleSysPropsSpec.getResource("/m2repo").toURI().toString()) - System.properties.setProperty("stubrunner.stubs.classifier", 'classifier that will be overridden') - } - - @AfterClass - void cleanupProps() { - System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); - System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); - } - - @ClassRule @Shared AccurestRule rule = new AccurestRule() - .downloadStub("io.codearte.accurest.stubs", "loanIssuance", "stubs") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:stubs") - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - rule.findStubUrl('loanIssuance') != null - rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null - and: 'Stubs were registered' - "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' - cleanup: - System.properties.setProperty("stubrunner.stubs.repository.root", "") - System.properties.setProperty("stubrunner.stubs.classifier", 'stubs') - } -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml index 890cbe6dd8..3bec94b4b9 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml @@ -1,2 +1,2 @@ stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:integrationService \ No newline at end of file +stubrunner.stubs.ids: io.codearte.accurest.stubs:integrationService:0.0.1-SNAPSHOT \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml index e83bb967d7..0bcac69997 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml +++ b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml @@ -1,5 +1,5 @@ stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService +stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs spring: cloud: diff --git a/stub-runner/stub-runner/README.adoc b/stub-runner/stub-runner/README.adoc index af37e01bfc..075d1c7a6a 100644 --- a/stub-runner/stub-runner/README.adoc +++ b/stub-runner/stub-runner/README.adoc @@ -22,7 +22,7 @@ You can set the following options to the main class: (default: 10000) -s (--stubs) VAL : Comma separated list of Ivy representation of jars with stubs. Eg. groupid:artifactid1,group - id2:artifactid2:classifier + id2:artifactid2:version:classifier -sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you keep your stubs (e.g. http://nexus.net/content /repositories/repository) @@ -48,7 +48,7 @@ and inside the `build/lib` there will be a Fat Jar with classifier `fatJar` wait [source,groovy,indent=0] ---- -java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h +java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h:i ---- ==== Stub runner configuration diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy index 15e36801be..b5b875d163 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy @@ -12,19 +12,14 @@ import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory import org.eclipse.aether.impl.DefaultServiceLocator import org.eclipse.aether.repository.LocalRepository import org.eclipse.aether.repository.RemoteRepository -import org.eclipse.aether.resolution.ArtifactRequest -import org.eclipse.aether.resolution.ArtifactResult -import org.eclipse.aether.resolution.VersionRangeRequest -import org.eclipse.aether.resolution.VersionRangeResult +import org.eclipse.aether.resolution.* import org.eclipse.aether.spi.connector.RepositoryConnectorFactory import org.eclipse.aether.spi.connector.transport.TransporterFactory import org.eclipse.aether.transport.file.FileTransporterFactory import org.eclipse.aether.transport.http.HttpTransporterFactory -import org.eclipse.aether.version.Version import static io.codearte.accurest.stubrunner.util.ZipCategory.unzipTo import static java.nio.file.Files.createTempDirectory - /** * @author Mariusz Smykula */ @@ -35,7 +30,8 @@ class AetherStubDownloader implements StubDownloader { private static final String MAVEN_LOCAL_REPOSITORY_LOCATION = 'maven.repo.local' private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest' private static final String ARTIFACT_EXTENSION = 'jar' - private static final String ARTIFACT_VERSION = '(0,]' + private static final String LATEST_ARTIFACT_VERSION = '(0,]' + private static final String LATEST_VERSION_IN_IVY = "+" private final List remoteRepos private final RepositorySystem repositorySystem @@ -79,25 +75,63 @@ class AetherStubDownloader implements StubDownloader { @Override public File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { - Version highestVersion = resolveArtifactVersion(stubsGroup, stubsModule, classifier); - log.info("Resolved highest version is $highestVersion") - if (!highestVersion) { + String version = getVersion(stubsGroup, stubsModule, LATEST_VERSION_IN_IVY, classifier) + return unpackedJar(version, stubsGroup, stubsModule, classifier, stubRepositoryRoot) + } + + private File unpackedJar(String resolvedVersion, String stubsGroup, String stubsModule, String classifier, String stubRepositoryRoot) { + log.info("Resolved version is $resolvedVersion") + if (!resolvedVersion) { log.warn("Stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] not found in [$stubRepositoryRoot]") return null } - Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, highestVersion.toString()) + Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, resolvedVersion) ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos) - log.info("Resolving artifact $artifact from ${remoteRepos?:'local maven repo'}") - ArtifactResult result = repositorySystem.resolveArtifact(session, request) - log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}") - return unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) + log.info("Resolving artifact $artifact from ${remoteRepos ?: 'local maven repo'}") + try { + ArtifactResult result = repositorySystem.resolveArtifact(session, request) + log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}") + return unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) + } catch (Exception e) { + log.warn("Exception occured while trying to download a stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] in [$stubRepositoryRoot]", e) + return null + } + } - private Version resolveArtifactVersion(String stubsGroup, String stubsModule, String classifier) { - Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, ARTIFACT_VERSION) + private String getVersion(String stubsGroup, String stubsModule, String version, String classifier) { + if (!version || LATEST_VERSION_IN_IVY == version) { + log.info("Desired version is [$version] - will try to resolve the latest version") + return resolveHighestArtifactVersion(stubsGroup, stubsModule, classifier); + } + log.info("Will try to resolve version [$version]") + return resolveArtifactVersion(stubsGroup, stubsModule, version, classifier) + } + + @Override + Map.Entry downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration) { + String version = getVersion(stubConfiguration.groupId, stubConfiguration.artifactId, stubConfiguration.version, stubConfiguration.classifier) + File unpackedJar = unpackedJar(version, stubConfiguration.groupId, stubConfiguration.artifactId, + stubConfiguration.classifier, options.stubRepositoryRoot) + if(!unpackedJar) { + return null + } + return new AbstractMap.SimpleEntry(new StubConfiguration(stubConfiguration.groupId, stubConfiguration.artifactId, version, stubConfiguration.classifier), + unpackedJar) + } + + private String resolveHighestArtifactVersion(String stubsGroup, String stubsModule, String classifier) { + Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, LATEST_ARTIFACT_VERSION) VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, remoteRepos, null); VersionRangeResult rangeResult = repositorySystem.resolveVersionRange(session, versionRangeRequest); - return rangeResult.highestVersion; + return rangeResult.highestVersion ?: '' + } + + private String resolveArtifactVersion(String stubsGroup, String stubsModule, String version, String classifier) { + Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, version) + VersionRequest versionRequest = new VersionRequest(artifact, remoteRepos, null) + VersionResult versionResult = repositorySystem.resolveVersion(session, versionRequest); + return versionResult.version ?: '' } private static File unpackStubJarToATemporaryFolder(URI stubJarUri) { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy index 1483b81926..90520ca15d 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy @@ -26,26 +26,14 @@ class RunningStubs { } Map.Entry getEntry(String artifactId) { - def strings = artifactId.split(':') - if (strings.length == 1) { - return namesAndPorts.entrySet().find { - it.key.artifactId == artifactId - } - } else if(strings.length == 2) { - return namesAndPorts.entrySet().find { - it.key.groupId == strings[0] && it.key.artifactId == strings[1] - } - } return namesAndPorts.entrySet().find { - it.key.groupId == strings[0] && - it.key.artifactId == strings[1] && - it.key.classifier == strings[2] + it.key.matchesIvyNotation(artifactId) } } Integer getPort(String groupId, String artifactId) { return namesAndPorts.entrySet().find { - it.key.artifactId == artifactId && it.key.groupId == groupId + it.key.matchesIvyNotation("$groupId:$artifactId") }?.value } @@ -55,7 +43,7 @@ class RunningStubs { boolean isPresent(String groupId, String artifactId) { return namesAndPorts.entrySet().find { - it.key.artifactId == artifactId && it.key.groupId == groupId + it.key.matchesIvyNotation("$groupId:$artifactId") } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy index fa22eae5a7..5d04e09850 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy @@ -12,54 +12,72 @@ import io.codearte.accurest.stubrunner.util.StringUtils @EqualsAndHashCode public class StubConfiguration { private static final String STUB_COLON_DELIMITER = ":" + private static final String DEFAULT_VERSION = "+" + private static final String DEFAULT_CLASSIFIER = "stubs" final String groupId final String artifactId + final String version final String classifier - public StubConfiguration(String groupId, String artifactId, String classifier) { + public StubConfiguration(String groupId, String artifactId, String version) { this.groupId = groupId this.artifactId = artifactId + this.version = version + this.classifier = DEFAULT_CLASSIFIER + } + + public StubConfiguration(String groupId, String artifactId, String version, String classifier) { + this.groupId = groupId + this.artifactId = artifactId + this.version = version this.classifier = classifier } - public StubConfiguration(String stubPath, String defaultClassifier = "stubs") { + public StubConfiguration(String stubPath, String defaultClassifier) { String[] parsedPath = parsedPathEmptyByDefault(stubPath, STUB_COLON_DELIMITER, defaultClassifier) this.groupId = parsedPath[0] this.artifactId = parsedPath[1] - this.classifier = parsedPath[2] + this.version = parsedPath[2] + this.classifier = parsedPath[3] + } + + public StubConfiguration(String stubPath) { + String[] parsedPath = parsedPathEmptyByDefault(stubPath, STUB_COLON_DELIMITER, DEFAULT_CLASSIFIER) + this.groupId = parsedPath[0] + this.artifactId = parsedPath[1] + this.version = parsedPath[2] + this.classifier = parsedPath[3] } private List parsedPathEmptyByDefault(String path, String delimiter, String defaultClassifier) { String[] splitPath = path.split(delimiter) String stubsGroupId = "" String stubsArtifactId = "" + String stubsVersion = "" String stubsClassifier = "" if (splitPath.length >= 2) { stubsGroupId = splitPath[0] stubsArtifactId = splitPath[1] - stubsClassifier = splitPath.length == 3 ? splitPath[2] : defaultClassifier + stubsVersion = splitPath.length >= 3 ? splitPath[2] : DEFAULT_VERSION + stubsClassifier = splitPath.length == 4 ? splitPath[3] : defaultClassifier } - return [stubsGroupId, stubsArtifactId, stubsClassifier] + return [stubsGroupId, stubsArtifactId, stubsVersion, stubsClassifier] } private boolean isDefined() { return StringUtils.hasText(groupId) && StringUtils.hasText(this.artifactId) } - boolean hasClassifier() { - return StringUtils.hasText(classifier) - } - String toColonSeparatedDependencyNotation() { if(!isDefined()) { return "" } - return [groupId, artifactId, classifier].join(STUB_COLON_DELIMITER) + return [groupId, artifactId, version, classifier].join(STUB_COLON_DELIMITER) } @CompileDynamic - boolean matches(String ivyNotationAsString) { + boolean groupIdAndArtifactMatches(String ivyNotationAsString) { def (String groupId, String artifactId) = ivyNotationFrom(ivyNotationAsString) if (!groupId) { return this.artifactId == artifactId @@ -67,6 +85,43 @@ public class StubConfiguration { return this.groupId == groupId && this.artifactId == artifactId } + boolean equals(o) { + if (this.is(o)) return true + if (getClass() != o.class) return false + + StubConfiguration that = (StubConfiguration) o + + if (artifactId != that.artifactId) return false + if (groupId != that.groupId) return false + + return true + } + + int hashCode() { + int result + result = (groupId != null ? groupId.hashCode() : 0) + result = 31 * result + (artifactId != null ? artifactId.hashCode() : 0) + return result + } + + boolean matchesIvyNotation(String ivyNotationAsString) { + def strings = ivyNotationAsString.split(':') + if (strings.length == 1) { + return artifactId == ivyNotationAsString + } else if(strings.length == 2) { + return groupId == strings[0] && + artifactId == strings[1] + } else if(strings.length == 3) { + return groupId == strings[0] && + artifactId == strings[1] && + (strings[2] == DEFAULT_VERSION || version == strings[2]) + } + return groupId == strings[0] && + artifactId == strings[1] && + (strings[2] == DEFAULT_VERSION || version == strings[2]) && + classifier == strings[3] + } + private String[] ivyNotationFrom(String ivyNotation) { String[] splitString = ivyNotation.split(":") if (splitString.length == 1) { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy index 006e639cfd..def3d78ae6 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy @@ -2,6 +2,15 @@ package io.codearte.accurest.stubrunner interface StubDownloader { + @Deprecated File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) + + /** + * Returns a mapping of updated StubConfiguration (it will contain the resolved version) and the location of the downloaded JAR. + * If there was no artifact this method will return {@code null}. + */ + Map.Entry downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration) + + } \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy index 0f30354e36..2852327f13 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy @@ -71,7 +71,7 @@ class StubRunnerExecutor implements StubFinder { @Override boolean trigger(String ivyNotationAsString, String labelName) { Collection matchingContracts = getAccurestContracts().findAll { - it.key.matches(ivyNotationAsString) + it.key.groupIdAndArtifactMatches(ivyNotationAsString) }.values().flatten() as Collection return triggerForDsls(matchingContracts, labelName) } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy index 9a969213bf..51a77acb7c 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -27,14 +27,15 @@ class StubRunnerFactory { Collection createStubsFromServiceConfiguration() { return collaborators.collect { StubConfiguration stubsConfiguration -> - final File unzipedStubDir = stubDownloader.downloadAndUnpackStubJar(stubRunnerOptions.workOffline, - stubRunnerOptions.stubRepositoryRoot, - stubsConfiguration.groupId, stubsConfiguration.artifactId, stubsConfiguration.classifier) - return createStubRunner(unzipedStubDir, stubsConfiguration) + Map.Entry entry = stubDownloader.downloadAndUnpackStubJar(stubRunnerOptions, stubsConfiguration) + if (!entry) { + return null + } + return createStubRunner(entry.key, entry.value) }.findAll { it != null } } - private StubRunner createStubRunner(File unzipedStubDir, StubConfiguration stubsConfiguration) { + private StubRunner createStubRunner(StubConfiguration stubsConfiguration, File unzipedStubDir) { if (!unzipedStubDir) { return null } diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy index d9cf63516b..11acce3339 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy @@ -6,26 +6,31 @@ import spock.lang.Specification * @author Marcin Grzejszczak */ class RunningStubsSpec extends Specification { - RunningStubs runningStubs = new RunningStubs([(new StubConfiguration('a', 'b', 'c')) : 100]) + RunningStubs runningStubs = new RunningStubs([(new StubConfiguration('group', 'artifact', 'version', 'classifier')) : 100]) def "should get port by group and artifact id"() { expect: - runningStubs.getPort('a', 'b') == 100 + runningStubs.getPort('group', 'artifact') == 100 } def "should get port by artifact id"() { expect: - runningStubs.getPort('b') == 100 + runningStubs.getPort('artifact') == 100 } def "should get port by group and artifact id in Ivy notation"() { expect: - runningStubs.getPort('a:b') == 100 + runningStubs.getPort('group:artifact') == 100 } - def "should get port by group, artifact id and classifier in Ivy notation"() { + def "should get port by group, artifact id and version in Ivy notation"() { expect: - runningStubs.getPort('a:b:c') == 100 + runningStubs.getPort('group:artifact:version') == 100 + } + + def "should get port by group, artifact id, version and classifier in Ivy notation"() { + expect: + runningStubs.getPort('group:artifact:version:classifier') == 100 } def "should return null if no stub has been found"() { @@ -35,22 +40,27 @@ class RunningStubsSpec extends Specification { def "should find stub by group and artifact id"() { expect: - runningStubs.isPresent('a', 'b') + runningStubs.isPresent('group', 'artifact') } def "should find stub by artifact id"() { expect: - runningStubs.isPresent('b') + runningStubs.isPresent('artifact') } def "should find stub by group and artifact id in Ivy notation"() { expect: - runningStubs.isPresent('a:b') + runningStubs.isPresent('group:artifact') } - def "should find stub by group, artifact id and classifier in Ivy notation"() { + def "should find stub by group, artifact id and version in Ivy notation"() { expect: - runningStubs.isPresent('a:b:c') + runningStubs.isPresent('group:artifact:version') + } + + def "should find stub by group, artifact id, version and classifier in Ivy notation"() { + expect: + runningStubs.isPresent('group:artifact:version:classifier') } def "should return false if no stub has been found"() { diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubConfigurationSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubConfigurationSpec.groovy new file mode 100644 index 0000000000..87b346da94 --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubConfigurationSpec.groovy @@ -0,0 +1,21 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +class StubConfigurationSpec extends Specification { + + def 'should parse ivy notation'() { + given: + String ivy = 'group:artifact:version:classifier' + when: + StubConfiguration stubConfiguration = new StubConfiguration(ivy) + then: + stubConfiguration.artifactId == 'artifact' + stubConfiguration.groupId == 'group' + stubConfiguration.classifier == 'classifier' + stubConfiguration.version == 'version' + } +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy index fc30f2978e..25add46ece 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy @@ -4,9 +4,8 @@ import spock.lang.Specification class StubRunnerExecutorSpec extends Specification { - static final URL EXPECTED_STUB_URL = new URL('http://localhost:8999') static final int MIN_PORT = 8999 - static final int MAX_PORT = 8999 + static final int MAX_PORT = 9999 private AvailablePortScanner portScanner private StubRepository repository @@ -24,7 +23,9 @@ class StubRunnerExecutorSpec extends Specification { when: executor.runStubs(stubRunnerOptions, repository, stub) then: - executor.findStubUrl("group", "artifact") == EXPECTED_STUB_URL + URL url = executor.findStubUrl("group", "artifact") + url.port >= MIN_PORT + url.port <= MAX_PORT and: executor.findAllRunningStubs().isPresent('artifact') executor.findAllRunningStubs().isPresent('group', 'artifact') diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy index 0d368096bb..19481ce7e0 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy @@ -18,7 +18,8 @@ class StubRunnerFactorySpec extends Specification { def "Should download stub definitions many times"() { given: folder.newFolder("mappings") - 2 * downloader.downloadAndUnpackStubJar(_, _, _, _, _) >> folder.root + 1 * downloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(new StubConfiguration('a:b'), folder.root) + 1 * downloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(new StubConfiguration('c:d'), folder.root) stubRunnerOptions.stubRepositoryRoot = folder.root.absolutePath when: Collection stubRunners = collectOnlyPresentValues(factory.createStubsFromServiceConfiguration()) From fa27cce1c788870a6ce24ab4548981bedbb3b1a7 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 30 Apr 2016 11:56:12 +0200 Subject: [PATCH 618/719] Revert "simplified config" [ci skip] This reverts commit 12173325d38eca1bc5597e518e2eb9fe44d73d06. --- .../io/codearte/accurest/maven/PluginIT.java | 14 ++++ src/test/projects/plugin-extension/pom.xml | 84 +++++++++++++++++++ .../src/main/java/hello/Application.java | 12 +++ .../src/main/java/hello/Greeting.java | 20 +++++ .../main/java/hello/GreetingController.java | 19 +++++ .../src/test/accurest/greetings_ok.groovy | 21 +++++ .../greetings_with_default_value.groovy | 17 ++++ .../src/test/java/hello/BaseAccurest.java | 13 +++ src/test/projects/spring-boot-groovy/pom.xml | 11 ++- src/test/projects/spring-boot-java/pom.xml | 10 ++- 10 files changed, 219 insertions(+), 2 deletions(-) create mode 100644 src/test/projects/plugin-extension/pom.xml create mode 100644 src/test/projects/plugin-extension/src/main/java/hello/Application.java create mode 100644 src/test/projects/plugin-extension/src/main/java/hello/Greeting.java create mode 100644 src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java create mode 100644 src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy create mode 100644 src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy create mode 100644 src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java diff --git a/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/io/codearte/accurest/maven/PluginIT.java index 4a4e396f46..268090b57a 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIT.java +++ b/src/test/java/io/codearte/accurest/maven/PluginIT.java @@ -57,6 +57,20 @@ public class PluginIT { .assertErrorFreeLog(); } + @Test + public void should_build_project_with_plugin_extension() throws Exception { + File basedir = resources.getBasedir("plugin-extension"); + maven.forProject(basedir) + .execute("package") + .assertErrorFreeLog() + .assertLogText("Generating server tests source code for Accurest contract verification") + .assertLogText("Generated 1 test classes.") + .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") + .assertLogText("Creating new json") + .assertLogText("Running io.codearte.accurest.tests.AccurestTest") + .assertErrorFreeLog(); + } + @Test @Ignore("Ignored, because of bug accurest#245") public void should_build_project_project_with_complex_configuration() throws Exception { diff --git a/src/test/projects/plugin-extension/pom.xml b/src/test/projects/plugin-extension/pom.xml new file mode 100644 index 0000000000..cebe6bce3e --- /dev/null +++ b/src/test/projects/plugin-extension/pom.xml @@ -0,0 +1,84 @@ + + + 4.0.0 + + org.springframework + gs-rest-service + 0.1.0 + + + org.springframework.boot + spring-boot-starter-parent + 1.3.3.RELEASE + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-test + test + + + ch.qos.logback + logback-classic + + + + + + com.jayway.restassured + rest-assured + 2.9.0 + test + + + com.jayway.restassured + spring-mock-mvc + 2.9.0 + test + + + com.toomuchcoding.jsonassert + jsonassert + 0.4.1 + test + + + org.assertj + assertj-core + 2.4.0 + test + + + + + + 1.8 + ${it-plugin.version} + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + io.codearte.accurest + accurest-maven-plugin + ${accurest-plugin.version} + true + + hello.BaseAccurest + + + + + + diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Application.java b/src/test/projects/plugin-extension/src/main/java/hello/Application.java new file mode 100644 index 0000000000..5abd411428 --- /dev/null +++ b/src/test/projects/plugin-extension/src/main/java/hello/Application.java @@ -0,0 +1,12 @@ +package hello; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } +} diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java b/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java new file mode 100644 index 0000000000..5d10b59b77 --- /dev/null +++ b/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java @@ -0,0 +1,20 @@ +package hello; + +public class Greeting { + + private final long id; + private final String content; + + public Greeting(long id, String content) { + this.id = id; + this.content = content; + } + + public long getId() { + return id; + } + + public String getContent() { + return content; + } +} diff --git a/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java b/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java new file mode 100644 index 0000000000..e356ab2b10 --- /dev/null +++ b/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java @@ -0,0 +1,19 @@ +package hello; + +import java.util.concurrent.atomic.AtomicLong; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class GreetingController { + + private static final String template = "Hello, %s!"; + private final AtomicLong counter = new AtomicLong(); + + @RequestMapping("/greeting") + public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { + return new Greeting(counter.incrementAndGet(), + String.format(template, name)); + } +} diff --git a/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy b/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy new file mode 100644 index 0000000000..0ffb665f6e --- /dev/null +++ b/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy @@ -0,0 +1,21 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'GET' + urlPath('/greeting') { + queryParameters { + parameter 'name': 'Something' + } + } + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, Something!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy b/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy new file mode 100644 index 0000000000..2c5c32f159 --- /dev/null +++ b/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy @@ -0,0 +1,17 @@ +io.codearte.accurest.dsl.GroovyDsl.make { + priority 2 + request { + method 'GET' + url('/greeting') + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, World!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java b/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java new file mode 100644 index 0000000000..d3bf7124e2 --- /dev/null +++ b/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java @@ -0,0 +1,13 @@ +package hello; + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; +import org.junit.Before; + +public class BaseAccurest { + + @Before + public void setup() { + RestAssuredMockMvc.standaloneSetup(new GreetingController()); + } + +} diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index 4df8f23a89..fcc5045b80 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -68,12 +68,21 @@ io.codearte.accurest accurest-maven-plugin ${accurest-plugin.version} - true + + + + convert + generateStubs + generateTests + + + hello.BaseAccurest SPOCK + org.codehaus.gmavenplus gmavenplus-plugin diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index cebe6bce3e..ecda0561c2 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -73,7 +73,15 @@ io.codearte.accurest accurest-maven-plugin ${accurest-plugin.version} - true + + + + convert + generateStubs + generateTests + + + hello.BaseAccurest From 86458352802214d64132e0ace80ef4086ca293c0 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 30 Apr 2016 12:19:04 +0200 Subject: [PATCH 619/719] fixed site config [skip ci] --- pom.xml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 8379e978e3..13d4d09f47 100644 --- a/pom.xml +++ b/pom.xml @@ -217,9 +217,25 @@ org.apache.maven.plugins maven-site-plugin - 3.5.1 + 3.4 true + + true + true + false + en + UTF-8 + UTF-8 + + + + font + coderay + style + 2 + + From 24d88fdce7bb102662aefb146a9b51a8e8c54023 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 30 Apr 2016 16:41:12 +0200 Subject: [PATCH 620/719] Added possibility to provide optional query param fixes #219 --- .../dsl/WireMockRequestStubStrategy.groovy | 4 + .../accurest/dsl/WireMockGroovyDslSpec.groovy | 78 +++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index f5c4f6945c..59d252a30c 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -10,6 +10,7 @@ import io.codearte.accurest.dsl.internal.Body import io.codearte.accurest.dsl.internal.DslProperty import io.codearte.accurest.dsl.internal.MatchingStrategy import io.codearte.accurest.dsl.internal.NamedProperty +import io.codearte.accurest.dsl.internal.OptionalProperty import io.codearte.accurest.dsl.internal.QueryParameters import io.codearte.accurest.dsl.internal.RegexPatterns import io.codearte.accurest.dsl.internal.Request @@ -152,6 +153,9 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { case Pattern: Pattern value = object as Pattern return ValuePattern.matches(value.pattern()) + case OptionalProperty: + OptionalProperty value = object as OptionalProperty + return ValuePattern.matches(value.optionalPattern()) case MatchingStrategy: MatchingStrategy value = object as MatchingStrategy switch (value.type) { 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 78ddfc8ca3..269d1c3b6f 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 @@ -1483,4 +1483,82 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie and: stubMappingIsValidWireMockStub(wireMockStub) } + + @Issue('#219') + def "should generate request with an optional queryParameter for client side"() { + given: + GroovyDsl groovyDsl = GroovyDsl.make { + request { + method 'GET' + urlPath ('/some/api') { + queryParameters { + parameter 'size': value( + client(regex('[0-9]+')), + server(1) + ) + parameter 'page': value( + client(regex('[0-9]+')), + server(0) + ) + parameter sort: value( + client(optional(regex('^[a-z]+$'))), + server('id') + ) + } + } + } + response { + status 200 + body( + content: [[ + id : '00000000-0000-0000-0000-000000000000', + type : 'Extraordinary', + state : 'ACTIVE', + ]], + totalPages: 1, + totalElements: 1, + last: true, + sort: [[ + direction: 'ASC', + property: 'id', + ignoreCase: false, + nullHandling: 'NATIVE', + ascending: true + ]], + first: true, + numberOfElements: 1, + size: 1, + number: 0 + ) + } + } + when: + def json = toWireMockClientJsonStub(groovyDsl) + then: + AssertionUtil.assertThatJsonsAreEqual((''' + { + "request" : { + "urlPath" : "/some/api", + "method" : "GET", + "queryParameters" : { + "size" : { + "matches" : "[0-9]+" + }, + "page" : { + "matches" : "[0-9]+" + }, + "sort" : { + "matches" : "(^[a-z]+$)?" + } + } + }, + "response" : { + "status" : 200, + "body" : "{\\"content\\":[{\\"id\\":\\"00000000-0000-0000-0000-000000000000\\",\\"type\\":\\"Extraordinary\\",\\"state\\":\\"ACTIVE\\"}],\\"totalPages\\":1,\\"totalElements\\":1,\\"last\\":true,\\"sort\\":[{\\"direction\\":\\"ASC\\",\\"property\\":\\"id\\",\\"ignoreCase\\":false,\\"nullHandling\\":\\"NATIVE\\",\\"ascending\\":true}],\\"first\\":true,\\"numberOfElements\\":1,\\"size\\":1,\\"number\\":0}" + } + } + '''), json) + and: + stubMappingIsValidWireMockStub(json) + } } From fd0cfe14cf6a27cd1125a8277c640df6afd31c2d Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sat, 30 Apr 2016 21:57:53 +0200 Subject: [PATCH 621/719] bad title [ci skip] --- src/site/site.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/site/site.xml b/src/site/site.xml index c8806a32eb..bf22b481c2 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -1,4 +1,4 @@ - + ${project.name} From db0fa56c70a8f35910564d27502c025d8411644c Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 1 May 2016 00:04:32 +0200 Subject: [PATCH 622/719] Release version: 1.1.0-M4 [ci skip] From d78f06c4f742f8862bb9b4924b6c5cf114bd8a1b Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 1 May 2016 00:04:32 +0200 Subject: [PATCH 623/719] Release version: 1.1.0-M4 [ci skip] From a272e3b1c628754821e443515a6b09a8973c5090 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Sun, 1 May 2016 00:04:32 +0200 Subject: [PATCH 624/719] Release version: 1.1.0-M4 [ci skip] From b7ae9da22e680e0d5b4ff74c6b1fb6e11de501ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sun, 1 May 2016 10:25:26 +0200 Subject: [PATCH 625/719] add shutdown for wiremock server (#21) --- .../groovy/io/codearte/accurest/maven/RunMojo.groovy | 12 +++++++++--- .../accurest/maven/stubrunner/LocalStubRunner.groovy | 6 ++++-- .../maven/stubrunner/RemoteStubRunner.groovy | 3 ++- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index 7dd0381ef3..81a870abc0 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -3,6 +3,8 @@ package io.codearte.accurest.maven import groovy.transform.CompileStatic import io.codearte.accurest.maven.stubrunner.LocalStubRunner import io.codearte.accurest.maven.stubrunner.RemoteStubRunner +import io.codearte.accurest.stubrunner.BatchStubRunner +import io.codearte.accurest.stubrunner.StubRunner import io.codearte.accurest.stubrunner.StubRunnerOptions import org.apache.maven.execution.MavenSession import org.apache.maven.plugin.AbstractMojo @@ -63,17 +65,21 @@ class RunMojo extends AbstractMojo { log.info("Skipping accurest execution: accurest.skip=${skip}") return } - + BatchStubRunner batchStubRunner if (!stubs) { StubRunnerOptions options = new StubRunnerOptions(httpPort, httpPort + 1, "", false, stubsClassifier) - localStubRunner.run(resolveStubsDirectory().absolutePath, options) + StubRunner stubRunner = localStubRunner.run(resolveStubsDirectory().absolutePath, options) + batchStubRunner = new BatchStubRunner(Arrays.asList(stubRunner)) } else { StubRunnerOptions options = new StubRunnerOptions(minPort, maxPort, "", false, stubsClassifier) - remoteStubRunner.run(stubs, options, repoSession) + batchStubRunner = remoteStubRunner.run(stubs, options, repoSession) } if (!insideProject) { pressAnyKeyToContinue() + if (batchStubRunner) { + batchStubRunner.close() + } } } diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy index 5239b412a6..73d6a7f16c 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy @@ -13,8 +13,10 @@ import javax.inject.Named @Slf4j class LocalStubRunner { - void run(String contractsDir, StubRunnerOptions options) { + StubRunner run(String contractsDir, StubRunnerOptions options) { log.info("Launching StubRunner with contracts from ${contractsDir}") - new StubRunner(options, contractsDir, new StubConfiguration(contractsDir)).runStubs() + StubRunner stubRunner = new StubRunner(options, contractsDir, new StubConfiguration(contractsDir)) + stubRunner.runStubs() + return stubRunner } } diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy index ca37885758..0de360b01b 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy @@ -21,7 +21,7 @@ class RemoteStubRunner { this.aetherStubDownloaderFactory = aetherStubDownloaderFactory } - void run(String stubs, StubRunnerOptions options, RepositorySystemSession repositorySystemSession) { + BatchStubRunner run(String stubs, StubRunnerOptions options, RepositorySystemSession repositorySystemSession) { AetherStubDownloader stubDownloader = aetherStubDownloaderFactory.build(repositorySystemSession) try { log.debug("Launching StubRunner with args: $options") @@ -30,6 +30,7 @@ class RemoteStubRunner { .buildBatchStubRunner() RunningStubs runningCollaborators = stubRunner.runStubs() log.info(runningCollaborators.toString()) + return stubRunner } catch (Exception e) { log.error("An exception occurred while trying to execute the stubs: ${e.message}") throw e From 48f0a2ccdc5bdb332368c876025406200641a146 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sun, 1 May 2016 08:29:58 +0000 Subject: [PATCH 626/719] Sets project version to 0.6.5-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 13d4d09f47..046e683a45 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.4-SNAPSHOT + 0.6.5-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From cc796748bed1a7da4c7445fddf6dddd48edeaf64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sun, 1 May 2016 13:29:13 +0200 Subject: [PATCH 627/719] support stubs coordinates with port and specific version (#22) --- pom.xml | 7 +- .../maven/EnhancedStubRunnerOptions.groovy | 30 ++++++++ .../EnhancedStubRunnerOptionsBuilder.groovy | 59 +++++++++++++++ .../io/codearte/accurest/maven/RunMojo.groovy | 6 +- .../maven/stubrunner/RemoteStubRunner.groovy | 12 ++-- .../maven/EnhancedStubRunnerOptionsTest.java | 72 +++++++++++++++++++ 6 files changed, 178 insertions(+), 8 deletions(-) create mode 100644 src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptions.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptionsBuilder.groovy create mode 100644 src/test/java/io/codearte/accurest/maven/EnhancedStubRunnerOptionsTest.java diff --git a/pom.xml b/pom.xml index 046e683a45..f03f8bada9 100644 --- a/pom.xml +++ b/pom.xml @@ -35,7 +35,7 @@ UTF-8 UTF-8 - 1.1.0-M3 + 1.1.0-M4 1.1.0 @@ -388,6 +388,11 @@ 4.12 test + + org.assertj + assertj-core + 2.4.0 + diff --git a/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptions.groovy b/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptions.groovy new file mode 100644 index 0000000000..98acc8be3d --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptions.groovy @@ -0,0 +1,30 @@ +package io.codearte.accurest.maven + +import groovy.transform.CompileStatic +import io.codearte.accurest.stubrunner.StubConfiguration +import io.codearte.accurest.stubrunner.StubRunnerOptions + +@CompileStatic +public class EnhancedStubRunnerOptions { + + @Delegate private final StubRunnerOptions options + private final Collection dependencies + + EnhancedStubRunnerOptions(Collection dependencies, StubRunnerOptions options) { + this.options = options + this.dependencies = dependencies + } + + EnhancedStubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, boolean workOffline, String stubsClassifier, Collection dependencies, StubRunnerOptions options) { + this.options = new StubRunnerOptions(minPortValue, maxPortValue, stubRepositoryRoot, workOffline, stubsClassifier) + this.dependencies = dependencies + } + + Collection getDependencies() { + return dependencies + } + + StubRunnerOptions getStubsRunnerOptions() { + return options + } +} diff --git a/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptionsBuilder.groovy b/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptionsBuilder.groovy new file mode 100644 index 0000000000..cd68d42ec4 --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptionsBuilder.groovy @@ -0,0 +1,59 @@ +package io.codearte.accurest.maven + +import groovy.transform.CompileStatic +import io.codearte.accurest.stubrunner.StubConfiguration +import io.codearte.accurest.stubrunner.StubRunnerOptions +import io.codearte.accurest.stubrunner.util.StubsParser + +@CompileStatic +public class EnhancedStubRunnerOptionsBuilder { + + private LinkedList stubs = new LinkedList<>() + + private final StubRunnerOptions options; + + EnhancedStubRunnerOptionsBuilder(StubRunnerOptions options) { + this.options = options + } + + EnhancedStubRunnerOptionsBuilder(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, + boolean workOffline, String stubsClassifier) { + this.options = new StubRunnerOptions(minPortValue, maxPortValue, stubRepositoryRoot, workOffline, stubsClassifier) + } + + EnhancedStubRunnerOptionsBuilder withStubs(String stubs) { + addStub(stubsToList(stubs)) + return this + } + + private Collection buildDependencies() { + return StubsParser.fromString(stubs, options.getStubsClassifier()); + } + + private static List stubsToList(String stubIdsToPortMapping) { + return stubIdsToPortMapping.split(',').collect { it } + } + + private void addStub(List notations) { + for (String notation : notations) { + addStub(notation); + } + } + + private void addStub(String notation) { + if (StubsParser.hasPort(notation)) { + addPort(notation); + stubs.add(StubsParser.ivyFromStringWithPort(notation)); + } else { + stubs.add(notation); + } + } + + private void addPort(String notation) { + options.putStubIdsToPortMapping(StubsParser.fromStringWithPort(notation)); + } + + EnhancedStubRunnerOptions build() { + return new EnhancedStubRunnerOptions(buildDependencies(), options) + } +} diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index 81a870abc0..74c6b23ccd 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -71,8 +71,10 @@ class RunMojo extends AbstractMojo { StubRunner stubRunner = localStubRunner.run(resolveStubsDirectory().absolutePath, options) batchStubRunner = new BatchStubRunner(Arrays.asList(stubRunner)) } else { - StubRunnerOptions options = new StubRunnerOptions(minPort, maxPort, "", false, stubsClassifier) - batchStubRunner = remoteStubRunner.run(stubs, options, repoSession) + EnhancedStubRunnerOptions options = new EnhancedStubRunnerOptionsBuilder(minPort, maxPort, "", false, stubsClassifier) + .withStubs(stubs) + .build() + batchStubRunner = remoteStubRunner.run(options, repoSession) } if (!insideProject) { diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy index 0de360b01b..de1831bfa3 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy @@ -2,8 +2,11 @@ package io.codearte.accurest.maven.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.* -import io.codearte.accurest.stubrunner.util.StubsParser +import io.codearte.accurest.maven.EnhancedStubRunnerOptions +import io.codearte.accurest.stubrunner.AetherStubDownloader +import io.codearte.accurest.stubrunner.BatchStubRunner +import io.codearte.accurest.stubrunner.BatchStubRunnerFactory +import io.codearte.accurest.stubrunner.RunningStubs import org.eclipse.aether.RepositorySystemSession import javax.inject.Inject @@ -21,12 +24,11 @@ class RemoteStubRunner { this.aetherStubDownloaderFactory = aetherStubDownloaderFactory } - BatchStubRunner run(String stubs, StubRunnerOptions options, RepositorySystemSession repositorySystemSession) { + BatchStubRunner run(EnhancedStubRunnerOptions options, RepositorySystemSession repositorySystemSession) { AetherStubDownloader stubDownloader = aetherStubDownloaderFactory.build(repositorySystemSession) try { log.debug("Launching StubRunner with args: $options") - Collection collaborators = StubsParser.fromString(stubs, options.stubsClassifier) - BatchStubRunner stubRunner = new BatchStubRunnerFactory(options, collaborators, stubDownloader) + BatchStubRunner stubRunner = new BatchStubRunnerFactory(options.getStubsRunnerOptions(), options.getDependencies(), stubDownloader) .buildBatchStubRunner() RunningStubs runningCollaborators = stubRunner.runStubs() log.info(runningCollaborators.toString()) diff --git a/src/test/java/io/codearte/accurest/maven/EnhancedStubRunnerOptionsTest.java b/src/test/java/io/codearte/accurest/maven/EnhancedStubRunnerOptionsTest.java new file mode 100644 index 0000000000..0e700200c6 --- /dev/null +++ b/src/test/java/io/codearte/accurest/maven/EnhancedStubRunnerOptionsTest.java @@ -0,0 +1,72 @@ +package io.codearte.accurest.maven; + +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.Test; + +import io.codearte.accurest.stubrunner.StubRunnerOptions; + +public class EnhancedStubRunnerOptionsTest { + + private EnhancedStubRunnerOptionsBuilder builder = new EnhancedStubRunnerOptionsBuilder(new StubRunnerOptions()); + + @Test + public void shouldAddStubCoordinatesWithPort() throws Exception { + + //given + builder.withStubs("foo:bar:8080"); + + //when + EnhancedStubRunnerOptions options = builder.build(); + + //then + assertThat(options.getDependencies()) + .hasToString("[foo:bar:+:stubs]"); + assertThat(options.getStubIdsToPortMapping()) + .hasToString("{foo:bar:+:stubs=8080}"); + } + + @Test + public void shouldAddStubCoordinatesWithoutPort() throws Exception { + + //given + builder.withStubs("foo:bar"); + + //when + EnhancedStubRunnerOptions options = builder.build(); + + //then + assertThat(options.getDependencies()) + .hasToString("[foo:bar:+:stubs]"); + assertThat(options.getStubIdsToPortMapping()) + .hasSize(0); + } + + @Test + public void shouldAddMultipleStubCoordinates() throws Exception { + + //given + builder.withStubs("foo:bar,bar:foo"); + + //when + EnhancedStubRunnerOptions options = builder.build(); + + //then + assertThat(options.getDependencies()) + .hasSize(2); + } + + @Test + public void shouldAddStubCoordinatesWithVersion() throws Exception { + + //given + builder.withStubs("foo:1.2.3:bar"); + + //when + EnhancedStubRunnerOptions options = builder.build(); + + //then + assertThat(options.getDependencies()) + .hasToString("[foo:1.2.3:bar:stubs]"); + } +} \ No newline at end of file From 91863c637ca9bd504ad97434f8f5cdd7c41b850a Mon Sep 17 00:00:00 2001 From: Travis CI Date: Sun, 1 May 2016 11:34:04 +0000 Subject: [PATCH 628/719] Sets project version to 0.6.6-SNAPSHOT. [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f03f8bada9..ecd22c9478 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.5-SNAPSHOT + 0.6.6-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From 5a5c79b922170e5ad5ce56d62fe6c9fa81f12714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sun, 1 May 2016 16:47:09 +0200 Subject: [PATCH 629/719] refactor to allow access logic related to stubs ports from external libraries (#259) --- .../stubrunner/junit/AccurestRule.java | 96 +++++--------- .../spring/StubRunnerConfiguration.java | 16 +-- .../stubrunner/BatchStubRunnerFactory.groovy | 24 ++-- .../stubrunner/StubRunnerFactory.groovy | 11 +- .../accurest/stubrunner/StubRunnerMain.groovy | 14 ++- .../stubrunner/StubRunnerOptions.groovy | 72 ++++------- .../StubRunnerOptionsBuilder.groovy | 118 ++++++++++++++++++ .../stubrunner/StubRunnerExecutorSpec.groovy | 12 +- .../stubrunner/StubRunnerFactorySpec.groovy | 14 ++- .../accurest/stubrunner/StubRunnerSpec.groovy | 2 +- 10 files changed, 229 insertions(+), 150 deletions(-) create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java index 75ba7705ab..fdc76d786a 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java @@ -1,17 +1,5 @@ package io.codearte.accurest.stubrunner.junit; -import java.net.URL; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - import io.codearte.accurest.dsl.GroovyDsl; import io.codearte.accurest.stubrunner.BatchStubRunner; import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; @@ -19,8 +7,16 @@ import io.codearte.accurest.stubrunner.RunningStubs; import io.codearte.accurest.stubrunner.StubConfiguration; import io.codearte.accurest.stubrunner.StubFinder; import io.codearte.accurest.stubrunner.StubRunnerOptions; -import io.codearte.accurest.stubrunner.util.StringUtils; -import io.codearte.accurest.stubrunner.util.StubsParser; +import io.codearte.accurest.stubrunner.StubRunnerOptionsBuilder; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.net.URL; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; /** * JUnit class rule that allows you to download the provided stubs. @@ -29,10 +25,9 @@ import io.codearte.accurest.stubrunner.util.StubsParser; */ public class AccurestRule implements TestRule, StubFinder { private static final String DELIMITER = ":"; - public static final String LATEST_VERSION = "+"; + private static final String LATEST_VERSION = "+"; - private LinkedList stubs = new LinkedList<>(); - private StubRunnerOptions stubRunnerOptions = defaultStubRunnerOptions(); + private StubRunnerOptionsBuilder stubRunnerOptionsBuilder = new StubRunnerOptionsBuilder(defaultStubRunnerOptions()); private BatchStubRunner stubFinder; @Override @@ -46,25 +41,21 @@ public class AccurestRule implements TestRule, StubFinder { } private void before() { - Collection dependencies = StubsParser.fromString(stubs, stubRunnerOptions.getStubsClassifier()); - stubFinder = new BatchStubRunnerFactory(stubRunnerOptions, dependencies) - .buildBatchStubRunner(); + stubFinder = new BatchStubRunnerFactory(stubRunnerOptionsBuilder.build()).buildBatchStubRunner(); stubFinder.runStubs(); } }; } private StubRunnerOptions defaultStubRunnerOptions() { - Integer minPort = Integer.valueOf(System.getProperty("stubrunner.port.range.min", "10000")); - Integer maxPort = Integer.valueOf(System.getProperty("stubrunner.port.range.max", "15000")); - String repoRoot = System.getProperty("stubrunner.stubs.repository.root", ""); - String stubSuffix = System.getProperty("stubrunner.stubs.classifier", "stubs"); - Boolean workOffline = Boolean.parseBoolean(System.getProperty("stubrunner.work-offline", "false")); - String stubsToDownload = System.getProperty("stubrunner.stubs.ids", ""); - if (StringUtils.hasText(stubsToDownload)) { - Collections.addAll(stubs, stubsToDownload.split(",")); - } - return new StubRunnerOptions(minPort, maxPort, repoRoot, workOffline, stubSuffix, stubsToDownload); + return new StubRunnerOptionsBuilder() + .withMinPort(Integer.valueOf(System.getProperty("stubrunner.port.range.min", "10000"))) + .withMaxPort(Integer.valueOf(System.getProperty("stubrunner.port.range.max", "15000"))) + .withStubRepositoryRoot(System.getProperty("stubrunner.stubs.repository.root", "")) + .withWorkOffline(Boolean.parseBoolean(System.getProperty("stubrunner.work-offline", "false"))) + .withStubsClassifier(System.getProperty("stubrunner.stubs.classifier", "stubs")) + .withStubs(System.getProperty("stubrunner.stubs.ids", "")) + .build(); } /** @@ -73,7 +64,7 @@ public class AccurestRule implements TestRule, StubFinder { * @see StubRunnerOptions */ public AccurestRule options(StubRunnerOptions stubRunnerOptions) { - this.stubRunnerOptions = stubRunnerOptions; + stubRunnerOptionsBuilder.withOptions(stubRunnerOptions); return this; } @@ -81,7 +72,7 @@ public class AccurestRule implements TestRule, StubFinder { * Min value of port for WireMock server */ public AccurestRule minPort(int minPort) { - this.stubRunnerOptions.setMinPortValue(minPort); + stubRunnerOptionsBuilder.withMinPort(minPort); return this; } @@ -89,7 +80,7 @@ public class AccurestRule implements TestRule, StubFinder { * Max value of port for WireMock server */ public AccurestRule maxPort(int maxPort) { - this.stubRunnerOptions.setMaxPortValue(maxPort); + stubRunnerOptionsBuilder.withMaxPort(maxPort); return this; } @@ -97,7 +88,7 @@ public class AccurestRule implements TestRule, StubFinder { * String URI of repository containing stubs */ public AccurestRule repoRoot(String repoRoot) { - this.stubRunnerOptions.setStubRepositoryRoot(repoRoot); + stubRunnerOptionsBuilder.withStubRepositoryRoot(repoRoot); return this; } @@ -105,7 +96,7 @@ public class AccurestRule implements TestRule, StubFinder { * Should download stubs or use only the local repository */ public AccurestRule workOffline(boolean workOffline) { - this.stubRunnerOptions.setWorkOffline(workOffline); + stubRunnerOptionsBuilder.withWorkOffline(workOffline); return this; } @@ -113,7 +104,7 @@ public class AccurestRule implements TestRule, StubFinder { * Group Id, artifact Id, version and classifier of a single stub to download */ public AccurestRule downloadStub(String groupId, String artifactId, String version, String classifier) { - addStub(groupId + DELIMITER + artifactId + DELIMITER + version + DELIMITER + classifier); + stubRunnerOptionsBuilder.withStubs(groupId + DELIMITER + artifactId + DELIMITER + version + DELIMITER + classifier); return this; } @@ -121,7 +112,7 @@ public class AccurestRule implements TestRule, StubFinder { * Group Id, artifact Id and classifier of a single stub to download in the latest version */ public AccurestRule downloadLatestStub(String groupId, String artifactId, String classifier) { - addStub(groupId + DELIMITER + artifactId + DELIMITER + LATEST_VERSION + DELIMITER + classifier); + stubRunnerOptionsBuilder.withStubs(groupId + DELIMITER + artifactId + DELIMITER + LATEST_VERSION + DELIMITER + classifier); return this; } @@ -129,7 +120,7 @@ public class AccurestRule implements TestRule, StubFinder { * Group Id, artifact Id and version of a single stub to download */ public AccurestRule downloadStub(String groupId, String artifactId, String version) { - addStub(groupId + DELIMITER + artifactId + DELIMITER + version); + stubRunnerOptionsBuilder.withStubs(groupId + DELIMITER + artifactId + DELIMITER + version); return this; } @@ -137,7 +128,7 @@ public class AccurestRule implements TestRule, StubFinder { * Group Id, artifact Id of a single stub to download. Default classifier will be picked. */ public AccurestRule downloadStub(String groupId, String artifactId) { - addStub(groupId + DELIMITER + artifactId); + stubRunnerOptionsBuilder.withStubs(groupId + DELIMITER + artifactId); return this; } @@ -145,7 +136,7 @@ public class AccurestRule implements TestRule, StubFinder { * Ivy notation of a single stub to download. */ public AccurestRule downloadStub(String ivyNotation) { - addStub(ivyNotation); + stubRunnerOptionsBuilder.withStubs(ivyNotation); return this; } @@ -153,7 +144,7 @@ public class AccurestRule implements TestRule, StubFinder { * Stubs to download in Ivy notations */ public AccurestRule downloadStubs(String... ivyNotations) { - addStub(Arrays.asList(ivyNotations)); + stubRunnerOptionsBuilder.withStubs(Arrays.asList(ivyNotations)); return this; } @@ -161,7 +152,7 @@ public class AccurestRule implements TestRule, StubFinder { * Stubs to download in Ivy notations */ public AccurestRule downloadStubs(List ivyNotations) { - addStub(ivyNotations); + stubRunnerOptionsBuilder.withStubs(ivyNotations); return this; } @@ -169,8 +160,7 @@ public class AccurestRule implements TestRule, StubFinder { * Appends port to last added stub */ public AccurestRule withPort(Integer port) { - String lastStub = stubs.peekLast(); - addPort(lastStub + DELIMITER + port); + stubRunnerOptionsBuilder.withPort(port); return this; } @@ -214,22 +204,4 @@ public class AccurestRule implements TestRule, StubFinder { return stubFinder.labels(); } - private void addStub(String notation) { - if(StubsParser.hasPort(notation)) { - addPort(notation); - stubs.add(StubsParser.ivyFromStringWithPort(notation)); - } else { - stubs.add(notation); - } - } - - private void addStub(List notations) { - for (String notation : notations) { - addStub(notation); - } - } - - private void addPort(String notation) { - stubRunnerOptions.putStubIdsToPortMapping(StubsParser.fromStringWithPort(notation)); - } } diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java index 973a4468ef..5ba1a3cc66 100644 --- a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java +++ b/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java @@ -5,12 +5,11 @@ import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging; import io.codearte.accurest.stubrunner.AetherStubDownloader; import io.codearte.accurest.stubrunner.BatchStubRunner; import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; -import io.codearte.accurest.stubrunner.StubConfiguration; import io.codearte.accurest.stubrunner.StubDownloader; import io.codearte.accurest.stubrunner.StubRunner; import io.codearte.accurest.stubrunner.StubRunnerOptions; +import io.codearte.accurest.stubrunner.StubRunnerOptionsBuilder; import io.codearte.accurest.stubrunner.StubRunning; -import io.codearte.accurest.stubrunner.util.StubsParser; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; @@ -18,7 +17,6 @@ import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import java.io.IOException; -import java.util.Set; /** * Configuration that initializes a {@link BatchStubRunner} that runs {@link StubRunner} instance for each stub @@ -49,10 +47,14 @@ public class StubRunnerConfiguration { @Value("${stubrunner.stubs.classifier:stubs}") String stubsSuffix, @Value("${stubrunner.work-offline:false}") boolean workOffline, @Value("${stubrunner.stubs.ids:}") String stubs) throws IOException { - StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue, maxPortValue, uriStringOrEmpty(stubRepositoryRoot), - stubRepositoryRoot == null || workOffline, stubsSuffix, stubs); - Set dependencies = StubsParser.fromString(stubs, stubsSuffix); - BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, dependencies, + StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder() + .withMinMaxPort(minPortValue, maxPortValue) + .withStubRepositoryRoot(uriStringOrEmpty(stubRepositoryRoot)) + .withWorkOffline(stubRepositoryRoot == null || workOffline) + .withStubsClassifier(stubsSuffix) + .withStubs(stubs) + .build(); + BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, stubDownloader != null ? stubDownloader : new AetherStubDownloader(stubRunnerOptions), accurestMessaging != null ? accurestMessaging : new NoOpAccurestMessaging()).buildBatchStubRunner(); // TODO: Consider running it in a separate thread diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy index 6563028f91..6c7061da7e 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy @@ -14,37 +14,29 @@ import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging class BatchStubRunnerFactory { private final StubRunnerOptions stubRunnerOptions - private final Collection dependencies private final StubDownloader stubDownloader private final AccurestMessaging accurestMessaging - BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies) { - this(stubRunnerOptions, dependencies, new AetherStubDownloader(stubRunnerOptions), new NoOpAccurestMessaging()) + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions) { + this(stubRunnerOptions, new AetherStubDownloader(stubRunnerOptions), new NoOpAccurestMessaging()) } - BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, Collection dependencies, - AccurestMessaging accurestMessaging) { - this(stubRunnerOptions, dependencies, new AetherStubDownloader(stubRunnerOptions), accurestMessaging) + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, AccurestMessaging accurestMessaging) { + this(stubRunnerOptions, new AetherStubDownloader(stubRunnerOptions), accurestMessaging) } - BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, - Collection dependencies, - StubDownloader stubDownloader) { - this(stubRunnerOptions, dependencies, stubDownloader, new NoOpAccurestMessaging()) + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader) { + this(stubRunnerOptions, stubDownloader, new NoOpAccurestMessaging()) } - BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, - Collection dependencies, - StubDownloader stubDownloader, - AccurestMessaging accurestMessaging) { + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader, AccurestMessaging accurestMessaging) { this.stubRunnerOptions = stubRunnerOptions - this.dependencies = dependencies this.stubDownloader = stubDownloader this.accurestMessaging = accurestMessaging } BatchStubRunner buildBatchStubRunner() { - StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, dependencies, stubDownloader, accurestMessaging) + StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, stubDownloader, accurestMessaging) return new BatchStubRunner(stubRunnerFactory.createStubsFromServiceConfiguration()) } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy index 51a77acb7c..42f5cf65af 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy @@ -3,6 +3,7 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import io.codearte.accurest.messaging.AccurestMessaging + /** * Factory of StubRunners. Basing on the options and passed collaborators * downloads the stubs and returns a list of corresponding stub runners. @@ -12,21 +13,17 @@ import io.codearte.accurest.messaging.AccurestMessaging class StubRunnerFactory { private final StubRunnerOptions stubRunnerOptions - private final Collection collaborators private final StubDownloader stubDownloader private final AccurestMessaging accurestMessaging - StubRunnerFactory(StubRunnerOptions stubRunnerOptions, - Collection collaborators, - StubDownloader stubDownloader, AccurestMessaging accurestMessaging) { + StubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader, AccurestMessaging accurestMessaging) { this.stubRunnerOptions = stubRunnerOptions - this.collaborators = collaborators this.stubDownloader = stubDownloader this.accurestMessaging = accurestMessaging } Collection createStubsFromServiceConfiguration() { - return collaborators.collect { StubConfiguration stubsConfiguration -> + return stubRunnerOptions.getDependencies().collect { StubConfiguration stubsConfiguration -> Map.Entry entry = stubDownloader.downloadAndUnpackStubJar(stubRunnerOptions, stubsConfiguration) if (!entry) { return null @@ -43,7 +40,7 @@ class StubRunnerFactory { } private StubRunner createStubRunner(File unzippedStubsDir, StubConfiguration stubsConfiguration, - StubRunnerOptions stubRunnerOptions) { + StubRunnerOptions stubRunnerOptions) { return new StubRunner(stubRunnerOptions, unzippedStubsDir.path, stubsConfiguration, accurestMessaging) } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy index 86002bf2db..aaa620a63a 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy @@ -2,7 +2,6 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.util.StubsParser import org.kohsuke.args4j.CmdLineException import org.kohsuke.args4j.CmdLineParser import org.kohsuke.args4j.Option @@ -37,8 +36,14 @@ class StubRunnerMain { CmdLineParser parser = new CmdLineParser(this) try { parser.parseArgument(args) - this.arguments = new Arguments(new StubRunnerOptions(minPortValue, maxPortValue, stubRepositoryRoot, - workOffline, stubsSuffix)) + StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder() + .withMinMaxPort(minPortValue, maxPortValue) + .withStubRepositoryRoot(stubRepositoryRoot) + .withWorkOffline(workOffline) + .withStubsClassifier(stubsSuffix) + .withStubs(stubs) + .build() + this.arguments = new Arguments(stubRunnerOptions) } catch (CmdLineException e) { printErrorMessage(e, parser) throw e @@ -61,8 +66,7 @@ class StubRunnerMain { try { log.debug("Launching StubRunner with args: $arguments") // TODO: Pass StubsToRun either from String or File - Collection collaborators = StubsParser.fromString(stubs, stubsSuffix) - BatchStubRunner stubRunner = new BatchStubRunnerFactory(arguments.stubRunnerOptions, collaborators).buildBatchStubRunner() + BatchStubRunner stubRunner = new BatchStubRunnerFactory(arguments.stubRunnerOptions).buildBatchStubRunner() RunningStubs runningCollaborators = stubRunner.runStubs() log.info(runningCollaborators.toString()) } catch (Exception e) { diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy index 9343f59e81..aa4a9a890f 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy @@ -1,11 +1,15 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic +import groovy.transform.PackageScope import groovy.transform.ToString -import io.codearte.accurest.stubrunner.util.StubsParser /** * Technical options related to running StubRunner + * + * Use {@class StubRunnerOptionsBuilder} to build this object. + * + * @see StubRunnerOptionsBuilder */ @ToString(includeNames = true) @CompileStatic @@ -14,77 +18,53 @@ class StubRunnerOptions { /** * min port value of the WireMock instance for the given collaborator */ - Integer minPortValue = 10000 + final Integer minPortValue /** * max port value of the WireMock instance for the given collaborator */ - Integer maxPortValue = 15000 + final Integer maxPortValue /** * root URL from where the JAR with stub mappings will be downloaded */ - String stubRepositoryRoot + final String stubRepositoryRoot /** * avoids local repository in dependency resolution */ - boolean workOffline = false + final boolean workOffline + + /** + * stub definition classifier + */ + final String stubsClassifier + + final Collection dependencies /** * colon separated list of ids to the desired port */ - Map stubIdsToPortMapping = [:] - - /** - * stub definition suffix - */ - String stubsClassifier = "stubs" + final Map stubIdsToPortMapping + @PackageScope StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, - boolean workOffline, String stubsClassifier, String stubIdsToPortMapping) { + boolean workOffline, String stubsClassifier, Collection dependencies, Map stubIdsToPortMapping) { this.minPortValue = minPortValue this.maxPortValue = maxPortValue this.stubRepositoryRoot = stubRepositoryRoot this.workOffline = workOffline this.stubsClassifier = stubsClassifier - this.stubIdsToPortMapping = stubIdsWithPortsFromString(stubIdsToPortMapping) - } - - StubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, - boolean workOffline, String stubsClassifier) { - this.minPortValue = minPortValue - this.maxPortValue = maxPortValue - this.stubRepositoryRoot = stubRepositoryRoot - this.workOffline = workOffline - this.stubsClassifier = stubsClassifier - } - - StubRunnerOptions(String stubRepositoryRoot) { - this.stubRepositoryRoot = stubRepositoryRoot - } - - StubRunnerOptions() {} - - Map stubIdsWithPortsFromString(String stubIdsToPortMapping) { - return stubIdsToPortMapping.split(',').collectEntries { String entry -> - return StubsParser.fromStringWithPort(entry) - } - } - - Integer port(StubConfiguration stubConfiguration) { - return stubIdsToPortMapping[stubConfiguration] - } - - void setStubIdsToPortMapping(Map stubIdsToPortMapping) { + this.dependencies = dependencies this.stubIdsToPortMapping = stubIdsToPortMapping } - void putStubIdsToPortMapping(Map stubIdsToPortMapping) { - this.stubIdsToPortMapping.putAll(stubIdsToPortMapping) + Integer port(StubConfiguration stubConfiguration) { + if (stubIdsToPortMapping) { + return stubIdsToPortMapping[stubConfiguration] + } else { + return null + } } - void setStubIdsToPortMapping(String stubIdsToPortMapping) { - this.stubIdsToPortMapping = stubIdsWithPortsFromString(stubIdsToPortMapping) - } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy new file mode 100644 index 0000000000..594bec0681 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy @@ -0,0 +1,118 @@ +package io.codearte.accurest.stubrunner + +import groovy.transform.CompileStatic +import io.codearte.accurest.stubrunner.util.StubsParser + +@CompileStatic +class StubRunnerOptionsBuilder { + private static final String DELIMITER = ":"; + private LinkedList stubs = new LinkedList<>() + private Map stubIdsToPortMapping = [:] + + private Integer minPortValue = 10000 + private Integer maxPortValue = 15000 + private String stubRepositoryRoot + private boolean workOffline = false + private String stubsClassifier = "stubs" + + StubRunnerOptionsBuilder() { + } + + StubRunnerOptionsBuilder(StubRunnerOptions options) { + withOptions(options) + } + + StubRunnerOptionsBuilder withStubs(String stubs) { + addStub(stubsToList(stubs)) + return this + } + + StubRunnerOptionsBuilder withStubs(List stubs) { + for (String stub : stubs) { + withStubs(stub); + } + return this + } + + StubRunnerOptionsBuilder withMinMaxPort(Integer minPortValue, Integer maxPortValue) { + this.minPortValue = minPortValue + this.maxPortValue = maxPortValue + return this + } + + StubRunnerOptionsBuilder withMinPort(int minPortValue) { + this.minPortValue = minPortValue + return this + } + + StubRunnerOptionsBuilder withMaxPort(int maxPortValue) { + this.maxPortValue = maxPortValue + return this + } + + StubRunnerOptionsBuilder withStubRepositoryRoot(String stubRepositoryRoot) { + this.stubRepositoryRoot = stubRepositoryRoot + return this + } + + StubRunnerOptionsBuilder withWorkOffline(boolean workOffline) { + this.workOffline = workOffline + return this + } + + StubRunnerOptionsBuilder withStubsClassifier(String stubsClassifier) { + this.stubsClassifier = stubsClassifier + return this + } + + StubRunnerOptionsBuilder withPort(Integer port) { + String lastStub = stubs.peekLast(); + println "PORT $lastStub -> $port" + addPort(lastStub + DELIMITER + port); + return this; + } + + StubRunnerOptions build() { + return new StubRunnerOptions(minPortValue, maxPortValue, stubRepositoryRoot, workOffline, stubsClassifier, buildDependencies(), stubIdsToPortMapping) + } + + void withOptions(StubRunnerOptions options) { + this.minPortValue = options.minPortValue + this.maxPortValue = options.maxPortValue + this.stubRepositoryRoot = options.stubRepositoryRoot + this.workOffline = options.workOffline + this.stubsClassifier = options.stubsClassifier + } + + private Collection buildDependencies() { + return StubsParser.fromString(stubs, stubsClassifier); + } + + private static List stubsToList(String stubIdsToPortMapping) { + return stubIdsToPortMapping.split(',').collect { it } + } + + private void addStub(List notations) { + for (String notation : notations) { + addStub(notation); + } + } + + private void addStub(String notation) { + if (StubsParser.hasPort(notation)) { + addPort(notation); + stubs.add(StubsParser.ivyFromStringWithPort(notation)); + } else { + stubs.add(notation); + } + } + + private void addPort(String notation) { + putStubIdsToPortMapping(StubsParser.fromStringWithPort(notation)); + } + + private void putStubIdsToPortMapping(Map stubIdsToPortMapping) { + this.stubIdsToPortMapping.putAll(stubIdsToPortMapping) + } + +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy index 25add46ece..a90447dce9 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy @@ -1,5 +1,6 @@ package io.codearte.accurest.stubrunner +import io.codearte.accurest.stubrunner.util.StubsParser import spock.lang.Specification class StubRunnerExecutorSpec extends Specification { @@ -10,7 +11,7 @@ class StubRunnerExecutorSpec extends Specification { private AvailablePortScanner portScanner private StubRepository repository private StubConfiguration stub = new StubConfiguration("group:artifact", "stubs") - private StubRunnerOptions stubRunnerOptions = new StubRunnerOptions() + private StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder().build() def setup() { portScanner = new AvailablePortScanner(MIN_PORT, MAX_PORT) @@ -46,11 +47,18 @@ class StubRunnerExecutorSpec extends Specification { def 'should start a stub on a given port'() { given: StubRunnerExecutor executor = new StubRunnerExecutor(portScanner) - stubRunnerOptions.setStubIdsToPortMapping('group:artifact:12345,someotherartifact:123') + stubRunnerOptions = new StubRunnerOptionsBuilder(stubIdsToPortMapping: stubIdsWithPortsFromString('group:artifact:12345,someotherartifact:123')) + .build() when: executor.runStubs(stubRunnerOptions, repository, stub) then: executor.findStubUrl("group", "artifact") == 'http://localhost:12345'.toURL() } + Map stubIdsWithPortsFromString(String stubIdsToPortMapping) { + return stubIdsToPortMapping.split(',').collectEntries { String entry -> + return StubsParser.fromStringWithPort(entry) + } + } + } diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy index 19481ce7e0..71d5e90f3b 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy @@ -10,17 +10,23 @@ class StubRunnerFactorySpec extends Specification { @Rule TemporaryFolder folder = new TemporaryFolder() - Collection collaborators = [new StubConfiguration("a:b"), new StubConfiguration("c:d")] + String stubs = "a:b,c:d" StubDownloader downloader = Mock(StubDownloader) - StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(stubRepositoryRoot: 'http://sth.net') - StubRunnerFactory factory = new StubRunnerFactory(stubRunnerOptions, collaborators, downloader, new NoOpAccurestMessaging()) + StubRunnerOptions stubRunnerOptions + StubRunnerFactory factory + + void setup() { + stubRunnerOptions = new StubRunnerOptionsBuilder() + .withStubRepositoryRoot(folder.root.absolutePath) // FIXME: not used + .withStubs(stubs).build() + factory = new StubRunnerFactory(stubRunnerOptions, downloader, new NoOpAccurestMessaging()) + } def "Should download stub definitions many times"() { given: folder.newFolder("mappings") 1 * downloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(new StubConfiguration('a:b'), folder.root) 1 * downloader.downloadAndUnpackStubJar(_, _) >> new AbstractMap.SimpleEntry(new StubConfiguration('c:d'), folder.root) - stubRunnerOptions.stubRepositoryRoot = folder.root.absolutePath when: Collection stubRunners = collectOnlyPresentValues(factory.createStubsFromServiceConfiguration()) then: diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy index 6735785f70..f67ad211fa 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy @@ -32,7 +32,7 @@ class StubRunnerSpec extends Specification { Arguments argumentsWithProjectDefinition() { StubConfiguration stubConfiguration = new StubConfiguration("groupId", "artifactId", "classifier") - StubRunnerOptions stubRunnerOptions = new StubRunnerOptions(minPortValue: MIN_PORT, maxPortValue: MAX_PORT) + StubRunnerOptions stubRunnerOptions = new StubRunnerOptionsBuilder().withMinMaxPort(MIN_PORT, MAX_PORT).build() return new Arguments(stubRunnerOptions, 'src/test/resources/repository', stubConfiguration) } From 02512534c6b6d08e461eed2c7267d9935fbb8f56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Sun, 1 May 2016 19:54:37 +0200 Subject: [PATCH 630/719] missing tests (#260) --- .../StubRunnerOptionsBuilder.groovy | 41 +++++------ .../StubRunnerOptionsBuilderSpec.groovy | 68 +++++++++++++++++++ 2 files changed, 89 insertions(+), 20 deletions(-) create mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilderSpec.groovy diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy index 594bec0681..903b21c789 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy @@ -5,7 +5,7 @@ import io.codearte.accurest.stubrunner.util.StubsParser @CompileStatic class StubRunnerOptionsBuilder { - private static final String DELIMITER = ":"; + private static final String DELIMITER = ':' private LinkedList stubs = new LinkedList<>() private Map stubIdsToPortMapping = [:] @@ -13,7 +13,7 @@ class StubRunnerOptionsBuilder { private Integer maxPortValue = 15000 private String stubRepositoryRoot private boolean workOffline = false - private String stubsClassifier = "stubs" + private String stubsClassifier = 'stubs' StubRunnerOptionsBuilder() { } @@ -29,7 +29,7 @@ class StubRunnerOptionsBuilder { StubRunnerOptionsBuilder withStubs(List stubs) { for (String stub : stubs) { - withStubs(stub); + withStubs(stub) } return this } @@ -66,26 +66,27 @@ class StubRunnerOptionsBuilder { } StubRunnerOptionsBuilder withPort(Integer port) { - String lastStub = stubs.peekLast(); + String lastStub = stubs.peekLast() println "PORT $lastStub -> $port" - addPort(lastStub + DELIMITER + port); - return this; + addPort(lastStub + DELIMITER + port) + return this + } + + StubRunnerOptionsBuilder withOptions(StubRunnerOptions options) { + this.minPortValue = options.minPortValue + this.maxPortValue = options.maxPortValue + this.stubRepositoryRoot = options.stubRepositoryRoot + this.workOffline = options.workOffline + this.stubsClassifier = options.stubsClassifier + return this } StubRunnerOptions build() { return new StubRunnerOptions(minPortValue, maxPortValue, stubRepositoryRoot, workOffline, stubsClassifier, buildDependencies(), stubIdsToPortMapping) } - void withOptions(StubRunnerOptions options) { - this.minPortValue = options.minPortValue - this.maxPortValue = options.maxPortValue - this.stubRepositoryRoot = options.stubRepositoryRoot - this.workOffline = options.workOffline - this.stubsClassifier = options.stubsClassifier - } - private Collection buildDependencies() { - return StubsParser.fromString(stubs, stubsClassifier); + return StubsParser.fromString(stubs, stubsClassifier) } private static List stubsToList(String stubIdsToPortMapping) { @@ -94,21 +95,21 @@ class StubRunnerOptionsBuilder { private void addStub(List notations) { for (String notation : notations) { - addStub(notation); + addStub(notation) } } private void addStub(String notation) { if (StubsParser.hasPort(notation)) { - addPort(notation); - stubs.add(StubsParser.ivyFromStringWithPort(notation)); + addPort(notation) + stubs.add(StubsParser.ivyFromStringWithPort(notation)) } else { - stubs.add(notation); + stubs.add(notation) } } private void addPort(String notation) { - putStubIdsToPortMapping(StubsParser.fromStringWithPort(notation)); + putStubIdsToPortMapping(StubsParser.fromStringWithPort(notation)) } private void putStubIdsToPortMapping(Map stubIdsToPortMapping) { diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilderSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilderSpec.groovy new file mode 100644 index 0000000000..07de7cb30b --- /dev/null +++ b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilderSpec.groovy @@ -0,0 +1,68 @@ +package io.codearte.accurest.stubrunner + +import spock.lang.Specification + +class StubRunnerOptionsBuilderSpec extends Specification { + + private StubRunnerOptionsBuilder builder = new StubRunnerOptionsBuilder() + + def shouldCreateDependenciesForStub() { + + given: + builder.withStubs('foo:bar') + + when: + StubRunnerOptions options = builder.build() + + then: + options.getDependencies().toString() == '[foo:bar:+:stubs]' + } + + def shouldCreateDependenciesForCommaSeparatedStubs() { + + given: + builder.withStubs('foo:bar,bar:foo') + + when: + StubRunnerOptions options = builder.build() + + then: + options.getDependencies().size() == 2 + } + + def shouldMapStubsWithPort() { + + given: + builder.withStubs('foo:bar:8080') + + when: + StubRunnerOptions options = builder.build() + + then: + options.getStubIdsToPortMapping().toString() == '[foo:bar:+:stubs:8080]' + } + + def shouldCreateDependenciesWithVersion() { + + given: + builder.withStubs('foo:1.2.3:bar') + + when: + StubRunnerOptions options = builder.build() + + then: + options.getDependencies().toString() == '[foo:1.2.3:bar:stubs]' + } + + def shouldCreateDependenciesWithClassifier() { + + given: + builder.withStubs('foo:bar').withStubsClassifier('xxx') + + when: + StubRunnerOptions options = builder.build() + + then: + options.getDependencies().toString() == '[foo:bar:+:xxx]' + } +} From be511a7bdb1d1960f722d710498fb1bc03442bee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Zaj=C4=85czkowski?= Date: Sun, 1 May 2016 21:46:58 +0200 Subject: [PATCH 631/719] Enhance CD bot commit message (#23) [ci skip] --- pom.xml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ecd22c9478..84fc4230ac 100644 --- a/pom.xml +++ b/pom.xml @@ -543,10 +543,9 @@ connection pom.xml - Sets project version to - ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT. + Sets project version to ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT - [ci skip] +[ci skip] From c09a6fa0d87dadaa0866066e30fde2cf74b5e8cc Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 2 May 2016 18:56:19 +0200 Subject: [PATCH 632/719] Refactored the conversion from String / File to Groovy DSL --- .../wiremock/DslToWireMockConverter.groovy | 4 +-- .../WireMockToDslConverterSpec.groovy | 23 ++++++++-------- .../accurest/SingleTestGenerator.groovy | 4 +-- .../accurest/file/ContractFileScanner.groovy | 4 +-- .../accurest/util/AccurestDslConverter.groovy | 26 +++++++++++++++++++ .../accurest/stubrunner/StubRepository.groovy | 6 ++--- 6 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/AccurestDslConverter.groovy 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 89b2b381ce..0279bbcebe 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 @@ -2,7 +2,7 @@ package io.codearte.accurest.wiremock import groovy.transform.CompileStatic import io.codearte.accurest.dsl.GroovyDsl -import org.codehaus.groovy.control.CompilerConfiguration +import io.codearte.accurest.util.AccurestDslConverter @CompileStatic abstract class DslToWireMockConverter implements SingleFileConverter { @@ -18,6 +18,6 @@ abstract class DslToWireMockConverter implements SingleFileConverter { } protected GroovyDsl createGroovyDSLfromStringContent(String groovyDslAsString) { - return (GroovyDsl) new GroovyShell(this.class.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate("$groovyDslAsString") + return AccurestDslConverter.convert(groovyDslAsString) } } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy index 80e8592276..5e71f81605 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy +++ b/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy @@ -2,6 +2,7 @@ package io.codearte.accurest.wiremock import com.github.tomakehurst.wiremock.stubbing.StubMapping import io.codearte.accurest.dsl.GroovyDsl +import io.codearte.accurest.util.AccurestDslConverter import spock.lang.Specification class WireMockToDslConverterSpec extends Specification { @@ -67,7 +68,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - new GroovyShell(this.class.classLoader).evaluate( + AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl @@ -121,7 +122,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - new GroovyShell(this.class.classLoader).evaluate( + AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl @@ -172,7 +173,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - new GroovyShell(this.class.classLoader).evaluate( + AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl @@ -226,7 +227,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - new GroovyShell(this.class.classLoader).evaluate( + AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl @@ -291,7 +292,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - new GroovyShell(this.class.classLoader).evaluate( + AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") == expectedGroovyDsl @@ -329,7 +330,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") @@ -369,7 +370,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") @@ -410,7 +411,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") @@ -450,7 +451,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") @@ -490,7 +491,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") @@ -528,7 +529,7 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = new GroovyShell(this.class.classLoader).evaluate( + GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( """ io.codearte.accurest.dsl.GroovyDsl.make { $groovyDsl }""") diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy index 678331c5eb..ee8a8e64b1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy @@ -10,7 +10,7 @@ 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 io.codearte.accurest.util.AccurestDslConverter import static io.codearte.accurest.builder.ClassBuilder.createClass import static io.codearte.accurest.builder.MethodBuilder.createTestMethod @@ -58,7 +58,7 @@ class SingleTestGenerator { Map 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) + GroovyDsl stubContent = AccurestDslConverter.convert(stubsFile) TestType testType = (stubContent.input || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP return [(new ParsedDsl(it, stubContent, stubsFile)) : testType] } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy index 5e125f0f31..cc00799c08 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy @@ -68,7 +68,7 @@ class ContractFileScanner { } private boolean hasScenarioFilenamePattern(Path path) { - SCENARIO_STEP_FILENAME_PATTERN.matcher(path.fileName.toString()).matches() + return SCENARIO_STEP_FILENAME_PATTERN.matcher(path.fileName.toString()).matches() } boolean matchesPattern(File file, Set excludeMatchers) { @@ -81,6 +81,6 @@ class ContractFileScanner { } private boolean isContractFile(File file) { - file.isFile() && FilenameUtils.getExtension(file.toString()).equalsIgnoreCase("groovy") + return file.isFile() && FilenameUtils.getExtension(file.toString()).equalsIgnoreCase("groovy") } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/AccurestDslConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/AccurestDslConverter.groovy new file mode 100644 index 0000000000..5f865ba24b --- /dev/null +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/AccurestDslConverter.groovy @@ -0,0 +1,26 @@ +package io.codearte.accurest.util + +import groovy.transform.CompileStatic +import io.codearte.accurest.dsl.GroovyDsl +import org.codehaus.groovy.control.CompilerConfiguration + +/** + * Converts to Groovy DSL + * + * @author Marcin Grzejszczak + */ +@CompileStatic +class AccurestDslConverter { + + static GroovyDsl convert(String dsl) { + return groovyShell().evaluate(dsl) as GroovyDsl + } + + static GroovyDsl convert(File dsl) { + return groovyShell().evaluate(dsl) as GroovyDsl + } + + private static GroovyShell groovyShell() { + return new GroovyShell(AccurestDslConverter.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding: 'UTF-8')) + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy index 49a06075be..78527dbd6c 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy @@ -4,8 +4,7 @@ import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j import io.codearte.accurest.dsl.GroovyDsl -import org.codehaus.groovy.control.CompilerConfiguration - +import io.codearte.accurest.util.AccurestDslConverter /** * Wraps the folder with WireMock mappings. */ @@ -68,8 +67,7 @@ class StubRepository { descriptorsDirectory.eachFileRecurse { File file -> if (isAccurestDescriptor(file)) { try { - mappingDescriptors << - ((new GroovyShell(delegate.class.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding:'UTF-8')).evaluate(file)) as GroovyDsl) + mappingDescriptors << AccurestDslConverter.convert(file) } catch (Exception e) { log.warn("Exception occurred while trying to parse file [$file]", e) } From 9756eacd099a56334bd44194d6cf3ad82acf358a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 3 May 2016 16:26:51 +0200 Subject: [PATCH 633/719] Added samples to the docs --- docs/src/docs/asciidoc/introduction.adoc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/docs/asciidoc/introduction.adoc index d43ce58b18..08f45e5fa9 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/docs/asciidoc/introduction.adoc @@ -122,3 +122,7 @@ video::130779882[vimeo] - http://www.slideshare.net/MarcinGrzejszczak/stick-to-the-rules-consumer-driven-contracts-201507-confitura[Slides from Marcin Grzejszczak's talk about Accurest] - http://toomuchcoding.com/blog/categories/accurest/[Accurest related articles from Marcin Grzejszczak's blog] + +=== Samples + +Here you can find some https://github.com/Codearte/accurest-samples[working samples]. Check the readme of each project for more information. \ No newline at end of file From 8015f11345e71fdf81bf936f8ac3978d3d5980f8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 3 May 2016 17:03:03 +0200 Subject: [PATCH 634/719] Changed default accurest contracts location /src/test/accurest -> /src/test/resources/accurest that way the contracts will be on the classpath if we need them --- .../plugin/AccurestGradlePlugin.groovy | 2 +- docs/src/docs/asciidoc/rest.adoc | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) 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 1ad75e1ba1..658f63bb30 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 @@ -54,7 +54,7 @@ class AccurestGradlePlugin implements Plugin { } private File defaultAccurestContractsDir() { - project.file("${project.rootDir}/src/test/accurest") + project.file("${project.rootDir}/src/test/resources/accurest") } private void createGenerateTestsTask(AccurestConfigProperties extension) { diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index 1dc0eda965..b956e77f29 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -53,7 +53,7 @@ Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugi ===== Add stubs -By default Accurest is looking for stubs in `src/test/accurest` directory. +By default Accurest is looking for stubs in `src/test/resources/accurest` 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. @@ -61,8 +61,8 @@ So with following structure [source,groovy,indent=0] ---- -src/test/accurest/myservice/shouldCreateUser.groovy -src/test/accurest/myservice/shouldReturnUser.groovy +src/test/resources/accurest/myservice/shouldCreateUser.groovy +src/test/resources/accurest/myservice/shouldReturnUser.groovy ---- Accurest will create test class `defaultBasePackage.MyService` with two methods @@ -96,7 +96,7 @@ accurest { - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` if using Spock tests. - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - **ignoredFiles** - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array [] - - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/accurest` + - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/resources/accurest` - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `$buildDir/generated-test-sources/accurest` - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with JUnit being the default framework @@ -125,7 +125,7 @@ To ensure that provider side is complaint with defined contracts, you need to in ==== Accurest on consumer side In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. If you don't want to use Stub Runner then you need to copy contracts stored in -`src/test/accurest` and generate WireMock json stubs using: +`src/test/resources/accurest` and generate WireMock json stubs using: [source,bash,indent=0] ---- @@ -188,15 +188,15 @@ Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugi ==== Add stubs -By default Accurest is looking for stubs in `src/test/accurest` directory. +By default Accurest is looking for stubs in `src/test/resources/accurest` 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 [source,groovy,indent=0] ---- -src/test/accurest/myservice/shouldCreateUser.groovy -src/test/accurest/myservice/shouldReturnUser.groovy +src/test/resources/accurest/myservice/shouldCreateUser.groovy +src/test/resources/accurest/myservice/shouldReturnUser.groovy ---- Accurest will create test class `defaultBasePackage.MyService` with two methods @@ -238,7 +238,7 @@ To change default configuration just add `configuration` section to plugin defin - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` if using Spock tests. - - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/accurest`. + - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/resources/accurest`. - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework For complete information take a look at http://codearte.github.io/accurest-maven-plugin/plugin-info.html[Plugin Documentation] @@ -306,7 +306,7 @@ To ensure that provider side is complaint with defined contracts, you need to in ==== Accurest on consumer side -In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. +In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/resources/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. Sample configuration: From d2830f5265d520e6b8094f6932ab0c785d640435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 3 May 2016 20:11:21 +0200 Subject: [PATCH 635/719] Fixes to accurest run command, changed default contracts directory and other small changes (#24) --- pom.xml | 26 ++--- .../accurest/maven/ConvertMojo.groovy | 92 ------------------ .../accurest/maven/CopyContracts.groovy | 47 +++++++++ .../accurest/maven/GenerateTestsMojo.groovy | 2 +- .../io/codearte/accurest/maven/RunMojo.groovy | 11 +-- .../ConvertMojo.java | 95 +++++++++++++++++++ .../{ => resources}/accurest/Messaging.groovy | 0 .../{ => resources}/accurest/Sample.groovy | 0 .../projects/complex-configuration/pom.xml | 1 + .../accurest/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../accurest/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../accurest/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 15 files changed, 164 insertions(+), 110 deletions(-) delete mode 100644 src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy create mode 100644 src/main/groovy/io/codearte/accurest/maven/CopyContracts.groovy create mode 100644 src/main/java/io.codearte.accurest.maven/ConvertMojo.java rename src/test/projects/basic/src/test/{ => resources}/accurest/Messaging.groovy (100%) rename src/test/projects/basic/src/test/{ => resources}/accurest/Sample.groovy (100%) rename src/test/projects/plugin-extension/src/test/{ => resources}/accurest/greetings_ok.groovy (100%) rename src/test/projects/plugin-extension/src/test/{ => resources}/accurest/greetings_with_default_value.groovy (100%) rename src/test/projects/spring-boot-groovy/src/test/{ => resources}/accurest/greetings_ok.groovy (100%) rename src/test/projects/spring-boot-groovy/src/test/{ => resources}/accurest/greetings_with_default_value.groovy (100%) rename src/test/projects/spring-boot-java/src/test/{ => resources}/accurest/greetings_ok.groovy (100%) rename src/test/projects/spring-boot-java/src/test/{ => resources}/accurest/greetings_with_default_value.groovy (100%) diff --git a/pom.xml b/pom.xml index 84fc4230ac..81dc775bd0 100644 --- a/pom.xml +++ b/pom.xml @@ -30,14 +30,14 @@ - 3.2.5 - 3.4 + 3.2.5 + 3.4 UTF-8 UTF-8 - 1.1.0-M4 - 1.1.0 + 1.1.0-M4 + 1.1.0 1.7 1.7 @@ -95,7 +95,10 @@ + addSources + generateStubs compile + removeStubs @@ -115,7 +118,7 @@ maven-plugin-plugin - ${mavenPluginPluginVersion} + ${maven.plugin.plugin.version} true @@ -285,7 +288,7 @@ org.eclipse.aether aether-api - ${aetherVersion} + ${aether.version} provided @@ -321,14 +324,14 @@ org.apache.maven maven-core - ${mavenVersion} + ${maven.version} provided org.apache.maven maven-plugin-api - ${mavenVersion} + ${maven.version} provided @@ -348,7 +351,7 @@ org.apache.maven.plugin-tools maven-plugin-annotations - ${mavenPluginPluginVersion} + ${maven.plugin.plugin.version} provided @@ -379,7 +382,7 @@ org.apache.maven maven-compat - ${mavenVersion} + ${maven.version} test @@ -392,6 +395,7 @@ org.assertj assertj-core 2.4.0 + test @@ -400,7 +404,7 @@ maven-plugin-plugin - ${mavenPluginPluginVersion} + ${maven.plugin.plugin.version} org.apache.maven.plugins diff --git a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy deleted file mode 100644 index 0b245842af..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/ConvertMojo.groovy +++ /dev/null @@ -1,92 +0,0 @@ -package io.codearte.accurest.maven - -import groovy.transform.CompileStatic -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.wiremock.DslToWireMockClientConverter -import io.codearte.accurest.wiremock.RecursiveFilesConverter -import org.apache.maven.execution.MavenSession -import org.apache.maven.model.Resource -import org.apache.maven.plugin.AbstractMojo -import org.apache.maven.plugin.MojoExecutionException -import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.Component -import org.apache.maven.plugins.annotations.LifecyclePhase -import org.apache.maven.plugins.annotations.Mojo -import org.apache.maven.plugins.annotations.Parameter -import org.apache.maven.project.MavenProject -import org.apache.maven.shared.filtering.MavenFilteringException -import org.apache.maven.shared.filtering.MavenResourcesExecution -import org.apache.maven.shared.filtering.MavenResourcesFiltering - -@Mojo(name = 'convert', requiresProject = false, defaultPhase = LifecyclePhase.PROCESS_TEST_RESOURCES) -@CompileStatic -class ConvertMojo extends AbstractMojo { - - @Parameter(defaultValue = '${basedir}/src/test/accurest') - private File contractsDirectory - - @Parameter(defaultValue = '${project.build.directory}/accurest') - private File outputDirectory - - @Parameter(property = 'contractsDirectory', defaultValue = '${basedir}') - private File source - - @Parameter(property = 'stubsDirectory', defaultValue = '${basedir}') - private File destination - - @Parameter(property = 'accurest.skip', defaultValue = 'false') - private boolean skip - - @Parameter(defaultValue = '${session}', readonly = true) - private MavenSession mavenSession - - @Parameter(defaultValue = '${project}', readonly = true) - private MavenProject project - - @Component(role = MavenResourcesFiltering.class, hint = "default") - private MavenResourcesFiltering mavenResourcesFiltering; - - void execute() throws MojoExecutionException, MojoFailureException { - - if (skip) { - log.info("Skipping accurest execution: accurest.skip=${skip}") - return - } - - copyContracts() - - AccurestConfigProperties config = new AccurestConfigProperties() - config.contractsDslDir = insideProject ? contractsDirectory : source - config.stubsOutputDir = insideProject ? new File(outputDirectory, 'mappings') : destination - - log.info('Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings') - log.info(" Accurest contracts directory: ${config.contractsDslDir}") - log.info("WireMock stubs mappings directory: ${config.stubsOutputDir}") - - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config) - converter.processFiles() - } - - private void copyContracts() { - log.info("Copying accurest contracts") - Resource testResource = new Resource(directory: contractsDirectory.absolutePath) - MavenResourcesExecution mavenResourcesExecution = - new MavenResourcesExecution([testResource], - new File(outputDirectory, 'accurest'), project, 'UTF-8', [], [], mavenSession); - mavenResourcesExecution.injectProjectBuildFilters = false - mavenResourcesExecution.overwrite = true - mavenResourcesExecution.includeEmptyDirs = false - mavenResourcesExecution.filterFilenames = false - try { - mavenResourcesFiltering.filterResources(mavenResourcesExecution); - } catch (MavenFilteringException e) { - throw new MojoExecutionException(e.getMessage(), e); - } - } - - private boolean isInsideProject() { - return mavenSession.request.projectPresent - } - - -} diff --git a/src/main/groovy/io/codearte/accurest/maven/CopyContracts.groovy b/src/main/groovy/io/codearte/accurest/maven/CopyContracts.groovy new file mode 100644 index 0000000000..4a5894b65e --- /dev/null +++ b/src/main/groovy/io/codearte/accurest/maven/CopyContracts.groovy @@ -0,0 +1,47 @@ +package io.codearte.accurest.maven + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import org.apache.maven.execution.MavenSession +import org.apache.maven.model.Resource +import org.apache.maven.plugin.MojoExecutionException +import org.apache.maven.project.MavenProject +import org.apache.maven.shared.filtering.MavenFilteringException +import org.apache.maven.shared.filtering.MavenResourcesExecution +import org.apache.maven.shared.filtering.MavenResourcesFiltering + +@CompileStatic +@Slf4j +class CopyContracts { + + private final MavenProject project + private final MavenSession mavenSession + private final MavenResourcesFiltering mavenResourcesFiltering + + CopyContracts(MavenProject project, MavenSession mavenSession, MavenResourcesFiltering mavenResourcesFiltering) { + this.project = project + this.mavenSession = mavenSession + this.mavenResourcesFiltering = mavenResourcesFiltering + } + + void copy(File contractsDirectory, File outputDirectory) { + log.info('Copying accurest contracts') + Resource testResource = new Resource(directory: contractsDirectory.absolutePath) + MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution( + resources: [testResource], + outputDirectory: new File(outputDirectory, 'accurest'), + mavenProject: project, + encoding: 'UTF-8', + mavenSession: mavenSession); + mavenResourcesExecution.injectProjectBuildFilters = false + mavenResourcesExecution.overwrite = true + mavenResourcesExecution.includeEmptyDirs = false + mavenResourcesExecution.filterFilenames = false + try { + mavenResourcesFiltering.filterResources(mavenResourcesExecution); + } catch (MavenFilteringException e) { + throw new MojoExecutionException(e.getMessage(), e); + } + } + +} diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy index c68bdc32c2..85557b228c 100644 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy @@ -21,7 +21,7 @@ import static java.lang.String.format @CompileStatic class GenerateTestsMojo extends AbstractMojo { - @Parameter(property = 'accurest.contractsDirectory', defaultValue = '${project.basedir}/src/test/accurest') + @Parameter(property = 'accurest.contractsDirectory', defaultValue = '${project.basedir}/src/test/resources/accurest') private File contractsDirectory @Parameter(defaultValue = '${project.build.directory}/generated-test-sources/accurest') diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index 74c6b23ccd..b644319285 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -67,7 +67,7 @@ class RunMojo extends AbstractMojo { } BatchStubRunner batchStubRunner if (!stubs) { - StubRunnerOptions options = new StubRunnerOptions(httpPort, httpPort + 1, "", false, stubsClassifier) + StubRunnerOptions options = new StubRunnerOptions(httpPort, httpPort, "", false, stubsClassifier) StubRunner stubRunner = localStubRunner.run(resolveStubsDirectory().absolutePath, options) batchStubRunner = new BatchStubRunner(Arrays.asList(stubRunner)) } else { @@ -77,11 +77,10 @@ class RunMojo extends AbstractMojo { batchStubRunner = remoteStubRunner.run(options, repoSession) } - if (!insideProject) { - pressAnyKeyToContinue() - if (batchStubRunner) { - batchStubRunner.close() - } + pressAnyKeyToContinue() + + if (batchStubRunner) { + batchStubRunner.close() } } diff --git a/src/main/java/io.codearte.accurest.maven/ConvertMojo.java b/src/main/java/io.codearte.accurest.maven/ConvertMojo.java new file mode 100644 index 0000000000..c1646cc12a --- /dev/null +++ b/src/main/java/io.codearte.accurest.maven/ConvertMojo.java @@ -0,0 +1,95 @@ +package io.codearte.accurest.maven; + +import groovy.transform.CompileStatic; +import io.codearte.accurest.config.AccurestConfigProperties; +import io.codearte.accurest.wiremock.DslToWireMockClientConverter; +import io.codearte.accurest.wiremock.RecursiveFilesConverter; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.Resource; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.*; +import org.apache.maven.project.MavenProject; +import org.apache.maven.shared.filtering.MavenFilteringException; +import org.apache.maven.shared.filtering.MavenResourcesExecution; +import org.apache.maven.shared.filtering.MavenResourcesFiltering; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; + +/** + * + * Convert Accurest contracts into WireMock stubs mappings. + * + * This goal allow to generate `stubs-jar` or execute `accurest:run` with generated WireMock mappings. + * + */ +@Mojo(name = "convert", requiresProject = false, defaultPhase = LifecyclePhase.PROCESS_TEST_RESOURCES) +@CompileStatic +public class ConvertMojo extends AbstractMojo { + + /** + * Directory containing Accurest contracts written using the GroovyDSL + */ + @Parameter(defaultValue = "${basedir}/src/test/resources/accurest") + private File contractsDirectory; + + /** + * Directory where the generated WireMock stubs from Groovy DSL should be placed. + * You can then mention them in your packaging task to create jar with stubs + */ + @Parameter(defaultValue = "${project.build.directory}/accurest") + private File outputDirectory; + + /** + * Directory containing contracts written using the GroovyDSL + * + * This parameter is only used when goal is executed outside of maven project. + */ + @Parameter(property = "contractsDirectory", defaultValue = "${basedir}") + private File source; + + @Parameter(property = "stubsDirectory", defaultValue = "${basedir}") + private File destination; + + @Parameter(property = "accurest.skip", defaultValue = "false") + private boolean skip; + + @Parameter(defaultValue = "${session}", readonly = true) + private MavenSession mavenSession; + + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject project; + + @Component(role = MavenResourcesFiltering.class, hint = "default") + private MavenResourcesFiltering mavenResourcesFiltering; + + public void execute() throws MojoExecutionException, MojoFailureException { + + if (skip) { + getLog().info(String.format("Skipping accurest execution: accurest.skip=%s", skip)); + return; + } + + new CopyContracts(project, mavenSession, mavenResourcesFiltering).copy(contractsDirectory, outputDirectory); + + final AccurestConfigProperties config = new AccurestConfigProperties(); + config.setContractsDslDir(isInsideProject() ? contractsDirectory : source); + config.setStubsOutputDir(isInsideProject() ? new File(outputDirectory, "mappings") : destination); + + getLog().info("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings"); + getLog().info(String.format(" Accurest contracts directory: %s", config.getContractsDslDir())); + getLog().info(String.format("WireMock stubs mappings directory: %s", config.getStubsOutputDir())); + + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); + converter.processFiles(); + } + + private boolean isInsideProject() { + return mavenSession.getRequest().isProjectPresent(); + } + + +} diff --git a/src/test/projects/basic/src/test/accurest/Messaging.groovy b/src/test/projects/basic/src/test/resources/accurest/Messaging.groovy similarity index 100% rename from src/test/projects/basic/src/test/accurest/Messaging.groovy rename to src/test/projects/basic/src/test/resources/accurest/Messaging.groovy diff --git a/src/test/projects/basic/src/test/accurest/Sample.groovy b/src/test/projects/basic/src/test/resources/accurest/Sample.groovy similarity index 100% rename from src/test/projects/basic/src/test/accurest/Sample.groovy rename to src/test/projects/basic/src/test/resources/accurest/Sample.groovy diff --git a/src/test/projects/complex-configuration/pom.xml b/src/test/projects/complex-configuration/pom.xml index 32eed3c57e..a96596d6df 100644 --- a/src/test/projects/complex-configuration/pom.xml +++ b/src/test/projects/complex-configuration/pom.xml @@ -81,6 +81,7 @@ generateTests + src/test/accurest com.blogspot.toomuchcoding.frauddetection MOCKMVC JUNIT diff --git a/src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy b/src/test/projects/plugin-extension/src/test/resources/accurest/greetings_ok.groovy similarity index 100% rename from src/test/projects/plugin-extension/src/test/accurest/greetings_ok.groovy rename to src/test/projects/plugin-extension/src/test/resources/accurest/greetings_ok.groovy diff --git a/src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy b/src/test/projects/plugin-extension/src/test/resources/accurest/greetings_with_default_value.groovy similarity index 100% rename from src/test/projects/plugin-extension/src/test/accurest/greetings_with_default_value.groovy rename to src/test/projects/plugin-extension/src/test/resources/accurest/greetings_with_default_value.groovy diff --git a/src/test/projects/spring-boot-groovy/src/test/accurest/greetings_ok.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_ok.groovy similarity index 100% rename from src/test/projects/spring-boot-groovy/src/test/accurest/greetings_ok.groovy rename to src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_ok.groovy diff --git a/src/test/projects/spring-boot-groovy/src/test/accurest/greetings_with_default_value.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_with_default_value.groovy similarity index 100% rename from src/test/projects/spring-boot-groovy/src/test/accurest/greetings_with_default_value.groovy rename to src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_with_default_value.groovy diff --git a/src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy b/src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_ok.groovy similarity index 100% rename from src/test/projects/spring-boot-java/src/test/accurest/greetings_ok.groovy rename to src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_ok.groovy diff --git a/src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy b/src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_with_default_value.groovy similarity index 100% rename from src/test/projects/spring-boot-java/src/test/accurest/greetings_with_default_value.groovy rename to src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_with_default_value.groovy From 169bbff3d377b8fa6cb845bb2f7acd6d187aecd7 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Tue, 3 May 2016 18:15:44 +0000 Subject: [PATCH 636/719] Sets project version to 0.6.7-SNAPSHOT [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 81dc775bd0..4a8dfec2f3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.6-SNAPSHOT + 0.6.7-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From 07e7664d0b13e755c94a982c7dd01c7257b806a0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 3 May 2016 21:25:00 +0200 Subject: [PATCH 637/719] Removed the unnecessary pringln --- stub-runner/stub-runner/build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index 6fa7593cd3..40d00f3308 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -61,7 +61,6 @@ run { } List parseArguments() { - println "Trying to parse the project arguments" List arguments = [] appendToListIfNotNull(stubRepositoryRoot, '-sr', arguments) appendToListIfNotNull(stubsSuffix, '-ss', arguments) From cf1bd5df331d477d619dfbc5c4ee42efeb5670d1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 3 May 2016 21:40:17 +0200 Subject: [PATCH 638/719] Added e2e for Accurest --- .travis.yml | 2 +- scripts/runTests.sh | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100755 scripts/runTests.sh diff --git a/.travis.yml b/.travis.yml index b51e928166..462f18b0e4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,4 @@ jdk: - oraclejdk8 install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --continue +script: ./gradlew clean check funcTest --stacktrace --continue && /.gradlew install --parallel && ./scripts/runTests.sh diff --git a/scripts/runTests.sh b/scripts/runTests.sh new file mode 100755 index 0000000000..4658a122d2 --- /dev/null +++ b/scripts/runTests.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash + +set -o errexit + +mkdir -p build +GRADLE_OUTPUT=`./gradlew cV --quiet` +ACCUREST_VERSION=`echo ${GRADLE_OUTPUT##*:}` +export ACCUREST_VERSION=${ACCUREST_VERSION} + +echo "Current accurest version is ${ACCUREST_VERSION}" + +cd build +echo "Cloning samples" +git clone https://github.com/Codearte/accurest-samples +cd accurest-samples + +echo "Running Gradle tests" +. ./runTests.sh + +echo "Running Maven tests" +. ./runMavenTests.sh From 998c9f2de60b41458e14036a786c92bd5481bec0 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 3 May 2016 22:35:05 +0200 Subject: [PATCH 639/719] Working with Travis --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 462f18b0e4..3b8813326f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,4 @@ jdk: - oraclejdk8 install: ./gradlew assemble -script: ./gradlew clean check funcTest --stacktrace --continue && /.gradlew install --parallel && ./scripts/runTests.sh +script: ./gradlew clean check funcTest install --stacktrace --continue && ./scripts/runTests.sh From b4ab8b06bf848002303c53cf455745116dcb1667 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 3 May 2016 23:15:24 +0200 Subject: [PATCH 640/719] Switching to JDK8 for tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3b8813326f..ad7126c071 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,4 +13,4 @@ jdk: - oraclejdk8 install: ./gradlew assemble -script: ./gradlew clean check funcTest install --stacktrace --continue && ./scripts/runTests.sh +script: ./gradlew clean check funcTest install --stacktrace --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh From 89ed40c547ce73b3abdc10451bc86425411abc35 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 4 May 2016 23:42:12 +0200 Subject: [PATCH 641/719] Updated docs for Stub Runner Spring Cloud fixes #264 --- stub-runner/stub-runner-spring-cloud/README.adoc | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/stub-runner/stub-runner-spring-cloud/README.adoc b/stub-runner/stub-runner-spring-cloud/README.adoc index d874c8f9d6..25e0ca4341 100644 --- a/stub-runner/stub-runner-spring-cloud/README.adoc +++ b/stub-runner/stub-runner-spring-cloud/README.adoc @@ -9,6 +9,17 @@ io.codearte.accurest:stub-runner-spring-cloud and the Stub Runner autoconfiguration should be picked up. +==== Stubbing Service Discovery + +The most important feature of `Stub Runner Spring Cloud` is the fact that it's stubbing + +- `DiscoveryClient` +- `Ribbon` `ServerList` + +that means that regardles of the fact whether you're using Zookeeper, Consul, Eureka or anything else, you don't need that in your tests. +We're starting WireMock instances of your dependencies and we're telling your application whenever you're using `Feign`, load balanced `RestTemplate` +or `DiscoveryClient` directly, to call those stubbed servers instead of calling the real Service Discovery tool. + ==== Additional Configuration You can match the artifactId of the stub with the name of your app by using the `stubrunner.stubs.idsToServiceIds:` map. From 4e95a90eed1470915a0cc12bb6a7e59a1845409d Mon Sep 17 00:00:00 2001 From: Jakub Kubrynski Date: Sat, 7 May 2016 22:50:36 +0200 Subject: [PATCH 642/719] Fix #262 - support maps in list --- .../DslToWireMockClientConverterSpec.groovy | 36 +++++++++++++++++++ .../dsl/BaseWireMockStubStrategy.groovy | 10 +++++- .../MockMvcMethodBodyBuilderSpec.groovy | 32 +++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) 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 2382878856..79632e7eb1 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 @@ -171,6 +171,42 @@ class DslToWireMockClientConverterSpec extends Specification { } ''', json, false) } + + + @Issue("262") + def "should create stub with map inside list"() { + given: + def converter = new DslToWireMockClientConverter() + and: + File file = tmpFolder.newFile("dsl-mapinlist.groovy") + file.write(""" + io.codearte.accurest.dsl.GroovyDsl.make { + request { + method 'GET' + urlPath '/foos' + } + response { + status 200 + body([[id: value( + client('123'), + server(regex('[0-9]+')) + )], [id: value( + client('567'), + server(regex('[0-9]+')) + )]]) + headers { + header 'Content-Type': 'application/json' + } + } + } +""") + when: + String json = converter.convertContent("test", new Contract(file.toPath(), false, 0, null)) + then: + JSONAssert.assertEquals(''' +{"request":{"urlPath":"/foos","method":"GET"},"response":{"body":"[{\\"id\\":\\"123\\"},{\\"id\\":\\"567\\"}]"}} +''', json, false) + } def 'should convert dsl to wiremock to show it in the docs'() { given: 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 index 985a7b8271..ac7376dc38 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy @@ -69,7 +69,15 @@ abstract class BaseWireMockStubStrategy { } public String parseBody(List list, ContentType contentType) { - return parseBody(toJson(list), contentType) + List result = [] + list.each { + if (it instanceof Map) { + result += MapConverter.getStubSideValues(it) + } else { + result += parseBody(it, contentType) + } + } + return parseBody(toJson(result), contentType) } public String parseBody(GString value, ContentType contentType) { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index 14ea6e61df..489fcfa298 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1168,6 +1168,38 @@ World.'''""" "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } + @Issue('262') + def "should generate proper test code with map inside list"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath '/foos' + } + response { + status 200 + body([[id: value( + client('123'), + server(regex('[0-9]+')) + )], [id: value( + client('567'), + server(regex('[0-9]+')) + )]]) + headers { + header('Content-Type': 'application/json;charset=UTF-8') + } + } + } + MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).array().contains("id").matches("[0-9]+")') + } + + GroovyDsl dslForDocs = // tag::dsl_example[] io.codearte.accurest.dsl.GroovyDsl.make { From 4c85a4bca80adcdf26d1fceb25f7dfcf33c9a485 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 8 May 2016 10:29:49 +0200 Subject: [PATCH 643/719] Added possibility to provide optional query param (#254) fixes #219 From 38cc614fc74aa1f6aa4d3ec9b5062b3c5d958bfd Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 8 May 2016 17:35:51 +0200 Subject: [PATCH 644/719] Fixed top level array issues (#267) Fixes #266 --- .../util/DelegatingJsonVerifiable.java | 4 ++- .../util/JsonToJsonPathsConverter.groovy | 5 +++ .../MockMvcMethodBodyBuilderSpec.groovy | 33 +++++++++++++++++++ .../util/JsonToJsonPathsConverterSpec.groovy | 15 ++++++--- gradle.properties | 2 +- 5 files changed, 52 insertions(+), 7 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index 3009f01207..3067c79049 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -90,7 +90,9 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { @Override public MethodBufferingJsonVerifiable arrayField() { - return new DelegatingJsonVerifiable(delegate.arrayField(), methodsBuffer); + DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.arrayField(), methodsBuffer); + verifiable.methodsBuffer.append(".arrayField()"); + return verifiable; } @Override diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index a3d0576cd2..21fd6ac1e1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -59,6 +59,11 @@ class JsonToJsonPathsConverter { return convertWithKey(List, key, value as Map, closure) } else if (value instanceof Map) { return convertWithKey(Map, key, value as Map, closure) + // JSON with a list of primitives ["a", "b", "c"] in root issue #266 + } else if (key.isIteratingOverNamelessArray() && value instanceof List && listContainsOnlyPrimitives(value)) { + value.each { + traverseRecursively(Object, key.arrayField().contains(it), it, closure) + } } else if (value instanceof List) { MethodBufferingJsonVerifiable jsonPathVerifiable = createAsserterFromList(key, value) value.each { def element -> diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index 489fcfa298..9193e11a55 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1199,6 +1199,39 @@ World.'''""" test.contains('assertThatJson(parsedJson).array().contains("id").matches("[0-9]+")') } + @Issue('266') + def "should generate proper test code with top level array using #methodBuilderName"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath '/api/tags' + } + response { + status 200 + body(["Java", "Java8", "Spring", "SpringBoot", "Stream"]) + headers { + header('Content-Type': 'application/json;charset=UTF-8') + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("Stream").value()') + test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + } + GroovyDsl dslForDocs = // tag::dsl_example[] diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index f25f7bc5b4..a4d8a06a5c 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -4,6 +4,7 @@ import com.jayway.jsonpath.Configuration import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.jayway.jsonpath.Option +import com.toomuchcoding.jsonassert.JsonAssertion import groovy.json.JsonOutput import groovy.json.JsonSlurper import net.minidev.json.JSONArray @@ -533,23 +534,27 @@ class JsonToJsonPathsConverterSpec extends Specification { JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { - it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(38.995548).value()""" && + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().contains(38.995548).value()""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]""" } pathAndValues.find { - it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(-77.119759).value()""" && + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().contains(-77.119759).value()""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]""" } pathAndValues.find { - it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(-76.909393).value()""" && + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().contains(-76.909393).value()""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]""" } pathAndValues.find { - it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().contains(38.791645).value()""" && + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().contains(38.791645).value()""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]""" } and: - pathAndValues.size() == 4 + pathAndValues.size() == 4 + and: + pathAndValues.each { + JsonAssertion.assertThat(json).matchesJsonPath(it.jsonPath()) + } } private void assertThatJsonPathsInMapAreValid(String json, JsonPaths pathAndValues) { diff --git a/gradle.properties b/gradle.properties index d4ffd5d33d..bc634783d3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.10-beta -jsonassertVersion = 0.4.1 +jsonassertVersion = 0.4.2 BOM_VERSION=Brixton-1.0.0.RC1 springBootVersion=1.3.3.RELEASE From a409a94005979e72a4f775c9cfe47c089056e1ac Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 11 May 2016 12:16:29 +0200 Subject: [PATCH 645/719] Issues wrong arrayfield (#272) * Bumped up jsonassert to 0.4.3 * Added a fix (?) for arrays of primitives - the tests pass ;) fixes #271 --- .../DslToWireMockClientConverterSpec.groovy | 80 +++++++++---------- .../util/DelegatingJsonVerifiable.java | 54 +++++++++---- .../FinishedDelegatingJsonVerifiable.java | 6 +- .../util/JsonToJsonPathsConverter.groovy | 35 +++++--- .../MockMvcMethodBodyBuilderSpec.groovy | 37 ++++++++- .../accurest/dsl/WireMockGroovyDslSpec.groovy | 8 +- .../util/JsonToJsonPathsConverterSpec.groovy | 10 +-- gradle.properties | 2 +- 8 files changed, 142 insertions(+), 90 deletions(-) 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 79632e7eb1..0d0eee7c03 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 @@ -117,48 +117,40 @@ class DslToWireMockClientConverterSpec extends Specification { { "request" : { "url" : "/api/12", - "method" : "PUT", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" - }, { - "matchesJsonPath" : "$[*].place[?(@.country == 'United States')]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" - }, { - "matchesJsonPath" : "$[*].place[?(@.name == 'Washington')]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box[?(@.type == 'Polygon')]" - }, { - "matchesJsonPath" : "$[*][?(@.id_str == '492967299297845248')]" - }, { - "matchesJsonPath" : "$[*].place[?(@.country_code == 'US')]" - }, { - "matchesJsonPath" : "$[*][?(@.id == 492967299297845248)]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" - }, { - "matchesJsonPath" : "$[*].place[?(@.id == '01fbe706f872cb32')]" - }, { - "matchesJsonPath" : "$[*].place[?(@.url == 'http://api.twitter.com/1/geo/id/01fbe706f872cb32.json')]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" - }, { - "matchesJsonPath" : "$[*][?(@.text == 'Gonna see you at Warsaw')]" - }, { - "matchesJsonPath" : "$[*].place[?(@.place_type == 'city')]" - }, { - "matchesJsonPath" : "$[*][?(@.created_at == 'Sat Jul 26 09:38:57 +0000 2014')]" - }, { - "matchesJsonPath" : "$[*].place[?(@.full_name == 'Washington, DC')]" - }, { - "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" - } ], + "method" : "PUT", + "bodyPatterns" : [ { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]" + }, { + "matchesJsonPath" : "$[*][?(@.text == 'Gonna see you at Warsaw')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.place_type == 'city')]" + }, { + "matchesJsonPath" : "$[*][?(@.id == 492967299297845248)]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.country == 'United States')]" + }, { + "matchesJsonPath" : "$[*][?(@.id_str == '492967299297845248')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.name == 'Washington')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box[?(@.type == 'Polygon')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.url == 'http://api.twitter.com/1/geo/id/01fbe706f872cb32.json')]" + }, { + "matchesJsonPath" : "$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]" + }, { + "matchesJsonPath" : "$[*].place[?(@.country_code == 'US')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.full_name == 'Washington, DC')]" + }, { + "matchesJsonPath" : "$[*][?(@.created_at == 'Sat Jul 26 09:38:57 +0000 2014')]" + }, { + "matchesJsonPath" : "$[*].place[?(@.id == '01fbe706f872cb32')]" + } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.com.ofg.twitter-places-analyzer.v1+json" @@ -207,7 +199,7 @@ class DslToWireMockClientConverterSpec extends Specification { {"request":{"urlPath":"/foos","method":"GET"},"response":{"body":"[{\\"id\\":\\"123\\"},{\\"id\\":\\"567\\"}]"}} ''', json, false) } - + def 'should convert dsl to wiremock to show it in the docs'() { given: def converter = new DslToWireMockClientConverter() @@ -272,5 +264,5 @@ class DslToWireMockClientConverterSpec extends Specification { // end::wiremock[] , json, false) } - + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index 3067c79049..cf96e2822d 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -2,6 +2,8 @@ package io.codearte.accurest.util; import com.toomuchcoding.jsonassert.JsonVerifiable; +import java.util.LinkedList; + import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; /** @@ -10,17 +12,17 @@ import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { private final JsonVerifiable delegate; - private final StringBuffer methodsBuffer; + private final LinkedList methodsBuffer; DelegatingJsonVerifiable(JsonVerifiable delegate, - StringBuffer methodsBuffer) { + LinkedList methodsBuffer) { this.delegate = delegate; - this.methodsBuffer = new StringBuffer(methodsBuffer.toString()); + this.methodsBuffer = new LinkedList(methodsBuffer); } DelegatingJsonVerifiable(JsonVerifiable delegate) { this.delegate = delegate; - this.methodsBuffer = new StringBuffer(); + this.methodsBuffer = new LinkedList(); } private static String stringWithEscapedQuotes(Object object) { @@ -35,8 +37,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { } private void appendMethodWithValue(String methodName, Object value) { - methodsBuffer.append(".").append(methodName).append("(").append(value) - .append(")"); + methodsBuffer.offer("." + methodName + "(" + value + ")"); } private void appendMethodWithQuotedValue(String methodName, Object value) { @@ -48,7 +49,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { DelegatingJsonVerifiable verifiable = new FinishedDelegatingJsonVerifiable(delegate.contains(value), methodsBuffer); verifiable.appendMethodWithQuotedValue("contains", value); if (isAssertingAValueInArray()) { - verifiable.methodsBuffer.append(".value()"); + verifiable.methodsBuffer.offer(".value()"); } return verifiable; } @@ -91,14 +92,14 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { @Override public MethodBufferingJsonVerifiable arrayField() { DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.arrayField(), methodsBuffer); - verifiable.methodsBuffer.append(".arrayField()"); + verifiable.methodsBuffer.offer(".arrayField()"); return verifiable; } @Override public MethodBufferingJsonVerifiable array() { DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.array(), methodsBuffer); - verifiable.methodsBuffer.append(".array()"); + verifiable.methodsBuffer.offer(".array()"); return verifiable; } @@ -110,8 +111,11 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { @Override public MethodBufferingJsonVerifiable isEqualTo(String value) { DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer); - if (delegate.isAssertingAValueInArray()) { - readyToCheck.methodsBuffer.append(".value()"); + if (delegate.isAssertingAValueInArray() && readyToCheck.methodsBuffer.peekLast().equals(".arrayField()")) { + readyToCheck.appendMethodWithQuotedValue("isEqualTo", escapeJava(value)); + readyToCheck.methodsBuffer.offer(".value()"); + } else if (delegate.isAssertingAValueInArray() && !readyToCheck.methodsBuffer.peekLast().contains("array")) { + readyToCheck.methodsBuffer.offer(".value()"); } else { readyToCheck.appendMethodWithQuotedValue("isEqualTo", escapeJava(value)); } @@ -129,18 +133,25 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { @Override public MethodBufferingJsonVerifiable isEqualTo(Number value) { DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer); - if (delegate.isAssertingAValueInArray()) { - readyToCheck.methodsBuffer.append(".value()"); + // related to #271 - the problem is with asserting arrays of maps vs arrays of primitives + String last = readyToCheck.methodsBuffer.peekLast(); + boolean containsAMatcher = containsAnyMatcher(last); + if (delegate.isAssertingAValueInArray() && containsAMatcher) { + readyToCheck.methodsBuffer.offer(".value()"); } else { readyToCheck.appendMethodWithValue("isEqualTo", String.valueOf(value)); } return readyToCheck; } + private boolean containsAnyMatcher(String string) { + return string.contains("isEqualTo") || string.contains("matches") || string.contains("isNull"); + } + @Override public MethodBufferingJsonVerifiable isNull() { DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isNull(), methodsBuffer); - readyToCheck.methodsBuffer.append(".isNull()"); + readyToCheck.methodsBuffer.offer(".isNull()"); return readyToCheck; } @@ -149,7 +160,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.matches(value), methodsBuffer); if (delegate.isAssertingAValueInArray()) { readyToCheck.appendMethodWithQuotedValue("matches", escapeJava(value)); - readyToCheck.methodsBuffer.append(".value()"); + readyToCheck.methodsBuffer.offer(".value()"); } else { readyToCheck.appendMethodWithQuotedValue("matches", escapeJava(value)); } @@ -160,7 +171,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { public MethodBufferingJsonVerifiable isEqualTo(Boolean value) { DelegatingJsonVerifiable readyToCheck = new FinishedDelegatingJsonVerifiable(delegate.isEqualTo(value), methodsBuffer); if (delegate.isAssertingAValueInArray()) { - readyToCheck.methodsBuffer.append(".value()"); + readyToCheck.methodsBuffer.offer(".value()"); } else { readyToCheck.appendMethodWithValue("isEqualTo", String.valueOf(value)); } @@ -204,7 +215,16 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { @Override public String method() { - return methodsBuffer.toString(); + return createMethodString(); + } + + private String createMethodString() { + LinkedList queue = new LinkedList(methodsBuffer); + StringBuilder stringBuffer = new StringBuilder(); + while (!queue.isEmpty()) { + stringBuffer.append(queue.remove()); + } + return stringBuffer.toString(); } @Override diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java index eb65cd73f4..abf0678d07 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java @@ -2,18 +2,20 @@ package io.codearte.accurest.util; import com.toomuchcoding.jsonassert.JsonVerifiable; +import java.util.LinkedList; + /** * @author Marcin Grzejszczak */ class FinishedDelegatingJsonVerifiable extends DelegatingJsonVerifiable { FinishedDelegatingJsonVerifiable(JsonVerifiable delegate, - StringBuffer methodsBuffer) { + LinkedList methodsBuffer) { super(delegate, methodsBuffer); } FinishedDelegatingJsonVerifiable(JsonVerifiable delegate) { - super(delegate, new StringBuffer()); + super(delegate, new LinkedList()); } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index 21fd6ac1e1..ae7558b952 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -62,17 +62,25 @@ class JsonToJsonPathsConverter { // JSON with a list of primitives ["a", "b", "c"] in root issue #266 } else if (key.isIteratingOverNamelessArray() && value instanceof List && listContainsOnlyPrimitives(value)) { value.each { - traverseRecursively(Object, key.arrayField().contains(it), it, closure) + traverseRecursively(Object, key.arrayField().contains(ContentUtils.returnParsedObject(it)), + ContentUtils.returnParsedObject(it), closure) + } + // JSON containing list of primitives { "partners":[ { "role":"AGENT", "payment_methods":[ "BANK", "CASH" ] } ] + } else if (value instanceof List && listContainsOnlyPrimitives(value)) { + value.each { + traverseRecursively(Object, valueToAsserter(key.arrayField(), ContentUtils.returnParsedObject(it)), + ContentUtils.returnParsedObject(it), closure) } } else if (value instanceof List) { MethodBufferingJsonVerifiable jsonPathVerifiable = createAsserterFromList(key, value) value.each { def element -> - traverseRecursively(List, createAsserterFromListElement(jsonPathVerifiable, element), - element, closure) + traverseRecursively(List, createAsserterFromListElement(jsonPathVerifiable, ContentUtils.returnParsedObject(element)), + ContentUtils.returnParsedObject(element), closure) } return value } else if (key.isIteratingOverArray()) { - traverseRecursively(Object, key.arrayField().contains(value), value, closure) + traverseRecursively(Object, key.arrayField().contains(ContentUtils.returnParsedObject(value)), + ContentUtils.returnParsedObject(value), closure) } try { return runClosure(closure, key, value) @@ -108,7 +116,7 @@ class JsonToJsonPathsConverter { } private static def runClosure(Closure closure, MethodBufferingJsonVerifiable key, def value) { - if (key.isAssertingAValueInArray()) { + if (key.isAssertingAValueInArray() && !(value instanceof List || value instanceof Map)) { return closure(valueToAsserter(key, value), value) } return closure(key, value) @@ -172,19 +180,20 @@ class JsonToJsonPathsConverter { } protected static MethodBufferingJsonVerifiable valueToAsserter(MethodBufferingJsonVerifiable key, Object value) { + def convertedValue = ContentUtils.returnParsedObject(value) if (key instanceof FinishedDelegatingJsonVerifiable) { return key } - if (value instanceof Pattern) { - return key.matches((value as Pattern).pattern()) - } else if (value instanceof OptionalProperty) { - return key.matches((value as OptionalProperty).optionalPattern()) - } else if (value instanceof GString) { - return key.matches(RegexpBuilders.buildGStringRegexpForTestSide(value)) - } else if (ContentUtils.returnParsedObject(value) instanceof ExecutionProperty) { + if (convertedValue instanceof Pattern) { + return key.matches((convertedValue as Pattern).pattern()) + } else if (convertedValue instanceof OptionalProperty) { + return key.matches((convertedValue as OptionalProperty).optionalPattern()) + } else if (convertedValue instanceof GString) { + return key.matches(RegexpBuilders.buildGStringRegexpForTestSide(convertedValue)) + } else if (convertedValue instanceof ExecutionProperty) { return key } - return key.isEqualTo(value) + return key.isEqualTo(convertedValue) } } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index 9193e11a55..5c54cae143 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1131,7 +1131,7 @@ World.'''""" builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: - test.contains('''assertThatJson(parsedJson).array("authorities").matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''') + test.contains('''assertThatJson(parsedJson).array("authorities").arrayField().matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''') where: methodBuilderName | methodBuilder "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } @@ -1232,6 +1232,39 @@ World.'''""" "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } + def "should generate proper test code with array of primitives using #methodBuilderName"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath '/api/tags' + } + response { + status 200 + body('''{ + "partners":[ + { + "payment_methods":[ "BANK", "CASH" ] + } + ] + } + ''') + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).array("partners").array("payment_methods").arrayField().isEqualTo("BANK").value()') + test.contains('assertThatJson(parsedJson).array("partners").array("payment_methods").arrayField().isEqualTo("CASH").value()') + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + } + GroovyDsl dslForDocs = // tag::dsl_example[] @@ -1278,4 +1311,4 @@ World.'''""" } } // end::dsl_example[] - } \ No newline at end of file +} \ No newline at end of file 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 269d1c3b6f..2b5157a3f7 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 @@ -1015,19 +1015,15 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie "matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]" }, { "matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]" - }, { - "matchesJsonPath" : "$.errors[*][?(@.providerValue == 'Test')]" }, { "matchesJsonPath" : "$[?(@.lastName =~ /.*/)]" }, { - "matchesJsonPath" : "$.errors[*][?(@.propertyName =~ /[0-9]{2}/)]" + "matchesJsonPath" : "$[?(@.firstName =~ /.*/)]" }, { "matchesJsonPath" : "$[?(@.birthDate =~ /[0-9]{4}-[0-9]{2}-[0-9]{2}/)]" }, { "matchesJsonPath" : "$[?(@.personalId =~ /[0-9]{11}/)]" - }, { - "matchesJsonPath" : "$[?(@.firstName =~ /.*/)]" - } ] + }] }, "response" : { "status" : 200, diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index a4d8a06a5c..1645aa7475 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -142,7 +142,7 @@ class JsonToJsonPathsConverterSpec extends Specification { JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { - it.method() == """.array("items").contains("HOP").value()""" && + it.method() == """.array("items").arrayField().isEqualTo("HOP").value()""" && it.jsonPath() == '''$.items[?(@ == 'HOP')]''' } and: @@ -534,19 +534,19 @@ class JsonToJsonPathsConverterSpec extends Specification { JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { - it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().contains(38.995548).value()""" && + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(38.995548)""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.995548)]""" } pathAndValues.find { - it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().contains(-77.119759).value()""" && + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(-77.119759)""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -77.119759)]""" } pathAndValues.find { - it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().contains(-76.909393).value()""" && + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(-76.909393)""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == -76.909393)]""" } pathAndValues.find { - it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().contains(38.791645).value()""" && + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(38.791645)""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]""" } and: diff --git a/gradle.properties b/gradle.properties index bc634783d3..c186a2a3ed 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.10-beta -jsonassertVersion = 0.4.2 +jsonassertVersion = 0.4.3 BOM_VERSION=Brixton-1.0.0.RC1 springBootVersion=1.3.3.RELEASE From 1c5337b1ea4fad8e4ed0cced70f11895a05c1336 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 11 May 2016 13:46:19 +0200 Subject: [PATCH 646/719] Bumped up to jsonassert 0.4.5 I hate JSON every single day more... From what I see the bug has been fixed fixes #266 --- .../MockMvcMethodBodyBuilderSpec.groovy | 32 +++++++++++++++++++ gradle.properties | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index 5c54cae143..ce1f0db1a0 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1232,6 +1232,38 @@ World.'''""" "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } + @Issue('266') + def "should generate proper test code with top level array or arrays using #methodBuilderName"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath '/api/categories' + } + response { + status 200 + body([["Programming", "Java"], ["Programming", "Java", "Spring", "Boot"]]) + headers { + header('Content-Type': 'application/json;charset=UTF-8') + } + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Programming").value()') + test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Java").value()') + test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Spring").value()') + test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Boot").value()') + where: + methodBuilderName | methodBuilder + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + } + def "should generate proper test code with array of primitives using #methodBuilderName"() { given: GroovyDsl contractDsl = GroovyDsl.make { diff --git a/gradle.properties b/gradle.properties index c186a2a3ed..45a95579c1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.10-beta -jsonassertVersion = 0.4.3 +jsonassertVersion = 0.4.5 BOM_VERSION=Brixton-1.0.0.RC1 springBootVersion=1.3.3.RELEASE From 76762e7e37e7a76441afc4dd05f97ee057e05b75 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 11 May 2016 18:10:29 +0200 Subject: [PATCH 647/719] Added documentation entry for json / txt fixes #269 --- docs/src/docs/asciidoc/contract.adoc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/docs/asciidoc/contract.adoc index 8778f7259b..ad8c58b3f3 100644 --- a/docs/src/docs/asciidoc/contract.adoc +++ b/docs/src/docs/asciidoc/contract.adoc @@ -4,7 +4,7 @@ Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn' a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself - it's statically typed. -WARNING: Since {messaging_version} you can use the `io.codearte.accurest.dsl.Accurest` class in your DSL files. +TIP: Since {messaging_version} you can use the `io.codearte.accurest.dsl.Accurest` class in your DSL files. Let's look at full example of a contract definition. @@ -17,6 +17,12 @@ Not all features of the DSL are used in example above. If you didn't find what y > You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. +=== Limitations + +WARNING: Accurest doesn't support XML properly. Please use JSON or help us implement this feature. + +WARNING: Accurest supports equality check on text response. Regular expressions are not yet available. + === HTTP Top-Level Elements Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. From 686e2a5ffc777e97f56ace729f12502c3ec6ac54 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 12 May 2016 08:03:19 +0200 Subject: [PATCH 648/719] Release version: 1.1.0-M5 [ci skip] From 85d25a6e48c8786ddbd643404dfedbeae2ec60e3 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 12 May 2016 08:03:19 +0200 Subject: [PATCH 649/719] Release version: 1.1.0-M5 [ci skip] From 84043804a7e62cd3baaf0b6b7645d1332db5c9d1 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Thu, 12 May 2016 08:03:19 +0200 Subject: [PATCH 650/719] Release version: 1.1.0-M5 [ci skip] From a2998acaa1275f1306172aaf36d8e71b7fc839f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Thu, 12 May 2016 17:14:02 +0200 Subject: [PATCH 651/719] Logic moved to accurest-core (#25) --- pom.xml | 2 +- .../maven/EnhancedStubRunnerOptions.groovy | 30 -------- .../EnhancedStubRunnerOptionsBuilder.groovy | 59 --------------- .../io/codearte/accurest/maven/RunMojo.groovy | 9 +-- .../maven/stubrunner/RemoteStubRunner.groovy | 11 +-- .../maven/EnhancedStubRunnerOptionsTest.java | 72 ------------------- 6 files changed, 9 insertions(+), 174 deletions(-) delete mode 100644 src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptions.groovy delete mode 100644 src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptionsBuilder.groovy delete mode 100644 src/test/java/io/codearte/accurest/maven/EnhancedStubRunnerOptionsTest.java diff --git a/pom.xml b/pom.xml index 4a8dfec2f3..daadd3ce5f 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ UTF-8 UTF-8 - 1.1.0-M4 + 1.1.0-M5 1.1.0 1.7 diff --git a/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptions.groovy b/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptions.groovy deleted file mode 100644 index 98acc8be3d..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptions.groovy +++ /dev/null @@ -1,30 +0,0 @@ -package io.codearte.accurest.maven - -import groovy.transform.CompileStatic -import io.codearte.accurest.stubrunner.StubConfiguration -import io.codearte.accurest.stubrunner.StubRunnerOptions - -@CompileStatic -public class EnhancedStubRunnerOptions { - - @Delegate private final StubRunnerOptions options - private final Collection dependencies - - EnhancedStubRunnerOptions(Collection dependencies, StubRunnerOptions options) { - this.options = options - this.dependencies = dependencies - } - - EnhancedStubRunnerOptions(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, boolean workOffline, String stubsClassifier, Collection dependencies, StubRunnerOptions options) { - this.options = new StubRunnerOptions(minPortValue, maxPortValue, stubRepositoryRoot, workOffline, stubsClassifier) - this.dependencies = dependencies - } - - Collection getDependencies() { - return dependencies - } - - StubRunnerOptions getStubsRunnerOptions() { - return options - } -} diff --git a/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptionsBuilder.groovy b/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptionsBuilder.groovy deleted file mode 100644 index cd68d42ec4..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/EnhancedStubRunnerOptionsBuilder.groovy +++ /dev/null @@ -1,59 +0,0 @@ -package io.codearte.accurest.maven - -import groovy.transform.CompileStatic -import io.codearte.accurest.stubrunner.StubConfiguration -import io.codearte.accurest.stubrunner.StubRunnerOptions -import io.codearte.accurest.stubrunner.util.StubsParser - -@CompileStatic -public class EnhancedStubRunnerOptionsBuilder { - - private LinkedList stubs = new LinkedList<>() - - private final StubRunnerOptions options; - - EnhancedStubRunnerOptionsBuilder(StubRunnerOptions options) { - this.options = options - } - - EnhancedStubRunnerOptionsBuilder(Integer minPortValue, Integer maxPortValue, String stubRepositoryRoot, - boolean workOffline, String stubsClassifier) { - this.options = new StubRunnerOptions(minPortValue, maxPortValue, stubRepositoryRoot, workOffline, stubsClassifier) - } - - EnhancedStubRunnerOptionsBuilder withStubs(String stubs) { - addStub(stubsToList(stubs)) - return this - } - - private Collection buildDependencies() { - return StubsParser.fromString(stubs, options.getStubsClassifier()); - } - - private static List stubsToList(String stubIdsToPortMapping) { - return stubIdsToPortMapping.split(',').collect { it } - } - - private void addStub(List notations) { - for (String notation : notations) { - addStub(notation); - } - } - - private void addStub(String notation) { - if (StubsParser.hasPort(notation)) { - addPort(notation); - stubs.add(StubsParser.ivyFromStringWithPort(notation)); - } else { - stubs.add(notation); - } - } - - private void addPort(String notation) { - options.putStubIdsToPortMapping(StubsParser.fromStringWithPort(notation)); - } - - EnhancedStubRunnerOptions build() { - return new EnhancedStubRunnerOptions(buildDependencies(), options) - } -} diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index b644319285..14c6d710b6 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -6,6 +6,7 @@ import io.codearte.accurest.maven.stubrunner.RemoteStubRunner import io.codearte.accurest.stubrunner.BatchStubRunner import io.codearte.accurest.stubrunner.StubRunner import io.codearte.accurest.stubrunner.StubRunnerOptions +import io.codearte.accurest.stubrunner.StubRunnerOptionsBuilder import org.apache.maven.execution.MavenSession import org.apache.maven.plugin.AbstractMojo import org.apache.maven.plugin.MojoExecutionException @@ -66,14 +67,14 @@ class RunMojo extends AbstractMojo { return } BatchStubRunner batchStubRunner + StubRunnerOptionsBuilder optionsBuilder = new StubRunnerOptionsBuilder() + .withStubsClassifier(stubsClassifier) if (!stubs) { - StubRunnerOptions options = new StubRunnerOptions(httpPort, httpPort, "", false, stubsClassifier) + StubRunnerOptions options = optionsBuilder.withPort(httpPort).build() StubRunner stubRunner = localStubRunner.run(resolveStubsDirectory().absolutePath, options) batchStubRunner = new BatchStubRunner(Arrays.asList(stubRunner)) } else { - EnhancedStubRunnerOptions options = new EnhancedStubRunnerOptionsBuilder(minPort, maxPort, "", false, stubsClassifier) - .withStubs(stubs) - .build() + StubRunnerOptions options = optionsBuilder.withMinMaxPort(minPort, maxPort).build() batchStubRunner = remoteStubRunner.run(options, repoSession) } diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy index de1831bfa3..bb2084ef25 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy @@ -2,11 +2,7 @@ package io.codearte.accurest.maven.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.maven.EnhancedStubRunnerOptions -import io.codearte.accurest.stubrunner.AetherStubDownloader -import io.codearte.accurest.stubrunner.BatchStubRunner -import io.codearte.accurest.stubrunner.BatchStubRunnerFactory -import io.codearte.accurest.stubrunner.RunningStubs +import io.codearte.accurest.stubrunner.* import org.eclipse.aether.RepositorySystemSession import javax.inject.Inject @@ -24,12 +20,11 @@ class RemoteStubRunner { this.aetherStubDownloaderFactory = aetherStubDownloaderFactory } - BatchStubRunner run(EnhancedStubRunnerOptions options, RepositorySystemSession repositorySystemSession) { + BatchStubRunner run(StubRunnerOptions options, RepositorySystemSession repositorySystemSession) { AetherStubDownloader stubDownloader = aetherStubDownloaderFactory.build(repositorySystemSession) try { log.debug("Launching StubRunner with args: $options") - BatchStubRunner stubRunner = new BatchStubRunnerFactory(options.getStubsRunnerOptions(), options.getDependencies(), stubDownloader) - .buildBatchStubRunner() + BatchStubRunner stubRunner = new BatchStubRunnerFactory(options, stubDownloader).buildBatchStubRunner() RunningStubs runningCollaborators = stubRunner.runStubs() log.info(runningCollaborators.toString()) return stubRunner diff --git a/src/test/java/io/codearte/accurest/maven/EnhancedStubRunnerOptionsTest.java b/src/test/java/io/codearte/accurest/maven/EnhancedStubRunnerOptionsTest.java deleted file mode 100644 index 0e700200c6..0000000000 --- a/src/test/java/io/codearte/accurest/maven/EnhancedStubRunnerOptionsTest.java +++ /dev/null @@ -1,72 +0,0 @@ -package io.codearte.accurest.maven; - -import static org.assertj.core.api.Assertions.assertThat; - -import org.junit.Test; - -import io.codearte.accurest.stubrunner.StubRunnerOptions; - -public class EnhancedStubRunnerOptionsTest { - - private EnhancedStubRunnerOptionsBuilder builder = new EnhancedStubRunnerOptionsBuilder(new StubRunnerOptions()); - - @Test - public void shouldAddStubCoordinatesWithPort() throws Exception { - - //given - builder.withStubs("foo:bar:8080"); - - //when - EnhancedStubRunnerOptions options = builder.build(); - - //then - assertThat(options.getDependencies()) - .hasToString("[foo:bar:+:stubs]"); - assertThat(options.getStubIdsToPortMapping()) - .hasToString("{foo:bar:+:stubs=8080}"); - } - - @Test - public void shouldAddStubCoordinatesWithoutPort() throws Exception { - - //given - builder.withStubs("foo:bar"); - - //when - EnhancedStubRunnerOptions options = builder.build(); - - //then - assertThat(options.getDependencies()) - .hasToString("[foo:bar:+:stubs]"); - assertThat(options.getStubIdsToPortMapping()) - .hasSize(0); - } - - @Test - public void shouldAddMultipleStubCoordinates() throws Exception { - - //given - builder.withStubs("foo:bar,bar:foo"); - - //when - EnhancedStubRunnerOptions options = builder.build(); - - //then - assertThat(options.getDependencies()) - .hasSize(2); - } - - @Test - public void shouldAddStubCoordinatesWithVersion() throws Exception { - - //given - builder.withStubs("foo:1.2.3:bar"); - - //when - EnhancedStubRunnerOptions options = builder.build(); - - //then - assertThat(options.getDependencies()) - .hasToString("[foo:1.2.3:bar:stubs]"); - } -} \ No newline at end of file From 62c736130edcc655447b8b822b7d40362ab2cd69 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Thu, 12 May 2016 15:25:04 +0000 Subject: [PATCH 652/719] Sets project version to 0.6.8-SNAPSHOT [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index daadd3ce5f..d6564694b9 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.7-SNAPSHOT + 0.6.8-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From fb60a10f0e89e977d62e3ae2339fff1c1f48bf9e Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Sat, 14 May 2016 21:28:13 +0200 Subject: [PATCH 653/719] Speed up Travis build --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ad7126c071..eb6e4b6279 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,5 +12,5 @@ jdk: - oraclejdk7 - oraclejdk8 -install: ./gradlew assemble -script: ./gradlew clean check funcTest install --stacktrace --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh +install: ./gradlew assemble -s +script: ./gradlew check funcTest install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh From 430bcd016237355d5ffce2434998f701b05342b9 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Sat, 14 May 2016 00:06:43 +0200 Subject: [PATCH 654/719] Add SNAPSHOT archives upload --- .travis.yml | 11 +++++++++-- build.gradle | 5 ++++- gradle/release.gradle | 19 +++++++++++++++++++ gradle/releaseRoot.gradle | 16 ++++++++++++++++ 4 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 gradle/releaseRoot.gradle diff --git a/.travis.yml b/.travis.yml index eb6e4b6279..17669d2150 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,8 +9,15 @@ before_install: - "cp -r stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs $HOME/.m2/repository/io/codearte/accurest/" jdk: - - oraclejdk7 - oraclejdk8 install: ./gradlew assemble -s -script: ./gradlew check funcTest install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh +script: ./gradlew check funcTest install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh && jdk_switcher use $TRAVIS_JDK_VERSION && ./gradlew uploadSnapshotArchives -s + +matrix: + include: + # Automatic snapshot release only in Java 7 build + - jdk: oraclejdk7 + env: + - DO_RELEASE=true + diff --git a/build.gradle b/build.gradle index 73d3214e83..9cc73475f1 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,8 @@ nexusStaging { stagingProfileId = '93c08fdebde1ff' } +apply from: "$rootDir/gradle/releaseRoot.gradle" + subprojects { apply plugin: 'groovy' apply from: "$rootDir/gradle/release.gradle" @@ -211,4 +213,5 @@ buildscript { } } -apply plugin: "com.palantir.idea-test-fix" \ No newline at end of file +apply plugin: "com.palantir.idea-test-fix" + diff --git a/gradle/release.gradle b/gradle/release.gradle index e3f5159bb1..e1c6fb4494 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -38,3 +38,22 @@ modifyPom { uploadArchives.dependsOn { check } + +task uploadSnapshotArchives { + if (shouldUploadSnapshotArchives) { + dependsOn { uploadArchives } + } + onlyIf { shouldUploadSnapshotArchives } +} + +//for Travis to leverage secure variables +project.ext { + if (!hasProperty('nexusUsername') && System.env.NEXUS_USERNAME) { + nexusUsername = System.env.NEXUS_USERNAME + } + if (!hasProperty('nexusPassword') && System.env.NEXUS_PASSWORD) { + nexusPassword = System.env.NEXUS_PASSWORD + } +} + + diff --git a/gradle/releaseRoot.gradle b/gradle/releaseRoot.gradle new file mode 100644 index 0000000000..667dcbcb82 --- /dev/null +++ b/gradle/releaseRoot.gradle @@ -0,0 +1,16 @@ +assert project == rootProject + +project.ext { + isSnapshot = project.version.endsWith("-SNAPSHOT") + currentBranch = System.env.TRAVIS_BRANCH + isPr = !isNullOrFalse(System.env.TRAVIS_PULL_REQUEST) + doRelease = !isNullOrFalse(System.env.DO_RELEASE) + shouldUploadSnapshotArchives = isSnapshot && currentBranch == 'master' && !isPr && doRelease +} + +logger.lifecycle("Automatic snapshot release: {} (isSnapshot: {}, currentBranch: {}, isPr: {}, doRelease: {})", shouldUploadSnapshotArchives, isSnapshot, currentBranch, isPr, doRelease) + +private boolean isNullOrFalse(def env) { + env == null || env == "false" || (env instanceof Boolean && !env) +} + From 3b9d86a62eaf0ddd18a478dfdc8fac54126937f8 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Sun, 15 May 2016 00:03:26 +0200 Subject: [PATCH 655/719] Add extra variables --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 17669d2150..1e3a304692 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,3 +21,8 @@ matrix: env: - DO_RELEASE=true +env: + global: + - secure: NbEQ9t5nGKW0LKmOSV4rTiEbYJARM2rynQBdSXkoILbp+nNaCD6uN41tUu8HrjgbjUDMepFUU+hmGQ47Q2vz5L3NzvW+oHBLgrIu6uAimpdR8qyBE899MBKPE19LsvUOeE9B9TydJgYlY+UEYgxwssUwxsN0RqyY4EErQWMNC8k= + - secure: zCjkMhjF5TbZehNmOK7EV68J35tuc0etWG/ia0eVTjgIv2kp9islJZ3+Jm/gDgkcv2Ydq3oAU2jFbVkUPSSstV3L5KANsighm2qn9tVzRrbTCfM55zcBhnoE0oZHTPNrLoScz0X5sM8Xuvi6ChjGf+lqAxnFW6tFMjx+1uhUIXU= + From f58754ecf0f74d53f038424e1e49a77dda1ddf8b Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Sun, 15 May 2016 00:28:52 +0200 Subject: [PATCH 656/719] Add snapshot versions to documentation --- docs/src/docs/asciidoc/rest.adoc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/docs/asciidoc/rest.adoc index b956e77f29..27ccbec36a 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/docs/asciidoc/rest.adoc @@ -29,6 +29,19 @@ dependencies { } ---- +====== Snapshot versions + +Add the additional snapshot repository to your build.gradle to use snapshot versions which are automatically uploaded after every successful build: + +[source,groovy,indent=0] +---- +repositories { + (...) + //Required only for SNAPSHOT versions + maven { url "https://oss.sonatype.org/content/repositories/snapshots" } +} +---- + ===== Add maven plugin [source,xml,indent=0] @@ -375,4 +388,4 @@ Such tree will cause Accurest generating Wiremock's scenario with name `scenario - logout marked as `Step2` which will close the scenario. More details about Wiremock scenarios can be found under [http://wiremock.org/stateful-behaviour.html](http://wiremock.org/stateful-behaviour.html) -Accurest will also generate tests with guaranteed order of execution. \ No newline at end of file +Accurest will also generate tests with guaranteed order of execution. From 4fdbdb41e121b2c3fded348ba8a708b602fa2818 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Sun, 15 May 2016 00:41:09 +0200 Subject: [PATCH 657/719] Downgrade Axion plugin Due to a bug with three commits on release: https://github.com/allegro/axion-release-plugin/issues/132 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9cc73475f1..53eb33d85b 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { if (project.hasProperty('fatJar')) jcenter() } dependencies { - classpath "pl.allegro.tech.build:axion-release-plugin:1.3.4" + classpath "pl.allegro.tech.build:axion-release-plugin:1.3.2" 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' From 75442fb682c0d3391e6443ea8eaebe42e095a8d7 Mon Sep 17 00:00:00 2001 From: Marcin Zajaczkowski Date: Sun, 15 May 2016 00:57:43 +0200 Subject: [PATCH 658/719] Disable 'check' for uploadSnapshotArchives task To speed up the build until the reason for the second time tests execution will be found (the whole 'check' should be up-to-date).. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1e3a304692..599d7dc7f0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,7 +12,7 @@ jdk: - oraclejdk8 install: ./gradlew assemble -s -script: ./gradlew check funcTest install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh && jdk_switcher use $TRAVIS_JDK_VERSION && ./gradlew uploadSnapshotArchives -s +script: ./gradlew check funcTest install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh && jdk_switcher use $TRAVIS_JDK_VERSION && ./gradlew uploadSnapshotArchives -x check -s matrix: include: From 7d2f01aad2fd166f5216d11811f71af5310c1222 Mon Sep 17 00:00:00 2001 From: Matt Reynolds Date: Mon, 16 May 2016 16:06:37 -0600 Subject: [PATCH 659/719] fix for issue #47 - add async options on request when new async flag set (#277) * fix for issue #47 - add async options on request when new async flag set * don't add async to initial request declaration and switch spaces to tabs for all changes. --- .../builder/JUnitMethodBodyBuilder.groovy | 6 +++- ...kMethodRequestProcessingBodyBuilder.groovy | 6 +++- .../accurest/dsl/internal/Response.groovy | 7 ++++- .../MockMvcMethodBodyBuilderSpec.groovy | 31 +++++++++++++++++-- 4 files changed, 45 insertions(+), 5 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy index 02f8ad854f..543e8c41cf 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy @@ -88,7 +88,11 @@ abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder @Override protected String getInputString(Request request) { - return 'ResponseOptions response = given().spec(request)' + def inputString = 'ResponseOptions response = given().spec(request)' + if (response.async){ + inputString = inputString + '.when().async()' + } + return inputString } @Override diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodRequestProcessingBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodRequestProcessingBodyBuilder.groovy index b9d1aedf86..c149c13bb8 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodRequestProcessingBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodRequestProcessingBodyBuilder.groovy @@ -71,7 +71,11 @@ abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessing @Override protected String getInputString(Request request) { - return 'def response = given().spec(request)' + def inputString = 'def response = given().spec(request)' + if (response.async){ + inputString = inputString + '.when().async()' + } + return inputString } @Override diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy index 612a092ef1..9078add18f 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy @@ -14,6 +14,7 @@ class Response extends Common { DslProperty delay Headers headers Body body + boolean async Response() { } @@ -54,6 +55,10 @@ class Response extends Common { this.delay = toDslProperty(timeInMilliseconds) } + public void async() { + this.async = true + } + void assertThatSidesMatch(OptionalProperty stubSide, Object testSide) { throw new IllegalStateException("Optional can be used only in the test side of the response!") } @@ -75,4 +80,4 @@ class ClientResponse extends Response { ClientResponse(Response request) { super(request) } -} \ No newline at end of file +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index ce1f0db1a0..533eaf7a9a 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1263,6 +1263,33 @@ World.'''""" "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } + @Issue('47') + def "should generate async body when async flag set in response"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + url '/test' + } + response { + status 200 + async() + } + } + MethodBodyBuilder builder = methodBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains(bodyDefinitionString) + and: + stubMappingIsValidWireMockStub(contractDsl) + where: + methodBuilderName | methodBuilder | bodyDefinitionString + "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '.when().async()' + "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.when().async()' + } def "should generate proper test code with array of primitives using #methodBuilderName"() { given: @@ -1280,7 +1307,7 @@ World.'''""" } ] } - ''') + ''') } } MethodBodyBuilder builder = methodBuilder(contractDsl) @@ -1343,4 +1370,4 @@ World.'''""" } } // end::dsl_example[] -} \ No newline at end of file +} From 4f74c0b26efcb3a992c20b47072c2f9d21fcc5a3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 17 May 2016 11:04:58 +0200 Subject: [PATCH 660/719] Fixed wrong $ escaping (#278) Fixed wrong $ escaping fixes #273 --- .../accurest/builder/MethodBodyBuilder.groovy | 8 ++- ...kMethodRequestProcessingBodyBuilder.groovy | 7 +- .../SpockMessagingMethodBodyBuilder.groovy | 6 ++ .../util/DelegatingJsonVerifiable.java | 2 +- .../MockMvcMethodBodyBuilderSpec.groovy | 64 +++++++++++++++++-- 5 files changed, 78 insertions(+), 9 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy index 8ca6aade46..044394a1aa 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy @@ -121,7 +121,9 @@ abstract class MethodBodyBuilder { appendJsonPath(bb, getResponseAsString()) JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) jsonPaths.each { - bb.addLine("assertThatJson(parsedJson)" + it.method()) + String method = it.method() + String postProcessedMethod = postProcessJsonPathCall(method) + bb.addLine("assertThatJson(parsedJson)" + postProcessedMethod) addColonIfRequired(bb) } processBodyElement(bb, "", responseBody) @@ -136,6 +138,10 @@ abstract class MethodBodyBuilder { } } + protected String postProcessJsonPathCall(String jsonPath) { + return jsonPath + } + protected void appendJsonPath(BlockBuilder blockBuilder, String json) { blockBuilder.addLine(("DocumentContext parsedJson = JsonPath.parse($json)")) addColonIfRequired(blockBuilder) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy index bf3cdeb509..5d983c3e6c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy @@ -48,4 +48,9 @@ class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestP blockBuilder.addLine("response.header('$property') ${convertHeaderComparison(value)}") } -} + // #273 - should escape $ for Groovy since it will try to make it a GString + @Override + protected String postProcessJsonPathCall(String jsonPath) { + return jsonPath.replace('$', '\\$') + } +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy index e9bbb2e1db..0c9a0b5f83 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy @@ -159,4 +159,10 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { return "==~ java.util.regex.Pattern.compile('$headerValue')" } + // #273 - should escape $ for Groovy since it will try to make it a GString + @Override + protected String postProcessJsonPathCall(String method) { + return method.replace('$', '\\$') + } + } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index cf96e2822d..bd41fa1c78 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -32,7 +32,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { private static String wrapValueWithQuotes(Object value) { return value instanceof String ? - "\"" + stringWithEscapedQuotes(value).replaceAll("\\$", "\\\\\\$") + "\"" : + "\"" + stringWithEscapedQuotes((String) value) + "\"" : value.toString(); } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index 533eaf7a9a..f42b7ef95a 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1101,7 +1101,7 @@ World.'''""" } @Issue('#216') - def "should parse JSON with arrays using #methodBuilderName"() { + def "should parse JSON with arrays using Spock"() { given: GroovyDsl contractDsl = GroovyDsl.make { request { @@ -1125,17 +1125,47 @@ World.'''""" ) } } - MethodBodyBuilder builder = methodBuilder(contractDsl) + MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) def test = blockBuilder.toString() then: test.contains('''assertThatJson(parsedJson).array("authorities").arrayField().matches("^[a-zA-Z0-9_\\\\- ]+\\$").value()''') - where: - methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + } + + @Issue('#216') + def "should parse JSON with arrays using JUnit"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method "GET" + urlPath('/auth/oauth/check_token') { + queryParameters { + parameter 'token': + value( + client(regex('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}')), + server('6973b31d-7140-402a-bca6-1cdb954e03a7') + ) + } + } + } + response { + status 200 + body( + authorities: [ + value(stub('ROLE_ADMIN'), test(regex('^[a-zA-Z0-9_\\- ]+$'))) + ] + ) + } + } + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.appendTo(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('''assertThatJson(parsedJson).array("authorities").arrayField().matches("^[a-zA-Z0-9_\\\\- ]+$").value()''') } def "should work with execution property"() { @@ -1324,6 +1354,28 @@ World.'''""" "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } + @Issue('#273') + def "should not escape dollar in Spock regex tests"() { + given: + GroovyDsl contractDsl = GroovyDsl.make { + request { + method 'GET' + urlPath '/get' + } + response { + status 200 + body( code: 9, message: $(client('Wrong credentials'), server(regex('^(?!\\s*$).+'))) ) + } + } + MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) + BlockBuilder blockBuilder = new BlockBuilder(" ") + when: + builder.then(blockBuilder) + def test = blockBuilder.toString() + then: + test.contains('assertThatJson(parsedJson).field("message").matches("^(?!\\\\s*\\$).+")') + } + GroovyDsl dslForDocs = // tag::dsl_example[] From 622a3875f9a9209bb9c24dccf17c745ab858e638 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Tue, 17 May 2016 11:11:26 +0200 Subject: [PATCH 661/719] Release version: 1.1.0-M6 [ci skip] From 91af7c205f22f40a217076636ed28857941011d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Thu, 19 May 2016 10:52:45 +0200 Subject: [PATCH 662/719] accurest update (#26) --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d6564694b9..15cf4df071 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ UTF-8 UTF-8 - 1.1.0-M5 + 1.1.0-M6 1.1.0 1.7 From 1f6316df6314e293047c4474aaa73655c6d6ed65 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Thu, 19 May 2016 08:59:59 +0000 Subject: [PATCH 663/719] Sets project version to 0.6.9-SNAPSHOT [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 15cf4df071..193e31cdbe 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.8-SNAPSHOT + 0.6.9-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From 0e4070ffc4d7ef884d379a35bcde073b2d52dbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Mon, 30 May 2016 15:24:35 +0200 Subject: [PATCH 664/719] force to check remote repository (#281) --- .../stubrunner/AetherStubDownloader.groovy | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy index b5b875d163..46f8dee7f8 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy @@ -12,7 +12,13 @@ import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory import org.eclipse.aether.impl.DefaultServiceLocator import org.eclipse.aether.repository.LocalRepository import org.eclipse.aether.repository.RemoteRepository -import org.eclipse.aether.resolution.* +import org.eclipse.aether.repository.RepositoryPolicy +import org.eclipse.aether.resolution.ArtifactRequest +import org.eclipse.aether.resolution.ArtifactResult +import org.eclipse.aether.resolution.VersionRangeRequest +import org.eclipse.aether.resolution.VersionRangeResult +import org.eclipse.aether.resolution.VersionRequest +import org.eclipse.aether.resolution.VersionResult import org.eclipse.aether.spi.connector.RepositoryConnectorFactory import org.eclipse.aether.spi.connector.transport.TransporterFactory import org.eclipse.aether.transport.file.FileTransporterFactory @@ -20,6 +26,7 @@ import org.eclipse.aether.transport.http.HttpTransporterFactory import static io.codearte.accurest.stubrunner.util.ZipCategory.unzipTo import static java.nio.file.Files.createTempDirectory + /** * @author Mariusz Smykula */ @@ -68,6 +75,7 @@ class AetherStubDownloader implements StubDownloader { private RepositorySystemSession newSession(RepositorySystem system) { DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); + session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS) LocalRepository localRepo = new LocalRepository(System.getProperty(MAVEN_LOCAL_REPOSITORY_LOCATION, "${System.getProperty("user.home")}/.m2/repository")); session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); return session; @@ -109,15 +117,15 @@ class AetherStubDownloader implements StubDownloader { } @Override - Map.Entry downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration) { + Map.Entry downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration) { String version = getVersion(stubConfiguration.groupId, stubConfiguration.artifactId, stubConfiguration.version, stubConfiguration.classifier) File unpackedJar = unpackedJar(version, stubConfiguration.groupId, stubConfiguration.artifactId, stubConfiguration.classifier, options.stubRepositoryRoot) - if(!unpackedJar) { + if (!unpackedJar) { return null } return new AbstractMap.SimpleEntry(new StubConfiguration(stubConfiguration.groupId, stubConfiguration.artifactId, version, stubConfiguration.classifier), - unpackedJar) + unpackedJar) } private String resolveHighestArtifactVersion(String stubsGroup, String stubsModule, String classifier) { From 89dd8c034a32b043f94c956ebfc2e21eb3a9c93f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 31 May 2016 09:02:04 +0200 Subject: [PATCH 665/719] Added array size assertion (#283) Fixes #279 --- .../dsl/WireMockRequestStubStrategy.groovy | 2 +- .../util/DelegatingJsonVerifiable.java | 68 +++++++++++++++---- .../FinishedDelegatingJsonVerifiable.java | 8 +-- .../util/JsonToJsonPathsConverter.groovy | 31 +++++++++ .../util/MethodBufferingJsonVerifiable.java | 4 ++ .../JaxRsClientMethodBuilderSpec.groovy | 1 + .../MockMvcMethodBodyBuilderSpec.groovy | 4 ++ .../util/JsonToJsonPathsConverterSpec.groovy | 38 +++++++++-- gradle.properties | 2 +- 9 files changed, 131 insertions(+), 27 deletions(-) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy index 59d252a30c..07955fc699 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy @@ -72,7 +72,7 @@ class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { requestPattern.bodyPatterns = [new ValuePattern(jsonCompareMode: org.skyscreamer.jsonassert.JSONCompareMode.LENIENT, equalToJson: JsonOutput.toJson(getMatchingStrategy(request.body.clientValue).clientValue) ) ] } else { - requestPattern.bodyPatterns = values.collect { new ValuePattern(matchesJsonPath: it.jsonPath().replace("\\\\", "\\")) } ?: null as List + requestPattern.bodyPatterns = values.findAll{ !it.assertsSize() }.collect { new ValuePattern(matchesJsonPath: it.jsonPath().replace("\\\\", "\\")) } ?: null as List } } else if (contentType == ContentType.XML) { requestPattern.bodyPatterns = [new ValuePattern(equalToXml: getMatchingStrategy(request.body.clientValue).clientValue.toString())] diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java index bd41fa1c78..0b927452cb 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java @@ -1,8 +1,9 @@ package io.codearte.accurest.util; -import com.toomuchcoding.jsonassert.JsonVerifiable; - import java.util.LinkedList; +import java.util.regex.Pattern; + +import com.toomuchcoding.jsonassert.JsonVerifiable; import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; @@ -11,18 +12,21 @@ import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; */ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { - private final JsonVerifiable delegate; - private final LinkedList methodsBuffer; + private static final Pattern FIELD_PATTERN = Pattern.compile("\\.field\\((\")?(.)+(\")?\\)"); + private static final Pattern ARRAY_PATTERN = Pattern.compile("\\.array\\((\")?(.)+(\")?\\)"); + + final JsonVerifiable delegate; + final LinkedList methodsBuffer; DelegatingJsonVerifiable(JsonVerifiable delegate, LinkedList methodsBuffer) { this.delegate = delegate; - this.methodsBuffer = new LinkedList(methodsBuffer); + this.methodsBuffer = new LinkedList<>(methodsBuffer); } DelegatingJsonVerifiable(JsonVerifiable delegate) { this.delegate = delegate; - this.methodsBuffer = new LinkedList(); + this.methodsBuffer = new LinkedList<>(); } private static String stringWithEscapedQuotes(Object object) { @@ -32,7 +36,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { private static String wrapValueWithQuotes(Object value) { return value instanceof String ? - "\"" + stringWithEscapedQuotes((String) value) + "\"" : + "\"" + stringWithEscapedQuotes(value) + "\"" : value.toString(); } @@ -103,6 +107,13 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { return verifiable; } + @Override + public JsonVerifiable elementWithIndex(int i) { + DelegatingJsonVerifiable verifiable = new DelegatingJsonVerifiable(delegate.elementWithIndex(i), methodsBuffer); + verifiable.methodsBuffer.offer(".elementWithIndex(" + i + ")"); + return verifiable; + } + @Override public MethodBufferingJsonVerifiable iterationPassingArray() { return new DelegatingJsonVerifiable(delegate, methodsBuffer); @@ -183,6 +194,26 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { return new FinishedDelegatingJsonVerifiable(delegate, methodsBuffer); } + @Override + public boolean assertsSize() { + for (String s : methodsBuffer) { + if (s.contains(".hasSize(")) { + return true; + } + } + return false; + } + + @Override + public boolean assertsConcreteValue() { + for (String s : methodsBuffer) { + if (FIELD_PATTERN.matcher(s).matches()|| ARRAY_PATTERN.matcher(s).matches()) { + return true; + } + } + return false; + } + @Override public JsonVerifiable withoutThrowingException() { return delegate.withoutThrowingException(); @@ -198,6 +229,13 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { delegate.matchesJsonPath(s); } + @Override + public JsonVerifiable hasSize(int size) { + FinishedDelegatingJsonVerifiable verifiable = new FinishedDelegatingJsonVerifiable(delegate.hasSize(size), methodsBuffer); + verifiable.methodsBuffer.offer(".hasSize(" + size + ")"); + return verifiable; + } + @Override public boolean isIteratingOverNamelessArray() { return delegate.isIteratingOverNamelessArray(); @@ -219,7 +257,7 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { } private String createMethodString() { - LinkedList queue = new LinkedList(methodsBuffer); + LinkedList queue = new LinkedList<>(methodsBuffer); StringBuilder stringBuffer = new StringBuilder(); while (!queue.isEmpty()) { stringBuffer.append(queue.remove()); @@ -238,17 +276,19 @@ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { if (delegate != null ? !delegate.equals(that.delegate) : that.delegate != null) return false; - return methodsBuffer != null ? - methodsBuffer.equals(that.methodsBuffer) : - that.methodsBuffer == null; + if (delegate == null) { + return false; + } + if (delegate.jsonPath() == null && that.delegate.jsonPath() == null) + return true; + return delegate.jsonPath().equals(that.delegate.jsonPath()); } @Override public int hashCode() { - int result = delegate != null ? delegate.hashCode() : 0; - result = 31 * result + (methodsBuffer != null ? methodsBuffer.hashCode() : 0); - return result; + int result = delegate != null ? delegate.jsonPath().hashCode() : 0; + return 31 * result; } @Override diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java index abf0678d07..8b89f4ea4b 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java @@ -1,9 +1,9 @@ package io.codearte.accurest.util; -import com.toomuchcoding.jsonassert.JsonVerifiable; - import java.util.LinkedList; +import com.toomuchcoding.jsonassert.JsonVerifiable; + /** * @author Marcin Grzejszczak */ @@ -14,8 +14,4 @@ class FinishedDelegatingJsonVerifiable extends DelegatingJsonVerifiable { super(delegate, methodsBuffer); } - FinishedDelegatingJsonVerifiable(JsonVerifiable delegate) { - super(delegate, new LinkedList()); - } - } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy index ae7558b952..131dde47e1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy @@ -7,11 +7,22 @@ import io.codearte.accurest.dsl.internal.ExecutionProperty import io.codearte.accurest.dsl.internal.OptionalProperty import java.util.regex.Pattern + /** + * I would like to apologize to anyone who is reading this class. Since JSON is a hectic structure + * this class is also hectic. The idea is to traverse the JSON structure and build a set of + * JSON Paths together with methods needed to be called to build them. + * * @author Marcin Grzejszczak */ class JsonToJsonPathsConverter { + /** + * In case of issues with size assertion just provide this property as system property + * equal to "false" and then size assertion will be disabled + */ + private static final String SIZE_ASSERTION_SYSTEM_PROP = "accurest.assert.size" + private static final Boolean SERVER_SIDE = false private static final Boolean CLIENT_SIDE = true @@ -61,18 +72,21 @@ class JsonToJsonPathsConverter { return convertWithKey(Map, key, value as Map, closure) // JSON with a list of primitives ["a", "b", "c"] in root issue #266 } else if (key.isIteratingOverNamelessArray() && value instanceof List && listContainsOnlyPrimitives(value)) { + addSizeVerificationForListWithPrimitives(key, closure, value) value.each { traverseRecursively(Object, key.arrayField().contains(ContentUtils.returnParsedObject(it)), ContentUtils.returnParsedObject(it), closure) } // JSON containing list of primitives { "partners":[ { "role":"AGENT", "payment_methods":[ "BANK", "CASH" ] } ] } else if (value instanceof List && listContainsOnlyPrimitives(value)) { + addSizeVerificationForListWithPrimitives(key, closure, value) value.each { traverseRecursively(Object, valueToAsserter(key.arrayField(), ContentUtils.returnParsedObject(it)), ContentUtils.returnParsedObject(it), closure) } } else if (value instanceof List) { MethodBufferingJsonVerifiable jsonPathVerifiable = createAsserterFromList(key, value) + addSizeVerificationForListWithPrimitives(key, closure, value) value.each { def element -> traverseRecursively(List, createAsserterFromListElement(jsonPathVerifiable, ContentUtils.returnParsedObject(element)), ContentUtils.returnParsedObject(element), closure) @@ -89,6 +103,23 @@ class JsonToJsonPathsConverter { } } + // Size verification: https://github.com/Codearte/accurest/issues/279 + private static void addSizeVerificationForListWithPrimitives(MethodBufferingJsonVerifiable key, Closure closure, List value) { + if (System.getProperty(SIZE_ASSERTION_SYSTEM_PROP, "true") == "false") { + return + } + if (isRootElement(key) || key.assertsConcreteValue()) { + if (value.size() > 0) { + closure(key.hasSize(value.size()), value) + } + } + } + + private static boolean isRootElement(MethodBufferingJsonVerifiable key) { + return key.jsonPath() == '$' + } + + // If you have a list of not-only primitives it can contain different sets of elements (maps, lists, primitives) private static MethodBufferingJsonVerifiable createAsserterFromList(MethodBufferingJsonVerifiable key, List value) { if (key.isIteratingOverNamelessArray()) { return key.array() diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java index 49e0234cb0..df22b85bc8 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java +++ b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java @@ -46,4 +46,8 @@ public interface MethodBufferingJsonVerifiable @Override MethodBufferingJsonVerifiable value(); + + boolean assertsSize(); + + boolean assertsConcreteValue(); } diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy index 59a33c47c1..38a6a8b442 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy @@ -98,6 +98,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub then: blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").hasSize(2)""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy index f42b7ef95a..538125006e 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -166,6 +166,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub then: blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("a")""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("a").isEqualTo("sth")""") + blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").hasSize(2)""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: stubMappingIsValidWireMockStub(contractDsl) @@ -1251,6 +1252,7 @@ World.'''""" builder.then(blockBuilder) def test = blockBuilder.toString() then: + test.contains('assertThatJson(parsedJson).hasSize(5)') test.contains('assertThatJson(parsedJson).arrayField().contains("Java8").value()') test.contains('assertThatJson(parsedJson).arrayField().contains("Spring").value()') test.contains('assertThatJson(parsedJson).arrayField().contains("Java").value()') @@ -1284,6 +1286,7 @@ World.'''""" builder.then(blockBuilder) def test = blockBuilder.toString() then: + test.contains('assertThatJson(parsedJson).hasSize(2)') test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Programming").value()') test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Java").value()') test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Spring").value()') @@ -1293,6 +1296,7 @@ World.'''""" "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } + @Issue('47') def "should generate async body when async flag set in response"() { given: diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy index 1645aa7475..5cfdfab42d 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy @@ -353,12 +353,16 @@ class JsonToJsonPathsConverterSpec extends Specification { it.method()== """.array("property2").contains("a").isEqualTo("sth")""" && it.jsonPath() == """\$.property2[*][?(@.a == 'sth')]""" } + pathAndValues.find { + it.method()== """.array("property2").hasSize(2)""" && + it.jsonPath() == """\$.property2[*]""" + } pathAndValues.find { it.method()== """.array("property2").contains("b").isEqualTo("sthElse")""" && it.jsonPath() == """\$.property2[*][?(@.b == 'sthElse')]""" } and: - pathAndValues.size() == 3 + pathAndValues.size() == 4 } def "should generate assertions for a response body containing map with integers as keys"() { @@ -404,8 +408,12 @@ class JsonToJsonPathsConverterSpec extends Specification { it.method()== """.array().contains("property2").isEqualTo("b")""" && it.jsonPath() == """\$[*][?(@.property2 == 'b')]""" } + pathAndValues.find { + it.method()== """.hasSize(2)""" && + it.jsonPath() == """\$""" + } and: - pathAndValues.size() == 2 + pathAndValues.size() == 3 } def "should generate assertions for array inside response body element"() { @@ -427,8 +435,12 @@ class JsonToJsonPathsConverterSpec extends Specification { it.method()== """.array("property1").contains("property3").isEqualTo("test2")""" && it.jsonPath() == """\$.property1[*][?(@.property3 == 'test2')]""" } + pathAndValues.find { + it.method()== """.array("property1").hasSize(2)""" && + it.jsonPath() == """\$.property1[*]""" + } and: - pathAndValues.size() == 2 + pathAndValues.size() == 3 } def "should generate assertions for nested objects in response body"() { @@ -509,8 +521,12 @@ class JsonToJsonPathsConverterSpec extends Specification { it.method()== """.array("errors").contains("message").isEqualTo("incorrect_format")""" && it.jsonPath() == """\$.errors[*][?(@.message == 'incorrect_format')]""" } + pathAndValues.find { + it.method()== """.array("errors").hasSize(1)""" && + it.jsonPath() == """\$.errors[*]""" + } and: - pathAndValues.size() == 2 + pathAndValues.size() == 3 } def "should manage to parse a double array"() { @@ -549,8 +565,20 @@ class JsonToJsonPathsConverterSpec extends Specification { it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(38.791645)""" && it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*][?(@ == 38.791645)]""" } + pathAndValues.find { + it.method()== """.hasSize(1)""" && + it.jsonPath() == """\$""" + } + pathAndValues.find { + it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().hasSize(2)""" && + it.jsonPath() == """\$[*].place.bounding_box.coordinates[*][*]""" + } + pathAndValues.find { + it.method()== """.array().field("place").field("bounding_box").array("coordinates").hasSize(1)""" && + it.jsonPath() == """\$[*].place.bounding_box.coordinates[*]""" + } and: - pathAndValues.size() == 4 + pathAndValues.size() == 7 and: pathAndValues.each { JsonAssertion.assertThat(json).matchesJsonPath(it.jsonPath()) diff --git a/gradle.properties b/gradle.properties index 45a95579c1..f9a69c8932 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ nexusUsername = nexusPassword = wiremockVersion = 2.0.10-beta -jsonassertVersion = 0.4.5 +jsonassertVersion = 0.4.7 BOM_VERSION=Brixton-1.0.0.RC1 springBootVersion=1.3.3.RELEASE From cc3bf2d838fb853450335c8462e01c9fdc5eb477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 31 May 2016 09:16:01 +0200 Subject: [PATCH 666/719] add support for versions like CD-001 and offline fixes (#282) --- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ---- .../streamService/maven-metadata-local.xml | 12 ---- .../stubrunner/junit/AccurestRuleSpec.groovy | 2 +- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ---- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ---- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ---- .../fraudDetectionServer/maven-metadata.xml} | 0 .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ---- .../stubs/loanIssuance/maven-metadata.xml} | 0 .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ---- .../maven-metadata-local.xml | 12 ---- .../fraudDetectionServer/maven-metadata.xml} | 0 .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 ---- .../loanIssuance/maven-metadata-local.xml | 12 ---- .../stubs/loanIssuance/maven-metadata.xml} | 0 .../stubrunner/AetherStubDownloader.groovy | 56 +++++++++---------- .../accurest/stubrunner/StubDownloader.groovy | 4 -- 17 files changed, 26 insertions(+), 156 deletions(-) delete mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml rename stub-runner/{stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml => stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml} (100%) delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml rename stub-runner/{stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml => stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml} (100%) delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml rename stub-runner/{stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml => stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml} (100%) delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml rename stub-runner/{stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml => stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml} (100%) diff --git a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index bad844ba2a..0000000000 --- a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - streamService - 0.0.1-SNAPSHOT - - - true - - 20160409062112 - - diff --git a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml deleted file mode 100644 index dc32790f53..0000000000 --- a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - streamService - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy index a8bbca3cbd..7b5ee643fd 100644 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy +++ b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy @@ -20,7 +20,7 @@ class AccurestRuleSpec extends Specification { // tag::classrule[] @ClassRule @Shared AccurestRule rule = new AccurestRule() - .repoRoot(AccurestRuleSpec.getResource("/m2repo").toURI().toString()) + .repoRoot(AccurestRuleSpec.getResource("/m2repo/repository").toURI().toString()) .downloadStub("io.codearte.accurest.stubs", "loanIssuance") .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 0bd6282c8e..0000000000 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - - - true - - 20160409062112 - - diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 5220bd8f0a..0000000000 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - - - true - - 20160409062111 - - diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 0bd6282c8e..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - - - true - - 20160409062112 - - diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml similarity index 100% rename from stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml rename to stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 5220bd8f0a..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - - - true - - 20160409062111 - - diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml similarity index 100% rename from stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml rename to stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 0bd6282c8e..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - - - true - - 20160409062112 - - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml deleted file mode 100644 index d4ab9afc83..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml similarity index 100% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata-local.xml rename to stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 5220bd8f0a..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - - - true - - 20160409062111 - - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml deleted file mode 100644 index bf14a1ad21..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062111 - - diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml similarity index 100% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata-local.xml rename to stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy index 46f8dee7f8..a01aa9211f 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy @@ -37,29 +37,21 @@ class AetherStubDownloader implements StubDownloader { private static final String MAVEN_LOCAL_REPOSITORY_LOCATION = 'maven.repo.local' private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest' private static final String ARTIFACT_EXTENSION = 'jar' - private static final String LATEST_ARTIFACT_VERSION = '(0,]' + private static final String LATEST_ARTIFACT_VERSION = '(,]' private static final String LATEST_VERSION_IN_IVY = "+" private final List remoteRepos private final RepositorySystem repositorySystem private final RepositorySystemSession session - AetherStubDownloader(RepositorySystem repositorySystem, List repositories, RepositorySystemSession session) { - this.remoteRepos = repositories - this.repositorySystem = repositorySystem ?: newRepositorySystem() - this.session = session ?: newSession(this.repositorySystem) - } - AetherStubDownloader(StubRunnerOptions stubRunnerOptions) { this.remoteRepos = remoteRepositories(stubRunnerOptions) + log.info("Download using remote repositories $remoteRepos") this.repositorySystem = newRepositorySystem() - this.session = newSession(this.repositorySystem) + this.session = newSession(this.repositorySystem, stubRunnerOptions.workOffline) } private List remoteRepositories(StubRunnerOptions stubRunnerOptions) { - if (stubRunnerOptions.workOffline || !stubRunnerOptions.stubRepositoryRoot) { - return [] - } return stubRunnerOptions.stubRepositoryRoot.split(',').collect { String repo -> new RemoteRepository.Builder("remote", "default", repo).build() } @@ -73,35 +65,34 @@ class AetherStubDownloader implements StubDownloader { return locator.getService(RepositorySystem) } - private RepositorySystemSession newSession(RepositorySystem system) { - DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession(); + private RepositorySystemSession newSession(RepositorySystem system, boolean workOffline) { + DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession() session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS) - LocalRepository localRepo = new LocalRepository(System.getProperty(MAVEN_LOCAL_REPOSITORY_LOCATION, "${System.getProperty("user.home")}/.m2/repository")); - session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)); - return session; + session.setOffline(workOffline) + LocalRepository localRepo = new LocalRepository(localRepositoryDirectory()) + session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)) + return session } - @Override - public File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String stubsModule, String classifier) { - String version = getVersion(stubsGroup, stubsModule, LATEST_VERSION_IN_IVY, classifier) - return unpackedJar(version, stubsGroup, stubsModule, classifier, stubRepositoryRoot) + private String localRepositoryDirectory() { + System.getProperty(MAVEN_LOCAL_REPOSITORY_LOCATION, "${System.getProperty("user.home")}/.m2/repository") } - private File unpackedJar(String resolvedVersion, String stubsGroup, String stubsModule, String classifier, String stubRepositoryRoot) { - log.info("Resolved version is $resolvedVersion") + private File unpackedJar(String resolvedVersion, String stubsGroup, String stubsModule, String classifier) { + log.info("Resolved version is [$resolvedVersion]") if (!resolvedVersion) { - log.warn("Stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] not found in [$stubRepositoryRoot]") + log.warn("Stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] not found in $remoteRepos") return null } Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, resolvedVersion) ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos) - log.info("Resolving artifact $artifact from ${remoteRepos ?: 'local maven repo'}") + log.info("Resolving artifact $artifact using repository $remoteRepos") try { ArtifactResult result = repositorySystem.resolveArtifact(session, request) - log.info("Resolved artifact $artifact to ${result.artifact.file} from ${result.repository}") + log.info("Resolved artifact $artifact to ${result.artifact.file}") return unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) } catch (Exception e) { - log.warn("Exception occured while trying to download a stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] in [$stubRepositoryRoot]", e) + log.warn("Exception occured while trying to download a stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] in $remoteRepos", e) return null } @@ -110,7 +101,7 @@ class AetherStubDownloader implements StubDownloader { private String getVersion(String stubsGroup, String stubsModule, String version, String classifier) { if (!version || LATEST_VERSION_IN_IVY == version) { log.info("Desired version is [$version] - will try to resolve the latest version") - return resolveHighestArtifactVersion(stubsGroup, stubsModule, classifier); + return resolveHighestArtifactVersion(stubsGroup, stubsModule, classifier) } log.info("Will try to resolve version [$version]") return resolveArtifactVersion(stubsGroup, stubsModule, version, classifier) @@ -120,7 +111,7 @@ class AetherStubDownloader implements StubDownloader { Map.Entry downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration) { String version = getVersion(stubConfiguration.groupId, stubConfiguration.artifactId, stubConfiguration.version, stubConfiguration.classifier) File unpackedJar = unpackedJar(version, stubConfiguration.groupId, stubConfiguration.artifactId, - stubConfiguration.classifier, options.stubRepositoryRoot) + stubConfiguration.classifier) if (!unpackedJar) { return null } @@ -130,15 +121,18 @@ class AetherStubDownloader implements StubDownloader { private String resolveHighestArtifactVersion(String stubsGroup, String stubsModule, String classifier) { Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, LATEST_ARTIFACT_VERSION) - VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, remoteRepos, null); - VersionRangeResult rangeResult = repositorySystem.resolveVersionRange(session, versionRangeRequest); + VersionRangeRequest versionRangeRequest = new VersionRangeRequest(artifact, remoteRepos, null) + VersionRangeResult rangeResult = repositorySystem.resolveVersionRange(session, versionRangeRequest) + if (!rangeResult.highestVersion) { + log.error("Version was not resolved!") + } return rangeResult.highestVersion ?: '' } private String resolveArtifactVersion(String stubsGroup, String stubsModule, String version, String classifier) { Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, version) VersionRequest versionRequest = new VersionRequest(artifact, remoteRepos, null) - VersionResult versionResult = repositorySystem.resolveVersion(session, versionRequest); + VersionResult versionResult = repositorySystem.resolveVersion(session, versionRequest) return versionResult.version ?: '' } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy index def3d78ae6..e3391a67ef 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy @@ -2,10 +2,6 @@ package io.codearte.accurest.stubrunner interface StubDownloader { - @Deprecated - File downloadAndUnpackStubJar(boolean workOffline, String stubRepositoryRoot, String stubsGroup, String - stubsModule, String classifier) - /** * Returns a mapping of updated StubConfiguration (it will contain the resolved version) and the location of the downloaded JAR. * If there was no artifact this method will return {@code null}. From b6a87ce1ae7e2c76522bad455b9d27bbf8d142d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Tue, 31 May 2016 21:45:27 +0200 Subject: [PATCH 667/719] stub downloader cleanup (#284) * ivy removed * better logging --- stub-runner/stub-runner/build.gradle | 1 - .../stubrunner/AetherStubDownloader.groovy | 24 ++++++++++++------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/stub-runner/stub-runner/build.gradle b/stub-runner/stub-runner/build.gradle index 40d00f3308..c633e222aa 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/stub-runner/stub-runner/build.gradle @@ -6,7 +6,6 @@ mainClassName = 'io.codearte.accurest.stubrunner.StubRunnerMain' dependencies { compile project(':accurest-core') compile project(':accurest-messaging-root:accurest-messaging-core') - compile 'org.apache.ivy:ivy:2.4.0' compile 'org.codehaus.groovy:groovy-all:2.4.4' compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile 'javax.servlet:javax.servlet-api:3.1.0' diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy index a01aa9211f..df26c01e27 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy @@ -38,22 +38,27 @@ class AetherStubDownloader implements StubDownloader { private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest' private static final String ARTIFACT_EXTENSION = 'jar' private static final String LATEST_ARTIFACT_VERSION = '(,]' - private static final String LATEST_VERSION_IN_IVY = "+" + private static final String LATEST_VERSION_IN_IVY = '+' private final List remoteRepos private final RepositorySystem repositorySystem private final RepositorySystemSession session AetherStubDownloader(StubRunnerOptions stubRunnerOptions) { - this.remoteRepos = remoteRepositories(stubRunnerOptions) - log.info("Download using remote repositories $remoteRepos") + remoteRepos = remoteRepositories(stubRunnerOptions) + if (!remoteRepos) { + log.error('Remote repositories for stubs are not specified!') + } this.repositorySystem = newRepositorySystem() this.session = newSession(this.repositorySystem, stubRunnerOptions.workOffline) } private List remoteRepositories(StubRunnerOptions stubRunnerOptions) { - return stubRunnerOptions.stubRepositoryRoot.split(',').collect { String repo -> - new RemoteRepository.Builder("remote", "default", repo).build() + return stubRunnerOptions.stubRepositoryRoot.split(',') + .toList().withIndex() + .findAll { String repo, int index -> repo } + .collect { String repo, int index -> + new RemoteRepository.Builder('remote' + index, 'default', repo).build() } } @@ -67,8 +72,11 @@ class AetherStubDownloader implements StubDownloader { private RepositorySystemSession newSession(RepositorySystem system, boolean workOffline) { DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession() - session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS) - session.setOffline(workOffline) + if (workOffline) { + session.setOffline(workOffline) + } else { + session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS) + } LocalRepository localRepo = new LocalRepository(localRepositoryDirectory()) session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)) return session @@ -86,7 +94,7 @@ class AetherStubDownloader implements StubDownloader { } Artifact artifact = new DefaultArtifact(stubsGroup, stubsModule, classifier, ARTIFACT_EXTENSION, resolvedVersion) ArtifactRequest request = new ArtifactRequest(artifact: artifact, repositories: remoteRepos) - log.info("Resolving artifact $artifact using repository $remoteRepos") + log.info("Resolving artifact '$artifact' using remote repositories $remoteRepos.url") try { ArtifactResult result = repositorySystem.resolveArtifact(session, request) log.info("Resolved artifact $artifact to ${result.artifact.file}") From 28a7764471185c1c1f18e637f32d5e69cf940fd6 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 1 Jun 2016 09:18:33 +0200 Subject: [PATCH 668/719] Release version: 1.1.0-M7 [ci skip] From 7520d7e95ef2187aeebecc2d9f78346f2ba62ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Thu, 2 Jun 2016 22:05:43 +0200 Subject: [PATCH 669/719] Missing constructor used by maven (#285) --- .../stubrunner/AetherFactories.groovy | 52 +++++++++++++++ .../stubrunner/AetherStubDownloader.groovy | 66 +++++++------------ 2 files changed, 76 insertions(+), 42 deletions(-) create mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherFactories.groovy diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherFactories.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherFactories.groovy new file mode 100644 index 0000000000..4999d49b93 --- /dev/null +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherFactories.groovy @@ -0,0 +1,52 @@ +package io.codearte.accurest.stubrunner + +import org.apache.maven.repository.internal.MavenRepositorySystemUtils +import org.eclipse.aether.DefaultRepositorySystemSession +import org.eclipse.aether.RepositorySystem +import org.eclipse.aether.RepositorySystemSession +import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory +import org.eclipse.aether.impl.DefaultServiceLocator +import org.eclipse.aether.repository.LocalRepository +import org.eclipse.aether.repository.RemoteRepository +import org.eclipse.aether.repository.RepositoryPolicy +import org.eclipse.aether.spi.connector.RepositoryConnectorFactory +import org.eclipse.aether.spi.connector.transport.TransporterFactory +import org.eclipse.aether.transport.file.FileTransporterFactory +import org.eclipse.aether.transport.http.HttpTransporterFactory + +class AetherFactories { + + private static final String MAVEN_LOCAL_REPOSITORY_LOCATION = 'maven.repo.local' + + static RepositorySystem newRepositorySystem() { + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator() + locator.addService(RepositoryConnectorFactory, BasicRepositoryConnectorFactory) + locator.addService(TransporterFactory, FileTransporterFactory) + locator.addService(TransporterFactory, HttpTransporterFactory) + return locator.getService(RepositorySystem) + } + + static RepositorySystemSession newSession(RepositorySystem system, boolean workOffline) { + DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession() + session.setOffline(workOffline) + if (!workOffline) { + session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS) + } + LocalRepository localRepo = new LocalRepository(localRepositoryDirectory()) + session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)) + return session + } + + static List newRepositories(List repositories) { + return repositories.withIndex() + .findAll { String repo, int index -> repo } + .collect { String repo, int index -> + new RemoteRepository.Builder('remote' + index, 'default', repo).build() + } + } + + static String localRepositoryDirectory() { + System.getProperty(MAVEN_LOCAL_REPOSITORY_LOCATION, "${System.getProperty("user.home")}/.m2/repository") + } + +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy index df26c01e27..271d98cceb 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy +++ b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy @@ -2,28 +2,21 @@ package io.codearte.accurest.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import org.apache.maven.repository.internal.MavenRepositorySystemUtils -import org.eclipse.aether.DefaultRepositorySystemSession import org.eclipse.aether.RepositorySystem import org.eclipse.aether.RepositorySystemSession import org.eclipse.aether.artifact.Artifact import org.eclipse.aether.artifact.DefaultArtifact -import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory -import org.eclipse.aether.impl.DefaultServiceLocator -import org.eclipse.aether.repository.LocalRepository import org.eclipse.aether.repository.RemoteRepository -import org.eclipse.aether.repository.RepositoryPolicy import org.eclipse.aether.resolution.ArtifactRequest import org.eclipse.aether.resolution.ArtifactResult import org.eclipse.aether.resolution.VersionRangeRequest import org.eclipse.aether.resolution.VersionRangeResult import org.eclipse.aether.resolution.VersionRequest import org.eclipse.aether.resolution.VersionResult -import org.eclipse.aether.spi.connector.RepositoryConnectorFactory -import org.eclipse.aether.spi.connector.transport.TransporterFactory -import org.eclipse.aether.transport.file.FileTransporterFactory -import org.eclipse.aether.transport.http.HttpTransporterFactory +import static io.codearte.accurest.stubrunner.AetherFactories.newRepositories +import static io.codearte.accurest.stubrunner.AetherFactories.newRepositorySystem +import static io.codearte.accurest.stubrunner.AetherFactories.newSession import static io.codearte.accurest.stubrunner.util.ZipCategory.unzipTo import static java.nio.file.Files.createTempDirectory @@ -34,7 +27,6 @@ import static java.nio.file.Files.createTempDirectory @Slf4j class AetherStubDownloader implements StubDownloader { - private static final String MAVEN_LOCAL_REPOSITORY_LOCATION = 'maven.repo.local' private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest' private static final String ARTIFACT_EXTENSION = 'jar' private static final String LATEST_ARTIFACT_VERSION = '(,]' @@ -45,7 +37,7 @@ class AetherStubDownloader implements StubDownloader { private final RepositorySystemSession session AetherStubDownloader(StubRunnerOptions stubRunnerOptions) { - remoteRepos = remoteRepositories(stubRunnerOptions) + this.remoteRepos = remoteRepositories(stubRunnerOptions) if (!remoteRepos) { log.error('Remote repositories for stubs are not specified!') } @@ -53,37 +45,27 @@ class AetherStubDownloader implements StubDownloader { this.session = newSession(this.repositorySystem, stubRunnerOptions.workOffline) } + /** + * Used by Accurest Maven Plugin + * + * @param repositorySystem + * @param remoteRepositories - remote artifact repositories + * @param session + * @param workOffline + */ + AetherStubDownloader(RepositorySystem repositorySystem, + List remoteRepositories, + RepositorySystemSession session) { + this.remoteRepos = remoteRepositories + this.repositorySystem = repositorySystem + this.session = session + if (!remoteRepos) { + log.error('Remote remoteRepositories for stubs are not specified!') + } + } + private List remoteRepositories(StubRunnerOptions stubRunnerOptions) { - return stubRunnerOptions.stubRepositoryRoot.split(',') - .toList().withIndex() - .findAll { String repo, int index -> repo } - .collect { String repo, int index -> - new RemoteRepository.Builder('remote' + index, 'default', repo).build() - } - } - - private RepositorySystem newRepositorySystem() { - DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator() - locator.addService(RepositoryConnectorFactory, BasicRepositoryConnectorFactory) - locator.addService(TransporterFactory, FileTransporterFactory) - locator.addService(TransporterFactory, HttpTransporterFactory) - return locator.getService(RepositorySystem) - } - - private RepositorySystemSession newSession(RepositorySystem system, boolean workOffline) { - DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession() - if (workOffline) { - session.setOffline(workOffline) - } else { - session.setUpdatePolicy(RepositoryPolicy.UPDATE_POLICY_ALWAYS) - } - LocalRepository localRepo = new LocalRepository(localRepositoryDirectory()) - session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo)) - return session - } - - private String localRepositoryDirectory() { - System.getProperty(MAVEN_LOCAL_REPOSITORY_LOCATION, "${System.getProperty("user.home")}/.m2/repository") + return newRepositories(stubRunnerOptions.stubRepositoryRoot.split(',').toList()) } private File unpackedJar(String resolvedVersion, String stubsGroup, String stubsModule, String classifier) { From 601729de3ddc75ed0450279b46d4f695688c21d2 Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Thu, 2 Jun 2016 22:07:08 +0200 Subject: [PATCH 670/719] Release version: 1.1.0-M8 [ci skip] From 56222186fc00a6f0b96ef97c03bd5c6e5748654c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Thu, 2 Jun 2016 22:57:35 +0200 Subject: [PATCH 671/719] accurest update (#27) --- pom.xml | 9 ++------- .../groovy/io/codearte/accurest/maven/RunMojo.groovy | 4 +++- src/test/projects/complex-configuration/pom.xml | 2 +- src/test/projects/plugin-extension/pom.xml | 4 ++-- src/test/projects/spring-boot-groovy/pom.xml | 2 +- src/test/projects/spring-boot-java/pom.xml | 4 ++-- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 193e31cdbe..f9ac7d2891 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ UTF-8 UTF-8 - 1.1.0-M6 + 1.1.0-M8 1.1.0 1.7 @@ -291,12 +291,7 @@ ${aether.version} provided - - com.toomuchcoding.jsonassert - jsonassert - 0.3.0 - test - + org.apache.maven.shared maven-filtering diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy index 14c6d710b6..cfa0248e5d 100644 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy @@ -74,7 +74,9 @@ class RunMojo extends AbstractMojo { StubRunner stubRunner = localStubRunner.run(resolveStubsDirectory().absolutePath, options) batchStubRunner = new BatchStubRunner(Arrays.asList(stubRunner)) } else { - StubRunnerOptions options = optionsBuilder.withMinMaxPort(minPort, maxPort).build() + StubRunnerOptions options = optionsBuilder + .withStubs(stubs) + .withMinMaxPort(minPort, maxPort).build() batchStubRunner = remoteStubRunner.run(options, repoSession) } diff --git a/src/test/projects/complex-configuration/pom.xml b/src/test/projects/complex-configuration/pom.xml index a96596d6df..2561e2254c 100644 --- a/src/test/projects/complex-configuration/pom.xml +++ b/src/test/projects/complex-configuration/pom.xml @@ -45,7 +45,7 @@ com.toomuchcoding.jsonassert jsonassert - 0.4.1 + 0.4.6 test diff --git a/src/test/projects/plugin-extension/pom.xml b/src/test/projects/plugin-extension/pom.xml index cebe6bce3e..647e9b5dae 100644 --- a/src/test/projects/plugin-extension/pom.xml +++ b/src/test/projects/plugin-extension/pom.xml @@ -45,13 +45,13 @@ com.toomuchcoding.jsonassert jsonassert - 0.4.1 + 0.4.6 test org.assertj assertj-core - 2.4.0 + 2.4.1 test diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index fcc5045b80..e4a1112ff9 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -46,7 +46,7 @@ com.toomuchcoding.jsonassert jsonassert - 0.4.1 + 0.4.6 test diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index ecda0561c2..e9562a557a 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -45,13 +45,13 @@ com.toomuchcoding.jsonassert jsonassert - 0.4.1 + 0.4.6 test org.assertj assertj-core - 2.4.0 + 2.4.1 test From d23ed76d6843cdb5a6260b7530b4a49dbecd2d6f Mon Sep 17 00:00:00 2001 From: Travis CI Date: Thu, 2 Jun 2016 21:02:52 +0000 Subject: [PATCH 672/719] Sets project version to 0.6.10-SNAPSHOT [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f9ac7d2891..7e685f7da8 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.9-SNAPSHOT + 0.6.10-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From a5627759802b86703e1eb082f87b915cfdf61c00 Mon Sep 17 00:00:00 2001 From: Olga Maciaszek-Sharma Date: Mon, 13 Jun 2016 21:31:00 +0200 Subject: [PATCH 673/719] Release version: 1.1.0 [ci skip] From 9901cbead6aa0aa9c219876b53ba642acc2deac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mariusz=20Smyku=C5=82a?= Date: Wed, 15 Jun 2016 21:43:31 +0200 Subject: [PATCH 674/719] Switch to stable accurest (#28) --- pom.xml | 2 +- src/test/projects/complex-configuration/pom.xml | 4 ++-- src/test/projects/plugin-extension/pom.xml | 4 ++-- src/test/projects/spring-boot-groovy/pom.xml | 4 ++-- src/test/projects/spring-boot-java/pom.xml | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 7e685f7da8..0b104f9f65 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ UTF-8 UTF-8 - 1.1.0-M8 + 1.1.0 1.1.0 1.7 diff --git a/src/test/projects/complex-configuration/pom.xml b/src/test/projects/complex-configuration/pom.xml index 2561e2254c..aa1e0fc4b3 100644 --- a/src/test/projects/complex-configuration/pom.xml +++ b/src/test/projects/complex-configuration/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 1.3.3.RELEASE + 1.3.5.RELEASE @@ -45,7 +45,7 @@ com.toomuchcoding.jsonassert jsonassert - 0.4.6 + 0.4.7 test diff --git a/src/test/projects/plugin-extension/pom.xml b/src/test/projects/plugin-extension/pom.xml index 647e9b5dae..dff0c4a439 100644 --- a/src/test/projects/plugin-extension/pom.xml +++ b/src/test/projects/plugin-extension/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 1.3.3.RELEASE + 1.3.5.RELEASE @@ -45,7 +45,7 @@ com.toomuchcoding.jsonassert jsonassert - 0.4.6 + 0.4.7 test diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index e4a1112ff9..ca332f3606 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 1.3.3.RELEASE + 1.3.5.RELEASE @@ -46,7 +46,7 @@ com.toomuchcoding.jsonassert jsonassert - 0.4.6 + 0.4.7 test diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index e9562a557a..9e9385e62c 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -10,7 +10,7 @@ org.springframework.boot spring-boot-starter-parent - 1.3.3.RELEASE + 1.3.5.RELEASE @@ -45,7 +45,7 @@ com.toomuchcoding.jsonassert jsonassert - 0.4.6 + 0.4.7 test From 23967900fa9ae6418982f0c387ad1009aca76f16 Mon Sep 17 00:00:00 2001 From: Travis CI Date: Wed, 15 Jun 2016 19:48:30 +0000 Subject: [PATCH 675/719] Sets project version to 0.6.11-SNAPSHOT [ci skip] --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0b104f9f65..0cba3e6e2a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.codearte.accurest accurest-maven-plugin maven-plugin - 0.6.10-SNAPSHOT + 0.6.11-SNAPSHOT Accurest Maven Plugin Accurest Maven Plugin From 957de2359187286979e2512533f40847c6e89a21 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 19 Jun 2016 23:49:03 +0200 Subject: [PATCH 676/719] Rebranding (#29) --- .mvn/settings.xml | 28 ---- .travis.yml | 28 +--- README.md | 8 +- mvnw | 21 ++- pom.xml | 148 ++++++++++++++--- src/etc/header.txt | 14 ++ .../accurest/maven/GenerateStubsMojo.groovy | 97 ----------- .../accurest/maven/GenerateTestsMojo.groovy | 119 -------------- .../io/codearte/accurest/maven/RunMojo.groovy | 110 ------------- .../maven/stubrunner/LocalStubRunner.groovy | 22 --- .../verifier}/maven/CopyContracts.groovy | 22 ++- .../verifier/maven/ManifestCreator.groovy | 36 +++++ .../AetherStubDownloaderFactory.groovy | 20 ++- .../maven/stubrunner/LocalStubRunner.groovy | 38 +++++ .../maven/stubrunner/RemoteStubRunner.groovy | 20 ++- .../contract/verifier/maven}/ConvertMojo.java | 66 ++++---- .../verifier/maven/GenerateStubsMojo.java | 100 ++++++++++++ .../verifier/maven/GenerateTestsMojo.java | 142 ++++++++++++++++ .../contract/verifier/maven/RunMojo.java | 151 ++++++++++++++++++ .../resources/META-INF/plexus/components.xml | 30 +++- src/site/asciidoc/index.adoc | 6 +- src/site/asciidoc/usage.adoc | 10 +- src/site/site.xml | 18 +++ .../contract/verifier}/maven/PluginIT.java | 43 +++-- .../verifier}/maven/PluginUnitTest.java | 44 +++-- src/test/projects/basic/pom.xml | 22 ++- .../test/resources/accurest/Messaging.groovy | 23 --- .../test/resources/contracts/Messaging.groovy | 37 +++++ .../test/resources/contracts/Sample.groovy | 34 ++++ .../projects/complex-configuration/pom.xml | 22 ++- .../frauddetection/Application.java | 16 ++ .../FraudDetectionController.java | 21 ++- .../frauddetection/model/FraudCheck.java | 16 ++ .../model/FraudCheckResult.java | 16 ++ .../model/FraudCheckStatus.java | 16 ++ .../src/test/accurest/brokenContract.groovy | 28 ---- .../accurest/shouldMarkClientAsFraud.groovy | 27 ---- .../shouldMarkClientAsNotFraud.groovy | 28 ---- .../src/test/contracts/brokenContract.groovy | 44 +++++ .../contracts/shouldMarkClientAsFraud.groovy | 43 +++++ .../shouldMarkClientAsNotFraud.groovy | 44 +++++ .../frauddetection/BaseAccurest.java | 20 ++- .../matchers/CustomMatchers.java | 16 ++ src/test/projects/generatedStubs/pom.xml | 22 ++- .../target/accurest/contracts/Sample.groovy | 18 --- .../target/stubs/contracts}/Sample.groovy | 2 +- .../{accurest => stubs}/mappings/Sample.json | 0 src/test/projects/plugin-extension/pom.xml | 22 ++- .../src/main/java/hello/Application.java | 16 ++ .../src/main/java/hello/Greeting.java | 16 ++ .../main/java/hello/GreetingController.java | 17 ++ .../src/test/java/hello/BaseAccurest.java | 17 ++ .../resources/accurest/greetings_ok.groovy | 21 --- .../greetings_with_default_value.groovy | 17 -- .../resources/contracts/greetings_ok.groovy | 37 +++++ .../greetings_with_default_value.groovy | 33 ++++ src/test/projects/pomless/Sample.groovy | 18 ++- src/test/projects/spring-boot-groovy/pom.xml | 24 ++- .../src/main/java/hello/Application.java | 16 ++ .../src/main/java/hello/Greeting.java | 16 ++ .../main/java/hello/GreetingController.java | 17 ++ .../src/test/groovy/hello/BaseAccurest.groovy | 16 ++ .../resources/accurest/greetings_ok.groovy | 21 --- .../greetings_with_default_value.groovy | 17 -- .../resources/contracts/greetings_ok.groovy | 37 +++++ .../greetings_with_default_value.groovy | 33 ++++ src/test/projects/spring-boot-java/pom.xml | 22 ++- .../src/main/java/hello/Application.java | 16 ++ .../src/main/java/hello/Greeting.java | 16 ++ .../main/java/hello/GreetingController.java | 17 ++ .../src/test/java/hello/BaseAccurest.java | 17 ++ .../resources/accurest/greetings_ok.groovy | 21 --- .../greetings_with_default_value.groovy | 17 -- .../resources/contracts/greetings_ok.groovy | 37 +++++ .../greetings_with_default_value.groovy | 33 ++++ src/test/projects/withStubs/pom.xml | 22 ++- .../src/test/resources/stubs/Sample.groovy | 18 ++- 77 files changed, 1729 insertions(+), 774 deletions(-) delete mode 100644 .mvn/settings.xml create mode 100644 src/etc/header.txt delete mode 100644 src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy delete mode 100644 src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy delete mode 100644 src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy delete mode 100644 src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy rename src/main/groovy/{io/codearte/accurest => org/springframework/cloud/contract/verifier}/maven/CopyContracts.groovy (67%) create mode 100644 src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy rename src/main/groovy/{io/codearte/accurest => org/springframework/cloud/contract/verifier}/maven/stubrunner/AetherStubDownloaderFactory.groovy (50%) create mode 100644 src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy rename src/main/groovy/{io/codearte/accurest => org/springframework/cloud/contract/verifier}/maven/stubrunner/RemoteStubRunner.groovy (61%) rename src/main/java/{io.codearte.accurest.maven => org/springframework/cloud/contract/verifier/maven}/ConvertMojo.java (51%) create mode 100644 src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java create mode 100644 src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java create mode 100644 src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java rename src/test/java/{io/codearte/accurest => org/springframework/cloud/contract/verifier}/maven/PluginIT.java (58%) rename src/test/java/{io/codearte/accurest => org/springframework/cloud/contract/verifier}/maven/PluginUnitTest.java (67%) delete mode 100644 src/test/projects/basic/src/test/resources/accurest/Messaging.groovy create mode 100644 src/test/projects/basic/src/test/resources/contracts/Messaging.groovy create mode 100644 src/test/projects/basic/src/test/resources/contracts/Sample.groovy delete mode 100644 src/test/projects/complex-configuration/src/test/accurest/brokenContract.groovy delete mode 100644 src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsFraud.groovy delete mode 100644 src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy create mode 100644 src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy create mode 100644 src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy create mode 100644 src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy delete mode 100644 src/test/projects/generatedStubs/target/accurest/contracts/Sample.groovy rename src/test/projects/{basic/src/test/resources/accurest => generatedStubs/target/stubs/contracts}/Sample.groovy (84%) rename src/test/projects/generatedStubs/target/{accurest => stubs}/mappings/Sample.json (100%) delete mode 100644 src/test/projects/plugin-extension/src/test/resources/accurest/greetings_ok.groovy delete mode 100644 src/test/projects/plugin-extension/src/test/resources/accurest/greetings_with_default_value.groovy create mode 100644 src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy create mode 100644 src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy delete mode 100644 src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_ok.groovy delete mode 100644 src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_with_default_value.groovy create mode 100644 src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy create mode 100644 src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy delete mode 100644 src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_ok.groovy delete mode 100644 src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_with_default_value.groovy create mode 100644 src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy create mode 100644 src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy diff --git a/.mvn/settings.xml b/.mvn/settings.xml deleted file mode 100644 index 564d2466ed..0000000000 --- a/.mvn/settings.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - oss - ${env.CI_DEPLOY_USERNAME} - ${env.CI_DEPLOY_PASSWORD} - - - github.com - ${env.GITHUBKEY} - - - - - release - - - - - release - - ${env.GPG_KEY_NAME} - ${env.GPG_PASSPHRASE} - - - - \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index d1c24045ab..2765fbe53f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,31 +1,5 @@ language: java jdk: - oraclejdk8 -before_install: -- openssl aes-256-cbc -K $encrypted_6c56aea9ab8c_key -iv $encrypted_6c56aea9ab8c_iv -in .mvn/codesigning.asc.enc -out .mvn/codesigning.asc -d -- gpg --fast-import .mvn/codesigning.asc -- git config --global user.email "builds@travis-ci.com" -- git config --global user.name "Travis CI" -- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then git checkout master; fi -before_script: -- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw initialize -Pversion; fi script: -- if [[ $TRAVIS_PULL_REQUEST == "false" && $TRAVIS_BRANCH == "master" ]]; then ./mvnw deploy --settings .mvn/settings.xml; else ./mvnw install; fi -after_success: -- ./mvnw clean test jacoco:report coveralls:report -install: true -branches: - except: - - /^v\d/ - - gh-pages -cache: - directories: - - ~/.m2/repository - - ~/.m2/wrapper -env: - global: - - secure: oYAoU+PDuaWLo4MBoQYCF++kEqwWn8xtDAeBxBRIvduJO7758+haeSW43AFjmLfuJ9aUdfS+MrqGnDuj+Nqw1oSU9vdbyX7m+Q3wFDkO1Ln2NCaifrSCVHaAAMSfSKNlYBjD4+sATsrnSF75BSIS2WMNItkGcac7DPD+Ls64Ovw9MbkMB2i4TRYboGFNvOhtFYSOexd6hWltin0s6EHtsqFJKBKiPfvZYPJ34d0bfvMbi/TyfDoaia0QG8EUqyF1FZhBT5j/iXD03kTMdZ59o3pUgkgZjMfiD7rJGWffwZ+kV8PtzYyzjhiH8o+tqhFkLRXfu+s6zcMjBhJDR1rgguEqzlKbGRoFahY5PI+fbLwyNz+kQwtXxF3+lpwM/VZ/1OHPgpTtdDiz5ArRskb/Y/caGbLhjkm4V2x3/7fvRHGcLZf7DraJoShT/5MvG0AN7PCjEhbGX+08YaRucmQLWHUo1pGazwagP+7MqDsimdR+VzIY/HUctFi4DPOLjmZROukcPCFJTwn2T/0TFC5Luptb5ifsT9RvBv89/A71XcYs6rrGcU4UHdy6gZwWIRECKG82X+0jwoM39dFfweF7iVIuimdK2+yy4DtLZQfeqR7pWphs2i42twQUWcwIpRQyi/hn+wteVz7yxIBKfphaIVVP3juS1RPtMD0vOm8BRpo= - - secure: JnHy2f/hedU35C5imIRND+OOaM7xAfuJBa5l5rDKuxFmEQgnbxAYQVNij7QkawrdUsdIr/c8OmcmdSL7grxbblY4dRgwlSw/2LycmdZesSUci752beRZgz8ZnuERP3SLJcCbMYabUezd2GK4dElOt/BaZuGM9JDdV87Yz2yZfihcL8az/JQv8HJKdtkRlAzI3m7FIlA/ArsLnIUcibAkKwQqLBzjZWs+U0XmwCqcyX5YhQPZWl/wLrM12yRPJuPUXb7n+cGo8QIPCuLo7tHR4qBaYM9+1bVLqQ9irvJQ4o22G+NLsZPtzYx4XRTmTwFFmKEmNA05EfgwezaHOwifKOavdeCx1dx4sgznV176dXEcWVYJkr7UWiSy4+RcL/eclP6Ha+wEoC1NG2m8aVTDbDGOIpeR7YOBDA5RrB+bdQvkdp86lNbaC1BeC7pWCxgwstmLy0FiX2qF6HjIut6Yt2K+nUQLFiySE0nzkR7ZaKdRyNj0FO/dYd2glZHSv4Z3koqpXpnwcMlcfG1KaDuX6PryKKr2ocIsvTJDU1XzqkwdKcAqkCYCkYasheSY5JPV6746giATHQPlSMJaWjnFARJHunZ00ua64vc/WbYrTQhb+VKGDLwe2K4EMpTeUXceKhFPEZyHRdS3v9upUSDYsYhIwyOL+LXwPIPLz2J/ku0= - - secure: TcIM58kEMWOCBCyUq8yPA4r2W15xCsUvt3e3EPn7njiSpOMo1P5sTxVduddLSoHvcLpn3nci6TWzwqBb+kBMQoYwKKbCYrdxPb18HrekoRYk31saQpi4zQGzKl/ENoztLVSjcGnRNmoIKvQ5Hux/OZ7PFbDBFtsyf1OfzyCnu0q9vvY2e+uIbpuJMhbcQhx7+cLaS0i5cf+2l4ldzOYUDazCV0CLdUYfme+RrkSriLmgHZ4NN0+bKX6JYJFy5mwfyl+EP8QuirPh+rpVG1CyGz/+7nRY5GeiX1V7ZJzxGBBIOa4Uq73mvMxmlA8ojgYFfcpHl56nzpl0Usou04PiFzi5M4cVGY9uFy5mBcoaBjXS6I791HJhK3AayMigNfnxhf0VELBHUD/o2bn+2VTGtHwbac2vbd+2M7Ia4ZGq9HQLet1Wk/QO3jCLWOG4Vkg9phWCip3tMJP0YuocK3Y4fV/+/aKBs3XR/t7IRAWPpTyn83K3OzXcDpxYUewMvEvk7EgunU90vXcVPzgAPMQ0erkUuZ8U/v7JGsr9ZTbmAUegc51bRmYh2ykkELMv3tr4wQB0FsRtt5O1lqjUV4KcUE3ORGXYOePenisOb00PlmXhEzKgAaXXcK/8aEGD0rvohYRDdINS3WIPLFnGxkI42wWlf8OY8HICFe31EHy7nbY= - - secure: tlZB9DK8Q27upg4L+Nmb57ItvXjQ2Nq6rRJjndPKLEi8PqE6t/JBA5PAkq8JNsYMd6IydF9/NTao97fwq4lYlcAIm7xkymx9O2mVniRR6FE/nz9Z8bze/OoIFTxd8fCSSSotZGW3c3eX2WcMHfY9XOVEwUnvXGLsFPem9fS+ckQ0HNoEaeNItAubMtSXwHCUEK7gskThcULhH+yoNPLsx1RYxKkcR2Ijam+kcrdXBGnNU+2EVcxtPkJVs9j3LQiBIYVDm3I/8cQlOsVsVDIe8+zcp00PuK8cagHi3oFGl84jOOEZnqKBi+gcIzG/8zhNP/z9E9qbt9eA/eCUQXj1Wp5658IJJrCqjmrxdWyiIr69LJWjVWkSyG0sfzszaFfRvuDdCutnnqef2BVJ+GaF3MODsTHyC8N3kiVjJje5u40PT6CzyXlnKHT9CMUt0SnqL3omgJnXyzqZ+MlqwcWJ3qbYRvUN9dp8F6j8rYdkP5WXhhs1UXvtz8Kkya6GuBTTIUFXYQCwhHB1XfXr3lK2fanRtoZBkUos8wxcc2pTax/Z7gkCerS/RATAPxvHSvBuVq+taND/R7x8Rj/DAfjWuAEC6l8rtJm8ve2dARYxeXj1dkznBQuxQqMU9PN0l2f9ZR+rs3KyCl8rym5ESduvqCCXQGQDQlk+jUdayKXeCmM= - - secure: exbai4hxMVO2Wc480kD9L7dEQEuJTTyUINHyfx01Y6KuVf8rw+zKDhVwVF4b5g1frk/R27GuD0g4jWH2yRhXLkOMmc9OOuBfL4OsrxEFhZr85EgQGIz4ME5+NaifU3pxGPVl5/GqjZhumI5XfcQjF/4bdMOTthD0At2z4pE6jmydJHNmwBGD1hw3ox6xAJBASussbvRSHslOSKmkM5ktjtAstzOTpggOdA/eXC/43rZb78THBaDcaR54nF/NdmlexKw+SCZRMIibVI15m+9GZCBRQLM5ndes0vOmi7SUPDPQ2r3r9djx6VKOaaqM4RWpv36lryneervXLj4XV02Ndbv9LqGZApANvrwRN1a5hEPb+X1wg6YHsVCOErG0f9JvnjADxStZrATdVGDMQueMXQUOp8dYD5kO2SfSahKFLDt3f5JRGRXXMmMdW3Jgt8clviRvvuXuBUy13PaXG7fM48mr0x1VvIsvRjOg5NgWHmq/j5MklOEy3LrG2636/3piV2HJZ0GRV/GgPxrVscEDYxPc7Dx5TUyIuhrqH3EjbgCcoddkpb00e9V/IyQ7fF7lyYUnzLBsVoQxgThPBcpKXm41OAvrgHtrK30gvb4HX5mjEBoXdJUgyhSXBzWvx3ApfyTdxd/KL/ga1fe7fHgfQEQLkF8WR5IqolPcGnGlu0E= +- ./mvnw clean test jacoco:report coveralls:report \ No newline at end of file diff --git a/README.md b/README.md index bb88497011..5beb0e4d6a 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ [![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest/maven.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) -Accurest Maven Plugin -==== +Spring Cloud Contract Verifier Maven Plugin +=========================================== Documentation --- -* [Accurest Documentation](http://codearte.github.io/accurest/) -* [Accurest Maven Plugin Documentation Site](http://codearte.github.io/accurest-maven-plugin/plugin-info.html) +* [Spring Cloud Contract Verifier Documentation](http://codearte.github.io/accurest/) +* [Spring Cloud Contract Verifier Maven Plugin Documentation Site](http://codearte.github.io/accurest-maven-plugin/plugin-info.html) diff --git a/mvnw b/mvnw index fc7efd17d0..349bef124b 100755 --- a/mvnw +++ b/mvnw @@ -46,6 +46,15 @@ if [ -z "$MAVEN_SKIP_RC" ] ; then fi +VERSION=$(awk '/ 0) {$0=$0} 1' `dirname $0`/pom.xml| grep '\(.*\)<.*/\1/') +if echo $VERSION | egrep -q 'M|RC'; then + echo Activating \"milestone\" profile for version=\"$VERSION\" + echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone" +else + echo Deactivating \"milestone\" profile for version=\"$VERSION\" + echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//') +fi + # OS specific support. $var _must_ be set to either true or false. cygwin=false; darwin=false; @@ -57,27 +66,27 @@ case "`uname`" in # # Look for the Apple JDKs first to preserve the existing behaviour, and then look # for the new JDKs provided by Oracle. - # + # if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then # # Apple JDKs # export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home fi - + if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then # # Apple JDKs # export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home fi - + if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then # # Oracle JDKs # export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi + fi if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then # @@ -219,7 +228,7 @@ concat_lines() { export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" -# Provide a "standardized" way to retrieve the CLI args that will +# Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" export MAVEN_CMD_LINE_ARGS @@ -230,5 +239,5 @@ exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS + ${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@" diff --git a/pom.xml b/pom.xml index 0cba3e6e2a..3101ec6a40 100644 --- a/pom.xml +++ b/pom.xml @@ -3,15 +3,17 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin maven-plugin - 0.6.11-SNAPSHOT + 1.0.0.BUILD-SNAPSHOT - Accurest Maven Plugin - Accurest Maven Plugin + Spring Cloud Contract Verifier Maven Plugin + Spring Cloud Contract Verifier Maven Plugin https://github.com/Codearte/accurest-maven-plugin + 2016 + [3.2.1,) @@ -27,6 +29,11 @@ Mariusz Smykula mariuszs@gmail.com + + marcingrzejszczak + Marcin Grzejszczak + marcin@grzejszczak.pl + @@ -36,7 +43,7 @@ UTF-8 UTF-8 - 1.1.0 + 1.0.0.BUILD-SNAPSHOT 1.1.0 1.7 @@ -60,16 +67,16 @@ - - oss - Sonatype Nexus Snapshots - http://oss.sonatype.org/content/repositories/snapshots - - oss - Nexus Release Repository - http://oss.sonatype.org/service/local/staging/deploy/maven2/ + repo.spring.io + Spring Release Repository + https://repo.spring.io/plugins-release-local + + repo.spring.io + Spring Snapshot Repository + https://repo.spring.io/plugins-snapshot-local + github scm:git:ssh://git@github.com:Codearte/accurest-maven-plugin.git @@ -165,6 +172,35 @@ + + com.mycila + license-maven-plugin + 3.0.rc1 + +
src/etc/header.txt
+ + src/** + + + **/.idea/** + **/*.adoc + + true + true + + ${project.inceptionYear} + Codearte + + UTF-8 +
+ + + + check + + + +
org.jacoco jacoco-maven-plugin @@ -270,19 +306,19 @@ - io.codearte.accurest - accurest-core - ${accurest.version} + org.springframework.cloud.contract + spring-cloud-contract-verifier-core + ${spring.cloud.contract.verifier.version} - io.codearte.accurest - accurest-converters - ${accurest.version} + org.springframework.cloud.contract + spring-cloud-contract-verifier-converters + ${spring.cloud.contract.verifier.version} - io.codearte.accurest - stub-runner - ${accurest.version} + org.springframework.cloud.contract + spring-cloud-contract-stub-runner + ${spring.cloud.contract.verifier.version} @@ -594,5 +630,71 @@ + + spring + + true + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/libs-milestone-local + + false + + + + spring-releases + Spring Releases + http://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/libs-milestone-local + + false + + + + spring-plugin-snapshots + Spring Snapshots + http://repo.spring.io/plugins-snapshot-local + + true + + + + spring-plugin-milestones + Spring Milestones + http://repo.spring.io/plugins-milestone-local + + false + + + + diff --git a/src/etc/header.txt b/src/etc/header.txt new file mode 100644 index 0000000000..771f93dfec --- /dev/null +++ b/src/etc/header.txt @@ -0,0 +1,14 @@ + + Copyright 2013-${year} the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy deleted file mode 100644 index d8e7769e63..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateStubsMojo.groovy +++ /dev/null @@ -1,97 +0,0 @@ -package io.codearte.accurest.maven - -import groovy.transform.CompileStatic -import org.apache.maven.model.Plugin -import org.apache.maven.plugin.AbstractMojo -import org.apache.maven.plugin.MojoExecutionException -import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.Component -import org.apache.maven.plugins.annotations.LifecyclePhase -import org.apache.maven.plugins.annotations.Mojo -import org.apache.maven.plugins.annotations.Parameter -import org.apache.maven.project.MavenProject -import org.apache.maven.project.MavenProjectHelper -import org.codehaus.plexus.archiver.Archiver -import org.codehaus.plexus.archiver.jar.JarArchiver -import org.codehaus.plexus.archiver.jar.Manifest - -@Mojo(name = 'generateStubs', defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true) -@CompileStatic -class GenerateStubsMojo extends AbstractMojo { - - private static final String STUB_MAPPING_FILE_PATTERN = '**/*.json' - private static final String ACCUREST_FILE_PATTERN = '**/*.groovy' - - @Parameter(defaultValue = '${project.build.directory}', readonly = true, required = true) - private File projectBuildDirectory - - @Parameter(property = 'stubsDirectory', defaultValue = '${project.build.directory}/accurest') - private File outputDirectory - - @Parameter(property = 'accurest.skip', defaultValue = 'false') - private boolean skip - - @Component - private MavenProjectHelper projectHelper; - - @Parameter(defaultValue = '${project}', readonly = true) - private MavenProject project - - @Component(role = Archiver.class, hint = "jar") - private JarArchiver archiver; - - @Parameter(defaultValue = 'true') - private boolean attachContracts - - @Parameter(defaultValue = 'stubs') - private String classifier - - void execute() throws MojoExecutionException, MojoFailureException { - - if (skip) { - log.info("Skipping accurest execution: accurest.skip=${skip}") - return - } - - File stubsJarFile = createStubJar(outputDirectory) - projectHelper.attachArtifact(project, 'jar', classifier, stubsJarFile) - } - - private File createStubJar(File stubsOutputDir) { - if (!stubsOutputDir.exists()) { - throw new MojoExecutionException("Stubs could not be found: $stubsOutputDir.\nPlease make sure that accurest:convert was invoked"); - } - String stubArchiveName = "${project.build.finalName}-${classifier}.jar"; - File stubsJarFile = new File(projectBuildDirectory, stubArchiveName); - - try { - if (attachContracts) { - archiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN, ACCUREST_FILE_PATTERN] as String[], [] as String[]); - } else { - log.info("Skipping attaching accurest contracts") - archiver.addDirectory(stubsOutputDir, [STUB_MAPPING_FILE_PATTERN] as String[], [ACCUREST_FILE_PATTERN] as String[]); - } - archiver.setCompress(true); - archiver.setDestFile(stubsJarFile); - archiver.addConfiguredManifest(createManifest()); - archiver.createArchive(); - } catch (Exception e) { - throw new MojoFailureException("Exception while packaging ${classifier} jar.", e); - } - return stubsJarFile - } - - private Manifest createManifest() { - Manifest manifest = new Manifest(); - Plugin accurestMavenPlugin = project.getBuildPlugins().find { it.artifactId == 'accurest-maven-plugin' } - manifest.addConfiguredAttribute(new Manifest.Attribute("Accurest-Maven-Plugin-Version", accurestMavenPlugin.version)); - if (accurestMavenPlugin.getDependencies()) { - String accurestVersion = accurestMavenPlugin.getDependencies().find { - it.artifactId == 'accurest-core' - }.version - manifest.addConfiguredAttribute(new Manifest.Attribute("Accurest-Version", accurestVersion)); - } - return manifest - } - -} diff --git a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy deleted file mode 100644 index 85557b228c..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/GenerateTestsMojo.groovy +++ /dev/null @@ -1,119 +0,0 @@ -package io.codearte.accurest.maven - -import groovy.transform.CompileStatic -import io.codearte.accurest.AccurestException -import io.codearte.accurest.TestGenerator -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.config.TestFramework -import io.codearte.accurest.config.TestMode -import org.apache.maven.plugin.AbstractMojo -import org.apache.maven.plugin.MojoExecutionException -import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.LifecyclePhase -import org.apache.maven.plugins.annotations.Mojo -import org.apache.maven.plugins.annotations.Parameter -import org.apache.maven.plugins.annotations.ResolutionScope -import org.apache.maven.project.MavenProject - -import static java.lang.String.format - -@Mojo(name = 'generateTests', defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES, requiresDependencyResolution = ResolutionScope.TEST) -@CompileStatic -class GenerateTestsMojo extends AbstractMojo { - - @Parameter(property = 'accurest.contractsDirectory', defaultValue = '${project.basedir}/src/test/resources/accurest') - private File contractsDirectory - - @Parameter(defaultValue = '${project.build.directory}/generated-test-sources/accurest') - private File generatedTestSourcesDir - - @Parameter(defaultValue = 'io.codearte.accurest.tests') - private String basePackageForTests - - @Parameter - private String baseClassForTests - - @Parameter(defaultValue = 'MOCKMVC') - private TestMode testMode - - @Parameter(defaultValue = 'JUNIT') - private TestFramework testFramework - - @Parameter - private String ruleClassForTests - - @Parameter - private String nameSuffixForTests - - /** - * Imports that should be added to generated tests - */ - @Parameter - private String[] imports - - /** - * Static imports that should be added to generated tests - */ - @Parameter - private String[] staticImports - - /** - * Patterns that should not be taken into account for processing - */ - @Parameter - List excludedFiles - - /** - * Patterns for which Accurest should generate @Ignored tests - */ - @Parameter - List ignoredFiles - - @Parameter(defaultValue = '${project}', readonly = true) - private MavenProject project - - @Parameter(property = 'accurest.skip', defaultValue = 'false') - private boolean skip - - void execute() throws MojoExecutionException, MojoFailureException { - - if (skip) { - log.info("Skipping accurest execution: accurest.skip=${skip}") - return - } - - log.info('Generating server tests source code for Accurest contract verification') - - AccurestConfigProperties config = new AccurestConfigProperties() - config.contractsDslDir = contractsDirectory - config.generatedTestSourcesDir = generatedTestSourcesDir - config.targetFramework = testFramework - config.testMode = testMode - config.basePackageForTests = basePackageForTests - config.baseClassForTests = baseClassForTests - config.ruleClassForTests = ruleClassForTests - config.nameSuffixForTests = nameSuffixForTests - - config.setImports(imports) - config.setStaticImports(staticImports) - config.setIgnoredFiles(ignoredFiles) - config.setExcludedFiles(excludedFiles) - - project.addTestCompileSourceRoot(generatedTestSourcesDir.absolutePath) - - if (log.isInfoEnabled()) { - log.info("Test Source directory: $generatedTestSourcesDir added."); - log.info("Using ${config.baseClassForTests} as base class for test classes") - } - - try { - TestGenerator generator = new TestGenerator(config) - int generatedClasses = generator.generate() - log.info("Generated $generatedClasses test classes.") - } catch (AccurestException e) { - throw new MojoExecutionException(format("Accurest Plugin exception: %s", e.message), e) - } - - } - -} diff --git a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy b/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy deleted file mode 100644 index cfa0248e5d..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/RunMojo.groovy +++ /dev/null @@ -1,110 +0,0 @@ -package io.codearte.accurest.maven - -import groovy.transform.CompileStatic -import io.codearte.accurest.maven.stubrunner.LocalStubRunner -import io.codearte.accurest.maven.stubrunner.RemoteStubRunner -import io.codearte.accurest.stubrunner.BatchStubRunner -import io.codearte.accurest.stubrunner.StubRunner -import io.codearte.accurest.stubrunner.StubRunnerOptions -import io.codearte.accurest.stubrunner.StubRunnerOptionsBuilder -import org.apache.maven.execution.MavenSession -import org.apache.maven.plugin.AbstractMojo -import org.apache.maven.plugin.MojoExecutionException -import org.apache.maven.plugin.MojoFailureException -import org.apache.maven.plugins.annotations.Mojo -import org.apache.maven.plugins.annotations.Parameter -import org.apache.maven.plugins.annotations.ResolutionScope -import org.eclipse.aether.RepositorySystemSession - -import javax.inject.Inject - -@Mojo(name = 'run', requiresProject = false, requiresDependencyResolution = ResolutionScope.RUNTIME) -@CompileStatic -class RunMojo extends AbstractMojo { - - @Parameter(defaultValue = '${repositorySystemSession}', readonly = true) - private RepositorySystemSession repoSession - - @Parameter(defaultValue = '${project.build.directory}/accurest/mappings') - private File stubsDirectory - - @Parameter(property = 'stubsDirectory', defaultValue = '${basedir}') - private File destination - - @Parameter(property = 'accurest.http.port', defaultValue = '8080') - private int httpPort; - - @Parameter(property = 'accurest.skip', defaultValue = 'false') - private boolean skip - - @Parameter(property = 'accurest.stubs') - private String stubs - - @Parameter(property = 'accurest.http.minPort', defaultValue = '10000') - private int minPort - - @Parameter(property = 'accurest.http.maxPort', defaultValue = '15000') - private int maxPort - - private String stubsClassifier = 'stubs' - - @Parameter(defaultValue = '${session}', readonly = true) - private MavenSession mavenSession - - private final LocalStubRunner localStubRunner - private final RemoteStubRunner remoteStubRunner - - @Inject - RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner) { - this.localStubRunner = localStubRunner - this.remoteStubRunner = remoteStubRunner - } - - void execute() throws MojoExecutionException, MojoFailureException { - - if (skip) { - log.info("Skipping accurest execution: accurest.skip=${skip}") - return - } - BatchStubRunner batchStubRunner - StubRunnerOptionsBuilder optionsBuilder = new StubRunnerOptionsBuilder() - .withStubsClassifier(stubsClassifier) - if (!stubs) { - StubRunnerOptions options = optionsBuilder.withPort(httpPort).build() - StubRunner stubRunner = localStubRunner.run(resolveStubsDirectory().absolutePath, options) - batchStubRunner = new BatchStubRunner(Arrays.asList(stubRunner)) - } else { - StubRunnerOptions options = optionsBuilder - .withStubs(stubs) - .withMinMaxPort(minPort, maxPort).build() - batchStubRunner = remoteStubRunner.run(options, repoSession) - } - - pressAnyKeyToContinue() - - if (batchStubRunner) { - batchStubRunner.close() - } - } - - private File resolveStubsDirectory() { - if (insideProject) { - stubsDirectory - } else { - destination - } - } - - private void pressAnyKeyToContinue() { - log.info("Press ENTER to continue...") - try { - System.in.read() - } catch (Exception ignored) { - } - } - - private boolean isInsideProject() { - return mavenSession.request.projectPresent - } - -} diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy b/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy deleted file mode 100644 index 73d6a7f16c..0000000000 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/LocalStubRunner.groovy +++ /dev/null @@ -1,22 +0,0 @@ -package io.codearte.accurest.maven.stubrunner - -import groovy.transform.CompileStatic -import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.StubConfiguration -import io.codearte.accurest.stubrunner.StubRunner -import io.codearte.accurest.stubrunner.StubRunnerOptions - -import javax.inject.Named - -@Named -@CompileStatic -@Slf4j -class LocalStubRunner { - - StubRunner run(String contractsDir, StubRunnerOptions options) { - log.info("Launching StubRunner with contracts from ${contractsDir}") - StubRunner stubRunner = new StubRunner(options, contractsDir, new StubConfiguration(contractsDir)) - stubRunner.runStubs() - return stubRunner - } -} diff --git a/src/main/groovy/io/codearte/accurest/maven/CopyContracts.groovy b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy similarity index 67% rename from src/main/groovy/io/codearte/accurest/maven/CopyContracts.groovy rename to src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy index 4a5894b65e..25f2014644 100644 --- a/src/main/groovy/io/codearte/accurest/maven/CopyContracts.groovy +++ b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.maven +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven import groovy.transform.CompileStatic import groovy.util.logging.Slf4j @@ -25,11 +41,11 @@ class CopyContracts { } void copy(File contractsDirectory, File outputDirectory) { - log.info('Copying accurest contracts') + log.info('Copying Spring Cloud Contract Verifier contracts') Resource testResource = new Resource(directory: contractsDirectory.absolutePath) MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution( resources: [testResource], - outputDirectory: new File(outputDirectory, 'accurest'), + outputDirectory: new File(outputDirectory, 'contracts'), mavenProject: project, encoding: 'UTF-8', mavenSession: mavenSession); diff --git a/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy new file mode 100644 index 0000000000..e6dd688d85 --- /dev/null +++ b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy @@ -0,0 +1,36 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven + +import org.apache.maven.model.Plugin +import org.apache.maven.project.MavenProject +import org.codehaus.plexus.archiver.jar.Manifest + +class ManifestCreator { + static Manifest createManifest(MavenProject project) { + Manifest manifest = new Manifest(); + Plugin verifierMavenPlugin = project.getBuildPlugins().find { it.artifactId == 'spring-cloud-contract-verifier-maven-plugin' } + manifest.addConfiguredAttribute(new Manifest.Attribute("Spring-Cloud-Contract-Verifier-Maven-Plugin-Version", verifierMavenPlugin.version)); + if (verifierMavenPlugin.getDependencies()) { + String verifierVersion = verifierMavenPlugin.getDependencies().find { + it.artifactId == 'spring-cloud-contract-verifier-core' + }.version + manifest.addConfiguredAttribute(new Manifest.Attribute("Spring-Cloud-Contract-Verifier-Version", verifierVersion)); + } + return manifest + } +} diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy similarity index 50% rename from src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy rename to src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy index 2ec9a2d231..f6aa07e085 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/AetherStubDownloaderFactory.groovy +++ b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy @@ -1,11 +1,27 @@ -package io.codearte.accurest.maven.stubrunner +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.AetherStubDownloader import org.apache.maven.project.MavenProject import org.eclipse.aether.RepositorySystem import org.eclipse.aether.RepositorySystemSession +import org.springframework.cloud.contract.stubrunner.AetherStubDownloader import javax.inject.Inject import javax.inject.Named diff --git a/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy new file mode 100644 index 0000000000..687c3e1cd0 --- /dev/null +++ b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy @@ -0,0 +1,38 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven.stubrunner + +import groovy.transform.CompileStatic +import groovy.util.logging.Slf4j +import org.springframework.cloud.contract.stubrunner.StubConfiguration +import org.springframework.cloud.contract.stubrunner.StubRunner +import org.springframework.cloud.contract.stubrunner.StubRunnerOptions + +import javax.inject.Named + +@Named +@CompileStatic +@Slf4j +class LocalStubRunner { + + StubRunner run(String contractsDir, StubRunnerOptions options) { + log.info("Launching StubRunner with contracts from ${contractsDir}") + StubRunner stubRunner = new StubRunner(options, contractsDir, new StubConfiguration(contractsDir)) + stubRunner.runStubs() + return stubRunner + } +} diff --git a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy similarity index 61% rename from src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy rename to src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy index bb2084ef25..f85e6f80a2 100644 --- a/src/main/groovy/io/codearte/accurest/maven/stubrunner/RemoteStubRunner.groovy +++ b/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy @@ -1,9 +1,25 @@ -package io.codearte.accurest.maven.stubrunner +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.* import org.eclipse.aether.RepositorySystemSession +import org.springframework.cloud.contract.stubrunner.* import javax.inject.Inject import javax.inject.Named diff --git a/src/main/java/io.codearte.accurest.maven/ConvertMojo.java b/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java similarity index 51% rename from src/main/java/io.codearte.accurest.maven/ConvertMojo.java rename to src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java index c1646cc12a..cd8c5063b1 100644 --- a/src/main/java/io.codearte.accurest.maven/ConvertMojo.java +++ b/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java @@ -1,51 +1,61 @@ -package io.codearte.accurest.maven; +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven; + +import java.io.File; -import groovy.transform.CompileStatic; -import io.codearte.accurest.config.AccurestConfigProperties; -import io.codearte.accurest.wiremock.DslToWireMockClientConverter; -import io.codearte.accurest.wiremock.RecursiveFilesConverter; import org.apache.maven.execution.MavenSession; -import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugins.annotations.*; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; -import org.apache.maven.shared.filtering.MavenFilteringException; -import org.apache.maven.shared.filtering.MavenResourcesExecution; import org.apache.maven.shared.filtering.MavenResourcesFiltering; - -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties; +import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter; +import org.springframework.cloud.contract.verifier.wiremock.RecursiveFilesConverter; /** - * - * Convert Accurest contracts into WireMock stubs mappings. - * - * This goal allow to generate `stubs-jar` or execute `accurest:run` with generated WireMock mappings. - * + * Convert Spring Cloud Contract Verifier contracts into WireMock stubs mappings. + *

+ * This goal allow to generate `stubs-jar` or execute `spring-cloud-contract-verifier:run` with generated WireMock mappings. */ @Mojo(name = "convert", requiresProject = false, defaultPhase = LifecyclePhase.PROCESS_TEST_RESOURCES) -@CompileStatic public class ConvertMojo extends AbstractMojo { /** - * Directory containing Accurest contracts written using the GroovyDSL + * Directory containing Spring Cloud Contract Verifier contracts written using the GroovyDSL */ - @Parameter(defaultValue = "${basedir}/src/test/resources/accurest") + @Parameter(defaultValue = "${basedir}/src/test/resources/contracts") private File contractsDirectory; /** * Directory where the generated WireMock stubs from Groovy DSL should be placed. * You can then mention them in your packaging task to create jar with stubs */ - @Parameter(defaultValue = "${project.build.directory}/accurest") + @Parameter(defaultValue = "${project.build.directory}/stubs") private File outputDirectory; /** * Directory containing contracts written using the GroovyDSL - * + *

* This parameter is only used when goal is executed outside of maven project. */ @Parameter(property = "contractsDirectory", defaultValue = "${basedir}") @@ -54,7 +64,7 @@ public class ConvertMojo extends AbstractMojo { @Parameter(property = "stubsDirectory", defaultValue = "${basedir}") private File destination; - @Parameter(property = "accurest.skip", defaultValue = "false") + @Parameter(property = "spring.cloud.contract.verifier.skip", defaultValue = "false") private boolean skip; @Parameter(defaultValue = "${session}", readonly = true) @@ -69,18 +79,18 @@ public class ConvertMojo extends AbstractMojo { public void execute() throws MojoExecutionException, MojoFailureException { if (skip) { - getLog().info(String.format("Skipping accurest execution: accurest.skip=%s", skip)); + getLog().info(String.format("Skipping Spring Cloud Contract Verifier execution: spring.cloud.contract.verifier.skip=%s", skip)); return; } new CopyContracts(project, mavenSession, mavenResourcesFiltering).copy(contractsDirectory, outputDirectory); - final AccurestConfigProperties config = new AccurestConfigProperties(); + final ContractVerifierConfigProperties config = new ContractVerifierConfigProperties(); config.setContractsDslDir(isInsideProject() ? contractsDirectory : source); config.setStubsOutputDir(isInsideProject() ? new File(outputDirectory, "mappings") : destination); - getLog().info("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings"); - getLog().info(String.format(" Accurest contracts directory: %s", config.getContractsDslDir())); + getLog().info("Converting from Spring Cloud Contract Verifier contracts to WireMock stubs mappings"); + getLog().info(String.format(" Spring Cloud Contract Verifier contracts directory: %s", config.getContractsDslDir())); getLog().info(String.format("WireMock stubs mappings directory: %s", config.getStubsOutputDir())); RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), config); diff --git a/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java b/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java new file mode 100644 index 0000000000..dfb657506a --- /dev/null +++ b/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java @@ -0,0 +1,100 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven; + +import java.io.File; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Component; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.project.MavenProject; +import org.apache.maven.project.MavenProjectHelper; +import org.codehaus.plexus.archiver.Archiver; +import org.codehaus.plexus.archiver.jar.JarArchiver; + +@Mojo(name = "generateStubs", defaultPhase = LifecyclePhase.PACKAGE, requiresProject = true) +public class GenerateStubsMojo extends AbstractMojo { + + private static final String STUB_MAPPING_FILE_PATTERN = "**/*.json"; + private static final String CONTRACT_FILE_PATTERN = "**/*.groovy"; + + @Parameter(defaultValue = "${project.build.directory}", readonly = true, required = true) + private File projectBuildDirectory; + + @Parameter(property = "stubsDirectory", defaultValue = "${project.build.directory}/stubs") + private File outputDirectory; + + /** + * Set this to "true" to bypass Verifier execution.. + */ + @Parameter(property = "spring.cloud.contract.verifier.skip", defaultValue = "false") + private boolean skip; + + @Component + private MavenProjectHelper projectHelper; + + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject project; + + @Component(role = Archiver.class, hint = "jar") + private JarArchiver archiver; + + @Parameter(defaultValue = "true") + private boolean attachContracts; + + @Parameter(defaultValue = "stubs") + private String classifier; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (skip) { + getLog().info("Skipping Spring Cloud Contract Verifier execution: spring.cloud.contract.verifier.skip=" + skip); + return; + } + File stubsJarFile = createStubJar(outputDirectory); + projectHelper.attachArtifact(project, "jar", classifier, stubsJarFile); + } + + private File createStubJar(File stubsOutputDir) throws MojoFailureException, MojoExecutionException { + if (!stubsOutputDir.exists()) { + throw new MojoExecutionException("Stubs could not be found: " + stubsOutputDir.getAbsolutePath() + ".\nPlease make sure that spring-cloud-contract-verifier:convert was invoked"); + } + String stubArchiveName = project.getBuild().getFinalName() + "-" + classifier + ".jar"; + File stubsJarFile = new File(projectBuildDirectory, stubArchiveName); + try { + if (attachContracts) { + archiver.addDirectory(stubsOutputDir, new String[]{STUB_MAPPING_FILE_PATTERN, + CONTRACT_FILE_PATTERN }, new String[0]); + } else { + getLog().info("Skipping attaching Spring Cloud Contract Verifier contracts"); + archiver.addDirectory(stubsOutputDir, new String[]{STUB_MAPPING_FILE_PATTERN}, new String[]{ + CONTRACT_FILE_PATTERN }); + } + archiver.setCompress(true); + archiver.setDestFile(stubsJarFile); + archiver.addConfiguredManifest(ManifestCreator.createManifest(project)); + archiver.createArchive(); + } catch (Exception e) { + throw new MojoFailureException("Exception while packaging " + classifier + " jar.", e); + } + return stubsJarFile; + } + +} diff --git a/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java b/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java new file mode 100644 index 0000000000..d3a051961d --- /dev/null +++ b/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java @@ -0,0 +1,142 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven; + +import java.io.File; +import java.util.List; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; +import org.springframework.cloud.contract.verifier.ContractVerifierException; +import org.springframework.cloud.contract.verifier.TestGenerator; +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties; +import org.springframework.cloud.contract.verifier.config.TestFramework; +import org.springframework.cloud.contract.verifier.config.TestMode; + +@Mojo(name = "generateTests", defaultPhase = LifecyclePhase.GENERATE_TEST_SOURCES, requiresDependencyResolution = ResolutionScope.TEST) +public class GenerateTestsMojo extends AbstractMojo { + + @Parameter(property = "spring.cloud.contract.verifier.contractsDirectory", defaultValue = "${project.basedir}/src/test/resources/contracts") + private File contractsDirectory; + + @Parameter(defaultValue = "${project.build.directory}/generated-test-sources/contracts") + private File generatedTestSourcesDir; + + @Parameter(defaultValue = "org.springframework.cloud.contract.verifier.tests") + private String basePackageForTests; + + @Parameter + private String baseClassForTests; + + @Parameter(defaultValue = "MOCKMVC") + private TestMode testMode; + + @Parameter(defaultValue = "JUNIT") + private TestFramework testFramework; + + @Parameter + private String ruleClassForTests; + + @Parameter + private String nameSuffixForTests; + + /** + * Imports that should be added to generated tests + */ + @Parameter + private String[] imports; + + /** + * Static imports that should be added to generated tests + */ + @Parameter + private String[] staticImports; + + /** + * Patterns that should not be taken into account for processing + */ + @Parameter + private List excludedFiles; + + /** + * Patterns for which Spring Cloud Contract Verifier should generate @Ignored tests + */ + @Parameter + private List ignoredFiles; + + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject project; + + @Parameter(property = "spring.cloud.contract.verifier.skip", defaultValue = "false") + private boolean skip; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (skip) { + getLog().info("Skipping Spring Cloud Contract Verifier execution: spring.cloud.contract.verifier.skip=" + skip); + return; + } + getLog().info("Generating server tests source code for Spring Cloud Contract Verifier contract verification"); + final ContractVerifierConfigProperties config = new ContractVerifierConfigProperties(); + config.setContractsDslDir(contractsDirectory); + config.setGeneratedTestSourcesDir(generatedTestSourcesDir); + config.setTargetFramework(testFramework); + config.setTestMode(testMode); + config.setBasePackageForTests(basePackageForTests); + config.setBaseClassForTests(baseClassForTests); + config.setRuleClassForTests(ruleClassForTests); + config.setNameSuffixForTests(nameSuffixForTests); + config.setImports(imports); + config.setStaticImports(staticImports); + config.setIgnoredFiles(ignoredFiles); + config.setExcludedFiles(excludedFiles); + project.addTestCompileSourceRoot(generatedTestSourcesDir.getAbsolutePath()); + if (getLog().isInfoEnabled()) { + getLog().info("Test Source directory: " + generatedTestSourcesDir.getAbsolutePath() + " added."); + getLog().info("Using " + config.getBaseClassForTests() + " as base class for test classes"); + } + try { + TestGenerator generator = new TestGenerator(config); + int generatedClasses = generator.generate(); + getLog().info("Generated " + generatedClasses + " test classes."); + } catch (ContractVerifierException e) { + throw new MojoExecutionException(String.format("Spring Cloud Contract Verifier Plugin exception: %s", e.getMessage()), e); + } + } + + public List getExcludedFiles() { + return excludedFiles; + } + + public void setExcludedFiles(List excludedFiles) { + this.excludedFiles = excludedFiles; + } + + public List getIgnoredFiles() { + return ignoredFiles; + } + + public void setIgnoredFiles(List ignoredFiles) { + this.ignoredFiles = ignoredFiles; + } + +} diff --git a/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java b/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java new file mode 100644 index 0000000000..c8b4b42f0f --- /dev/null +++ b/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java @@ -0,0 +1,151 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven; + +import javax.inject.Inject; +import java.io.File; +import java.io.IOException; +import java.util.Collections; + +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.eclipse.aether.RepositorySystemSession; +import org.springframework.cloud.contract.stubrunner.BatchStubRunner; +import org.springframework.cloud.contract.stubrunner.StubRunner; +import org.springframework.cloud.contract.stubrunner.StubRunnerOptions; +import org.springframework.cloud.contract.stubrunner.StubRunnerOptionsBuilder; +import org.springframework.cloud.contract.verifier.maven.stubrunner.LocalStubRunner; + +import org.springframework.cloud.contract.verifier.maven.stubrunner.RemoteStubRunner; + +import static com.google.common.base.Strings.isNullOrEmpty; + +@Mojo(name = "run", requiresProject = false, requiresDependencyResolution = ResolutionScope.RUNTIME) +public class RunMojo extends AbstractMojo { + + @Parameter(defaultValue = "${repositorySystemSession}", readonly = true) + private RepositorySystemSession repoSession; + + @Parameter(defaultValue = "${project.build.directory}/contracts/mappings") + private File stubsDirectory; + + @Parameter(property = "stubsDirectory", defaultValue = "${basedir}") + private File destination; + + /** + * HTTP port for WireMock server + */ + @Parameter(property = "spring.cloud.contract.verifier.http.port", defaultValue = "8080") + private int httpPort; + + /** + * Set this to "true" to bypass verifier execution. + */ + @Parameter(property = "spring.cloud.contract.verifier.skip", defaultValue = "false") + private boolean skip; + + /** + * Set this to "true" to bypass verifier test generation. + */ + @Parameter(property = "spring.cloud.contract.verifier.skipTestOnly", defaultValue = "false") + private boolean skipTestOnly; + + @Parameter(property = "spring.cloud.contract.verifier.stubs") + private String stubs; + + @Parameter(property = "spring.cloud.contract.verifier.http.minPort", defaultValue = "10000") + private int minPort; + + @Parameter(property = "spring.cloud.contract.verifier.http.maxPort", defaultValue = "15000") + private int maxPort; + + /** + * Classifier used by stubs artifacts. + */ + @Parameter(defaultValue = "stubs") + private String stubsClassifier = "stubs"; + + @Parameter(defaultValue = "${session}", readonly = true) + private MavenSession mavenSession; + + private final LocalStubRunner localStubRunner; + + private final RemoteStubRunner remoteStubRunner; + + @Inject + public RunMojo(LocalStubRunner localStubRunner, RemoteStubRunner remoteStubRunner) { + this.localStubRunner = localStubRunner; + this.remoteStubRunner = remoteStubRunner; + } + + public void execute() throws MojoExecutionException, MojoFailureException { + if (skip || skipTestOnly) { + getLog().info("Skipping verifier execution: spring.cloud.contract.verifier.skip=" + String.valueOf(skip)); + return; + } + BatchStubRunner batchStubRunner = null; + StubRunnerOptionsBuilder optionsBuilder = new StubRunnerOptionsBuilder() + .withStubsClassifier(stubsClassifier); + if (isNullOrEmpty(stubs)) { + StubRunnerOptions options = optionsBuilder + .withPort(httpPort) + .build(); + StubRunner stubRunner = localStubRunner.run(resolveStubsDirectory().getAbsolutePath(), options); + batchStubRunner = new BatchStubRunner(Collections.singleton(stubRunner)); + } else { + StubRunnerOptions options = optionsBuilder + .withStubs(stubs) + .withMinMaxPort(minPort, maxPort) + .build(); + batchStubRunner = remoteStubRunner.run(options, repoSession); + } + pressAnyKeyToContinue(); + if (batchStubRunner != null) { + try { + batchStubRunner.close(); + } catch (IOException e) { + throw new MojoExecutionException("Fail to close batch stub runner", e); + } + } + } + + private File resolveStubsDirectory() { + if (isInsideProject()) { + return stubsDirectory; + } else { + return destination; + } + } + + private void pressAnyKeyToContinue() { + getLog().info("Press ENTER to continue..."); + try { + System.in.read(); + } catch (Exception ignored) { + } + } + + private boolean isInsideProject() { + return mavenSession.getRequest().isProjectPresent(); + } + +} diff --git a/src/main/resources/META-INF/plexus/components.xml b/src/main/resources/META-INF/plexus/components.xml index a0ace0cd0e..19a83714fc 100644 --- a/src/main/resources/META-INF/plexus/components.xml +++ b/src/main/resources/META-INF/plexus/components.xml @@ -1,24 +1,42 @@ + org.apache.maven.lifecycle.Lifecycle org.apache.maven.lifecycle.Lifecycle - accurest + spring-cloud-contract-verifier - accurest + spring-cloud-contract-verifier - accurest-not-used-phase + spring-cloud-contract-verifier-not-used-phase - io.codearte.accurest:accurest-maven-plugin:${project.version}:convert + org.springframework.cloud.contract:spring-cloud-contract-verifier-maven-plugin:${project.version}:convert - io.codearte.accurest:accurest-maven-plugin:${project.version}:generateTests + org.springframework.cloud.contract:spring-cloud-contract-verifier-maven-plugin:${project.version}:generateTests - io.codearte.accurest:accurest-maven-plugin:${project.version}:generateStubs + org.springframework.cloud.contract:spring-cloud-contract-verifier-maven-plugin:${project.version}:generateStubs diff --git a/src/site/asciidoc/index.adoc b/src/site/asciidoc/index.adoc index 4f25a82574..f73fbb3dc9 100644 --- a/src/site/asciidoc/index.adoc +++ b/src/site/asciidoc/index.adoc @@ -1,10 +1,10 @@ -= Accurest Maven Plugin += Spring Cloud Contract Verifier Maven Plugin -Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. +Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. * Stubs mappings to be used by WireMock when doing integration testing on the client code (client tests). * Acceptance tests used to verify if server-side implementation of the API is compliant with the contract (server tests). -Accurest moves TDD to the level of software architecture. +Spring Cloud Contract Verifier moves TDD to the level of software architecture. diff --git a/src/site/asciidoc/usage.adoc b/src/site/asciidoc/usage.adoc index 976de79d95..825f738e45 100644 --- a/src/site/asciidoc/usage.adoc +++ b/src/site/asciidoc/usage.adoc @@ -2,11 +2,11 @@ == Converting Accurest GroovyDSL into WireMock stub mappings - mvn io.codearte.accurest:accurest-maven-plugin:convert + mvn org.springframework.cloud.contract:spring-cloud-contract-verifier-maven-plugin:convert or shortly footnoteref:[prefix,Additional configuration inside `~/.m2/settings.xml` is required: `io.codearte.accurest`.] - mvn accurest:convert + mvn spring-cloud-contract-verifier:convert For more information please go to the Accurest Wiki or Plugin Documentation Site. @@ -14,15 +14,15 @@ For more information please go to the Accurest Wiki or Plugin Documentation Site Run stubs mappings from current directory: - mvn io.codearte.accurest:accurest-maven-plugin:run + mvn org.springframework.cloud.contract:spring-cloud-contract-verifier-maven-plugin:run or shortly footnoteref:[prefix] - mvn accurest:run + mvn spring-cloud-contract-verifier:run == Running stubs from repository - mvn accurest:run -Dstubs="org.springframework:gs-rest-service" + mvn spring-cloud-contract-verifier:run -Dstubs="org.springframework:gs-rest-service" where `org.springframework:gs-rest-service` is artifact with stubs classifier contains wiremock mappings. diff --git a/src/site/site.xml b/src/site/site.xml index bf22b481c2..8d23c5f4d2 100644 --- a/src/site/site.xml +++ b/src/site/site.xml @@ -1,3 +1,21 @@ + ${project.name} diff --git a/src/test/java/io/codearte/accurest/maven/PluginIT.java b/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java similarity index 58% rename from src/test/java/io/codearte/accurest/maven/PluginIT.java rename to src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java index 268090b57a..cc2c878333 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginIT.java +++ b/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java @@ -1,7 +1,22 @@ -package io.codearte.accurest.maven; +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven; import java.io.File; -import java.util.regex.Pattern; import org.junit.Ignore; import org.junit.Rule; @@ -35,11 +50,11 @@ public class PluginIT { maven.forProject(basedir) .execute("package") .assertErrorFreeLog() - .assertLogText("Generating server tests source code for Accurest contract verification") + .assertLogText("Generating server tests source code for Spring Cloud Contract Verifier contract verification") .assertLogText("Generated 1 test classes.") - .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") + .assertLogText("Converting from Spring Cloud Contract Verifier contracts to WireMock stubs mappings") .assertLogText("Creating new json") - .assertLogText("Running io.codearte.accurest.tests.AccurestSpec") + .assertLogText("Running org.springframework.cloud.contract.verifier.tests.ContractVerifierSpec") .assertErrorFreeLog(); } @@ -49,11 +64,11 @@ public class PluginIT { maven.forProject(basedir) .execute("package") .assertErrorFreeLog() - .assertLogText("Generating server tests source code for Accurest contract verification") + .assertLogText("Generating server tests source code for Spring Cloud Contract Verifier contract verification") .assertLogText("Generated 1 test classes.") - .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") + .assertLogText("Converting from Spring Cloud Contract Verifier contracts to WireMock stubs mappings") .assertLogText("Creating new json") - .assertLogText("Running io.codearte.accurest.tests.AccurestTest") + .assertLogText("Running org.springframework.cloud.contract.verifier.tests.ContractVerifierTest") .assertErrorFreeLog(); } @@ -63,11 +78,11 @@ public class PluginIT { maven.forProject(basedir) .execute("package") .assertErrorFreeLog() - .assertLogText("Generating server tests source code for Accurest contract verification") + .assertLogText("Generating server tests source code for Spring Cloud Contract Verifier contract verification") .assertLogText("Generated 1 test classes.") - .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") + .assertLogText("Converting from Spring Cloud Contract Verifier contracts to WireMock stubs mappings") .assertLogText("Creating new json") - .assertLogText("Running io.codearte.accurest.tests.AccurestTest") + .assertLogText("Running org.springframework.cloud.contract.verifier.tests.ContractVerifierTest") .assertErrorFreeLog(); } @@ -79,7 +94,7 @@ public class PluginIT { .execute("package") .assertErrorFreeLog() .assertLogText("Tests run: 2, Failures: 0, Errors: 0, Skipped: 1") - .assertLogText("Running com.blogspot.toomuchcoding.frauddetection.AccurestTest") + .assertLogText("Running com.blogspot.toomuchcoding.frauddetection.ContractVerifierTest") .assertErrorFreeLog(); } @@ -89,9 +104,9 @@ public class PluginIT { properties.getPluginVersion(); maven.forProject(basedir) .withCliOption("-X") - .execute(String.format("io.codearte.accurest:accurest-maven-plugin:%s:convert", + .execute(String.format("org.springframework.cloud.contract:spring-cloud-contract-verifier-maven-plugin:%s:convert", properties.getPluginVersion())) - .assertLogText("Converting from accurest contracts written in GroovyDSL to WireMock stubs mappings") + .assertLogText("Converting from Spring Cloud Contract Verifier contracts to WireMock stubs mappings") .assertLogText("Creating new json") .assertErrorFreeLog(); } diff --git a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java b/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java similarity index 67% rename from src/test/java/io/codearte/accurest/maven/PluginUnitTest.java rename to src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java index d174e26a8e..5484243411 100644 --- a/src/test/java/io/codearte/accurest/maven/PluginUnitTest.java +++ b/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java @@ -1,12 +1,22 @@ -package io.codearte.accurest.maven; - -import static io.takari.maven.testing.TestMavenRuntime.newParameter; -import static io.takari.maven.testing.TestResources.assertFileContents; -import static io.takari.maven.testing.TestResources.assertFilesNotPresent; -import static io.takari.maven.testing.TestResources.assertFilesPresent; +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.maven; import java.io.File; -import java.util.Arrays; import org.junit.Rule; import org.junit.Test; @@ -14,6 +24,10 @@ import org.junit.Test; import io.takari.maven.testing.TestMavenRuntime; import io.takari.maven.testing.TestResources; +import static io.takari.maven.testing.TestMavenRuntime.newParameter; +import static io.takari.maven.testing.TestResources.assertFilesNotPresent; +import static io.takari.maven.testing.TestResources.assertFilesPresent; + public class PluginUnitTest { @Rule @@ -26,23 +40,23 @@ public class PluginUnitTest { public void shouldGenerateWireMockStubsInDefaultLocation() throws Exception { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "convert"); - assertFilesPresent(basedir, "target/accurest/mappings/Sample.json"); - assertFilesNotPresent(basedir, "target/accurest/mappings/Messaging.json"); + assertFilesPresent(basedir, "target/stubs/mappings/Sample.json"); + assertFilesNotPresent(basedir, "target/stubs/mappings/Messaging.json"); } @Test public void shouldGenerateWireMockFromStubsDirectory() throws Exception { File basedir = resources.getBasedir("withStubs"); maven.executeMojo(basedir, "convert", newParameter("contractsDirectory", "src/test/resources/stubs")); - assertFilesPresent(basedir, "target/accurest/mappings/Sample.json"); + assertFilesPresent(basedir, "target/stubs/mappings/Sample.json"); } @Test public void shouldCopyContracts() throws Exception { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "convert"); - assertFilesPresent(basedir, "target/accurest/accurest/Sample.groovy"); - assertFilesPresent(basedir, "target/accurest/accurest/Messaging.groovy"); + assertFilesPresent(basedir, "target/stubs/contracts/Sample.groovy"); + assertFilesPresent(basedir, "target/stubs/contracts/Messaging.groovy"); } @Test public void shouldGenerateWireMockStubsInSelectedLocation() throws Exception { @@ -56,7 +70,7 @@ public class PluginUnitTest { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "generateTests", newParameter("testFramework", "SPOCK")); assertFilesPresent(basedir, - "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestSpec.groovy"); + "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierSpec.groovy"); } @Test @@ -64,7 +78,7 @@ public class PluginUnitTest { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "generateTests"); assertFilesPresent(basedir, - "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestTest.java"); + "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java"); } @Test @@ -72,7 +86,7 @@ public class PluginUnitTest { File basedir = resources.getBasedir("basic"); maven.executeMojo(basedir, "generateTests", newParameter("imports", "")); assertFilesPresent(basedir, - "target/generated-test-sources/accurest/io/codearte/accurest/tests/AccurestTest.java"); + "target/generated-test-sources/contracts/org/springframework/cloud/contract/verifier/tests/ContractVerifierTest.java"); } @Test diff --git a/src/test/projects/basic/pom.xml b/src/test/projects/basic/pom.xml index fed7b7d67e..e7ee761ca9 100644 --- a/src/test/projects/basic/pom.xml +++ b/src/test/projects/basic/pom.xml @@ -1,4 +1,22 @@ + 4.0.0 @@ -10,8 +28,8 @@ - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin diff --git a/src/test/projects/basic/src/test/resources/accurest/Messaging.groovy b/src/test/projects/basic/src/test/resources/accurest/Messaging.groovy deleted file mode 100644 index 43b8b41c06..0000000000 --- a/src/test/projects/basic/src/test/resources/accurest/Messaging.groovy +++ /dev/null @@ -1,23 +0,0 @@ -import io.codearte.accurest.dsl.GroovyDsl - -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') - } - } -} \ No newline at end of file diff --git a/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy b/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy new file mode 100644 index 0000000000..60ff2c083a --- /dev/null +++ b/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy @@ -0,0 +1,37 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.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') + } + } +} \ No newline at end of file diff --git a/src/test/projects/basic/src/test/resources/contracts/Sample.groovy b/src/test/projects/basic/src/test/resources/contracts/Sample.groovy new file mode 100644 index 0000000000..8b10943730 --- /dev/null +++ b/src/test/projects/basic/src/test/resources/contracts/Sample.groovy @@ -0,0 +1,34 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + request { + method 'POST' + url('/users') { + + } + headers { + header 'Content-Type': 'application/json' + } + body '''{ "login" : "john", "name": "John The Contract" }''' + } + response { + status 200 + headers { + header 'Location': '/users/john' + } + } +} \ No newline at end of file diff --git a/src/test/projects/complex-configuration/pom.xml b/src/test/projects/complex-configuration/pom.xml index aa1e0fc4b3..efebefaf10 100644 --- a/src/test/projects/complex-configuration/pom.xml +++ b/src/test/projects/complex-configuration/pom.xml @@ -1,4 +1,22 @@ + 4.0.0 @@ -70,8 +88,8 @@ - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin ${accurest-plugin.version} diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java index 9ba071ba43..bedd785957 100644 --- a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.blogspot.toomuchcoding.frauddetection; import org.springframework.boot.SpringApplication; diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java index e264462cce..ce53beb419 100644 --- a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java @@ -1,13 +1,30 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.blogspot.toomuchcoding.frauddetection; +import java.math.BigDecimal; + import com.blogspot.toomuchcoding.frauddetection.model.FraudCheck; import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckResult; + import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.math.BigDecimal; - import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.FRAUD; import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.OK; import static org.springframework.web.bind.annotation.RequestMethod.PUT; diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java index 77471aee19..67f51b8a39 100644 --- a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.blogspot.toomuchcoding.frauddetection.model; import java.math.BigDecimal; diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java index 28efc573f5..a5fba329aa 100644 --- a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.blogspot.toomuchcoding.frauddetection.model; public class FraudCheckResult { diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java index b87c365d51..8ea884adb3 100644 --- a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java +++ b/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.blogspot.toomuchcoding.frauddetection.model; public enum FraudCheckStatus { diff --git a/src/test/projects/complex-configuration/src/test/accurest/brokenContract.groovy b/src/test/projects/complex-configuration/src/test/accurest/brokenContract.groovy deleted file mode 100644 index cd810a29dc..0000000000 --- a/src/test/projects/complex-configuration/src/test/accurest/brokenContract.groovy +++ /dev/null @@ -1,28 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 999 - body( - fraudCheckStatus: "OK", - rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsFraud.groovy b/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsFraud.groovy deleted file mode 100644 index 44b1c08604..0000000000 --- a/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsFraud.groovy +++ /dev/null @@ -1,27 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":99999} - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status 200 - body( """{ - "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", - "rejectionReason": "Amount too high" -}""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy b/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy deleted file mode 100644 index 7bc64d0dac..0000000000 --- a/src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy +++ /dev/null @@ -1,28 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy b/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy new file mode 100644 index 0000000000..22b6f23bc6 --- /dev/null +++ b/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy @@ -0,0 +1,44 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 999 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy b/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy new file mode 100644 index 0000000000..315fc317f9 --- /dev/null +++ b/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy @@ -0,0 +1,43 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy b/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy new file mode 100644 index 0000000000..a85b6b2737 --- /dev/null +++ b/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy @@ -0,0 +1,44 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java b/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java index 0e7194f8ed..0bc555db19 100644 --- a/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java +++ b/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java @@ -1,9 +1,25 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.blogspot.toomuchcoding.frauddetection; -import org.junit.Before; - import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; +import org.junit.Before; + public class BaseAccurest { @Before diff --git a/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java b/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java index a113e4ca37..44d5331c9e 100644 --- a/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java +++ b/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.blogspot.toomuchcoding.frauddetection.matchers; import org.junit.Assert; diff --git a/src/test/projects/generatedStubs/pom.xml b/src/test/projects/generatedStubs/pom.xml index fed7b7d67e..e7ee761ca9 100644 --- a/src/test/projects/generatedStubs/pom.xml +++ b/src/test/projects/generatedStubs/pom.xml @@ -1,4 +1,22 @@ + 4.0.0 @@ -10,8 +28,8 @@ - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin diff --git a/src/test/projects/generatedStubs/target/accurest/contracts/Sample.groovy b/src/test/projects/generatedStubs/target/accurest/contracts/Sample.groovy deleted file mode 100644 index 673ab7bd8d..0000000000 --- a/src/test/projects/generatedStubs/target/accurest/contracts/Sample.groovy +++ /dev/null @@ -1,18 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'POST' - url('/users') { - - } - headers { - header 'Content-Type': 'application/json' - } - body '''{ "login" : "john", "name": "John The Contract" }''' - } - response { - status 200 - headers { - header 'Location': '/users/john' - } - } -} \ No newline at end of file diff --git a/src/test/projects/basic/src/test/resources/accurest/Sample.groovy b/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy similarity index 84% rename from src/test/projects/basic/src/test/resources/accurest/Sample.groovy rename to src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy index 673ab7bd8d..b716f77dec 100644 --- a/src/test/projects/basic/src/test/resources/accurest/Sample.groovy +++ b/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy @@ -1,4 +1,4 @@ -io.codearte.accurest.dsl.GroovyDsl.make { +org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'POST' url('/users') { diff --git a/src/test/projects/generatedStubs/target/accurest/mappings/Sample.json b/src/test/projects/generatedStubs/target/stubs/mappings/Sample.json similarity index 100% rename from src/test/projects/generatedStubs/target/accurest/mappings/Sample.json rename to src/test/projects/generatedStubs/target/stubs/mappings/Sample.json diff --git a/src/test/projects/plugin-extension/pom.xml b/src/test/projects/plugin-extension/pom.xml index dff0c4a439..7d5f62d156 100644 --- a/src/test/projects/plugin-extension/pom.xml +++ b/src/test/projects/plugin-extension/pom.xml @@ -1,4 +1,22 @@ + 4.0.0 @@ -70,8 +88,8 @@ - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin ${accurest-plugin.version} true diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Application.java b/src/test/projects/plugin-extension/src/main/java/hello/Application.java index 5abd411428..bb79fe49da 100644 --- a/src/test/projects/plugin-extension/src/main/java/hello/Application.java +++ b/src/test/projects/plugin-extension/src/main/java/hello/Application.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; import org.springframework.boot.SpringApplication; diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java b/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java index 5d10b59b77..f22f746a8f 100644 --- a/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java +++ b/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; public class Greeting { diff --git a/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java b/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java index e356ab2b10..f6db9e06b9 100644 --- a/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java +++ b/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java @@ -1,6 +1,23 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; import java.util.concurrent.atomic.AtomicLong; + import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; diff --git a/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java b/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java index d3bf7124e2..5d04fddb2f 100644 --- a/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java +++ b/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java @@ -1,6 +1,23 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; + import org.junit.Before; public class BaseAccurest { diff --git a/src/test/projects/plugin-extension/src/test/resources/accurest/greetings_ok.groovy b/src/test/projects/plugin-extension/src/test/resources/accurest/greetings_ok.groovy deleted file mode 100644 index 0ffb665f6e..0000000000 --- a/src/test/projects/plugin-extension/src/test/resources/accurest/greetings_ok.groovy +++ /dev/null @@ -1,21 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'GET' - urlPath('/greeting') { - queryParameters { - parameter 'name': 'Something' - } - } - headers { - header 'Content-Type': 'application/json' - } - } - response { - status 200 - body( - id: 1, - content: "Hello, Something!" - ) - } -} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/resources/accurest/greetings_with_default_value.groovy b/src/test/projects/plugin-extension/src/test/resources/accurest/greetings_with_default_value.groovy deleted file mode 100644 index 2c5c32f159..0000000000 --- a/src/test/projects/plugin-extension/src/test/resources/accurest/greetings_with_default_value.groovy +++ /dev/null @@ -1,17 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'GET' - url('/greeting') - headers { - header 'Content-Type': 'application/json' - } - } - response { - status 200 - body( - id: 1, - content: "Hello, World!" - ) - } -} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy b/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy new file mode 100644 index 0000000000..4fecfabb2e --- /dev/null +++ b/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy @@ -0,0 +1,37 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + priority 2 + request { + method 'GET' + urlPath('/greeting') { + queryParameters { + parameter 'name': 'Something' + } + } + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, Something!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy b/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy new file mode 100644 index 0000000000..f2412db397 --- /dev/null +++ b/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy @@ -0,0 +1,33 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + priority 2 + request { + method 'GET' + url('/greeting') + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, World!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/pomless/Sample.groovy b/src/test/projects/pomless/Sample.groovy index 673ab7bd8d..8b10943730 100644 --- a/src/test/projects/pomless/Sample.groovy +++ b/src/test/projects/pomless/Sample.groovy @@ -1,4 +1,20 @@ -io.codearte.accurest.dsl.GroovyDsl.make { +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'POST' url('/users') { diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/src/test/projects/spring-boot-groovy/pom.xml index ca332f3606..b925aca3d1 100644 --- a/src/test/projects/spring-boot-groovy/pom.xml +++ b/src/test/projects/spring-boot-groovy/pom.xml @@ -1,4 +1,22 @@ + 4.0.0 @@ -65,8 +83,8 @@ - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin ${accurest-plugin.version} @@ -103,7 +121,7 @@ - ${project.build.directory}/generated-test-sources/accurest + ${project.build.directory}/generated-test-sources/contracts **/*.groovy diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java b/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java index 5abd411428..bb79fe49da 100644 --- a/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java +++ b/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; import org.springframework.boot.SpringApplication; diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java b/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java index 5d10b59b77..f22f746a8f 100644 --- a/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java +++ b/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; public class Greeting { diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java b/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java index e356ab2b10..f6db9e06b9 100644 --- a/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java +++ b/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java @@ -1,6 +1,23 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; import java.util.concurrent.atomic.AtomicLong; + import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; diff --git a/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy b/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy index 4819faaf12..82707cf2ef 100644 --- a/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy +++ b/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_ok.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_ok.groovy deleted file mode 100644 index 1a1f0c44f7..0000000000 --- a/src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_ok.groovy +++ /dev/null @@ -1,21 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'GET' - urlPath('/greeting') { - queryParameters { - parameter 'name': 'Something' - } - } - headers { - header 'Content-Type': 'application/json' - } - } - response { - status 200 - body ( - id: 1, - content: "Hello, Something!" - ) - } -} \ No newline at end of file diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_with_default_value.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_with_default_value.groovy deleted file mode 100644 index d61159c084..0000000000 --- a/src/test/projects/spring-boot-groovy/src/test/resources/accurest/greetings_with_default_value.groovy +++ /dev/null @@ -1,17 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'GET' - url('/greeting') - headers { - header 'Content-Type': 'application/json' - } - } - response { - status 200 - body ( - id: 1, - content: "Hello, World!" - ) - } -} \ No newline at end of file diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy new file mode 100644 index 0000000000..e96a275e8f --- /dev/null +++ b/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy @@ -0,0 +1,37 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + priority 2 + request { + method 'GET' + urlPath('/greeting') { + queryParameters { + parameter 'name': 'Something' + } + } + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body ( + id: 1, + content: "Hello, Something!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy b/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy new file mode 100644 index 0000000000..41ae428a8e --- /dev/null +++ b/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy @@ -0,0 +1,33 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + priority 2 + request { + method 'GET' + url('/greeting') + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body ( + id: 1, + content: "Hello, World!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/spring-boot-java/pom.xml b/src/test/projects/spring-boot-java/pom.xml index 9e9385e62c..26dd0112b4 100644 --- a/src/test/projects/spring-boot-java/pom.xml +++ b/src/test/projects/spring-boot-java/pom.xml @@ -1,4 +1,22 @@ + 4.0.0 @@ -70,8 +88,8 @@ - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin ${accurest-plugin.version} diff --git a/src/test/projects/spring-boot-java/src/main/java/hello/Application.java b/src/test/projects/spring-boot-java/src/main/java/hello/Application.java index 5abd411428..bb79fe49da 100644 --- a/src/test/projects/spring-boot-java/src/main/java/hello/Application.java +++ b/src/test/projects/spring-boot-java/src/main/java/hello/Application.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; import org.springframework.boot.SpringApplication; diff --git a/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java b/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java index 5d10b59b77..f22f746a8f 100644 --- a/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java +++ b/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java @@ -1,3 +1,19 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; public class Greeting { diff --git a/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java b/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java index e356ab2b10..f6db9e06b9 100644 --- a/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java +++ b/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java @@ -1,6 +1,23 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; import java.util.concurrent.atomic.AtomicLong; + import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; diff --git a/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java b/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java index d3bf7124e2..5d04fddb2f 100644 --- a/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java +++ b/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java @@ -1,6 +1,23 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package hello; import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; + import org.junit.Before; public class BaseAccurest { diff --git a/src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_ok.groovy b/src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_ok.groovy deleted file mode 100644 index 0ffb665f6e..0000000000 --- a/src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_ok.groovy +++ /dev/null @@ -1,21 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'GET' - urlPath('/greeting') { - queryParameters { - parameter 'name': 'Something' - } - } - headers { - header 'Content-Type': 'application/json' - } - } - response { - status 200 - body( - id: 1, - content: "Hello, Something!" - ) - } -} \ No newline at end of file diff --git a/src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_with_default_value.groovy b/src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_with_default_value.groovy deleted file mode 100644 index 2c5c32f159..0000000000 --- a/src/test/projects/spring-boot-java/src/test/resources/accurest/greetings_with_default_value.groovy +++ /dev/null @@ -1,17 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'GET' - url('/greeting') - headers { - header 'Content-Type': 'application/json' - } - } - response { - status 200 - body( - id: 1, - content: "Hello, World!" - ) - } -} \ No newline at end of file diff --git a/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy b/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy new file mode 100644 index 0000000000..4fecfabb2e --- /dev/null +++ b/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy @@ -0,0 +1,37 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + priority 2 + request { + method 'GET' + urlPath('/greeting') { + queryParameters { + parameter 'name': 'Something' + } + } + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, Something!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy b/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy new file mode 100644 index 0000000000..f2412db397 --- /dev/null +++ b/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy @@ -0,0 +1,33 @@ +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + priority 2 + request { + method 'GET' + url('/greeting') + headers { + header 'Content-Type': 'application/json' + } + } + response { + status 200 + body( + id: 1, + content: "Hello, World!" + ) + } +} \ No newline at end of file diff --git a/src/test/projects/withStubs/pom.xml b/src/test/projects/withStubs/pom.xml index fed7b7d67e..e7ee761ca9 100644 --- a/src/test/projects/withStubs/pom.xml +++ b/src/test/projects/withStubs/pom.xml @@ -1,4 +1,22 @@ + 4.0.0 @@ -10,8 +28,8 @@ - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin diff --git a/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy b/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy index 673ab7bd8d..8b10943730 100644 --- a/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy +++ b/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy @@ -1,4 +1,20 @@ -io.codearte.accurest.dsl.GroovyDsl.make { +/** + * + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'POST' url('/users') { From 817c232d3f394f604f8e97130e4a3c7825f4e85f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 19 Jun 2016 23:55:09 +0200 Subject: [PATCH 677/719] Rebranding (#287) --- .travis.yml | 18 +- README.adoc | 190 +++++++++ README.md | 47 --- .../ConversionAccurestException.groovy | 12 - .../DslToWireMockClientConverter.groovy | 17 - .../wiremock/DslToWireMockConverter.groovy | 23 - .../wiremock/SingleFileConverter.groovy | 14 - .../scenario/main_scenario/01_login.groovy | 9 - .../scenario/main_scenario/02_showCart.groovy | 9 - .../scenario/main_scenario/03_logout.groovy | 9 - .../converter/source/dir1/dsl1.groovy | 12 - .../converter/source/dir1/dsl1b.groovy | 12 - .../converter/source/dir2/dsl2.groovy | 12 - .../resources/converter/source/dslRoot.groovy | 12 - .../accurest/AccurestException.groovy | 15 - .../accurest/builder/MethodBuilder.groovy | 65 --- .../MockMvcJUnitMethodBodyBuilder.groovy | 46 -- .../codearte/accurest/config/TestMode.groovy | 21 - .../io/codearte/accurest/dsl/Accurest.groovy | 15 - .../dsl/BaseWireMockStubStrategy.groovy | 109 ----- .../io/codearte/accurest/dsl/GroovyDsl.groovy | 67 --- .../dsl/internal/ClientDslProperty.groovy | 11 - .../accurest/dsl/internal/DslProperty.groovy | 24 -- .../dsl/internal/ExecutionProperty.groovy | 19 - .../accurest/dsl/internal/Header.groovy | 23 - .../dsl/internal/JSONCompareMode.groovy | 5 - .../internal/JsonStructureConverter.groovy | 32 -- .../dsl/internal/NamedProperty.groovy | 25 -- .../dsl/internal/OptionalProperty.groovy | 13 - .../dsl/internal/QueryParameters.groovy | 23 - .../dsl/internal/ServerDslProperty.groovy | 15 - .../codearte/accurest/dsl/internal/Url.groovy | 32 -- .../accurest/dsl/internal/UrlPath.groovy | 20 - .../io/codearte/accurest/file/Contract.groovy | 30 -- .../accurest/util/AccurestDslConverter.groovy | 26 -- .../codearte/accurest/util/ContentType.groovy | 15 - .../FinishedDelegatingJsonVerifiable.java | 17 - .../codearte/accurest/util/JsonPaths.groovy | 6 - .../accurest/util/MethodBuffering.java | 9 - .../codearte/accurest/util/NamesUtil.groovy | 60 --- .../accurest/util/RegexpBuilders.groovy | 91 ---- .../accurest/util/ShouldTraverse.java | 12 - .../accurest/util/ValidateUtils.groovy | 46 -- .../accurest/GeneratorScannerSpec.groovy | 36 -- .../io/codearte/accurest/MainTest.groovy | 16 - .../accurest/builder/BookReturned.groovy | 14 - .../accurest/dsl/WireMockStubVerifier.groovy | 22 - .../dsl/internal/ExecutionPropertySpec.groovy | 19 - .../directory/with/scenario/01_login.groovy | 0 .../with/scenario/02_showCart.groovy | 0 .../directory/with/scenario/03_logout.groovy | 0 .../with/stubs/different/diff.groovy | 0 .../with/stubs/other/different/diff.groovy | 0 .../directory/with/stubs/other/other.groovy | 0 .../directory/with/stubs/other/sample.groovy | 0 .../with/stubs/package/exceptions/test.groovy | 0 .../stubs/package/v1/exceptions/testv1.groovy | 0 .../stubs/package/v2/exceptions/testv2.groovy | 0 .../test/resources/dsl/basic/sampleDsl.groovy | 30 -- .../strange_[3.3.3]_directory/02_login.groovy | 0 .../bar/03_login.groovy | 0 .../foo/01_login.groovy | 0 .../plugin/AccurestGradlePlugin.groovy | 89 ---- .../plugin/GenerateServerTestsTask.groovy | 40 -- ...erateWireMockClientStubsFromDslTask.groovy | 28 -- .../gradle-plugins/accurest.properties | 1 - .../plugin/AccurestGradlePluginTest.groovy | 22 - .../plugin/MessagingProjectSpec.groovy | 31 -- .../plugin/SampleJerseyProjectSpec.groovy | 30 -- .../accurest/plugin/SampleProjectSpec.groovy | 30 -- .../plugin/ScenarioProjectSpec.groovy | 30 -- .../bootSimple/gradle.properties | 6 - .../gradle/wrapper/gradle-wrapper.properties | 6 - .../pairId/collerate_PlacesFrom_Tweet.groovy | 18 - .../pairId/moreComplexVersion.groovy | 25 -- .../functionalTest/bootSimple/settings.gradle | 1 - .../ofg/twitter/places/AcceptanceSpec.groovy | 23 - .../ofg/twitter/places/BaseMockMvcSpec.groovy | 23 - .../src/test/resources/logback-test.groovy | 14 - .../messagingProject/gradle.properties | 6 - .../gradle/wrapper/gradle-wrapper.properties | 6 - .../repository/mappings/a_foo.groovy | 10 - .../repository/mappings/bookDeleted.groovy | 13 - .../repository/mappings/bookReturned1.groovy | 13 - .../repository/mappings/bookReturned2.groovy | 21 - .../messagingProject/settings.gradle | 1 - .../accurest/samples/book/BookDeleted.groovy | 14 - .../accurest/samples/book/BookReturned.groovy | 14 - .../IntegrationMessagingApplication.groovy | 22 - .../shouldMarkClientAsFraud.groovy | 27 -- .../shouldMarkClientAsNotFraud.groovy | 28 -- .../model/FraudCheckStatus.java | 5 - .../gradle/wrapper/gradle-wrapper.properties | 6 - .../frauddetection/model/Client.java | 14 - .../model/FraudCheckStatus.java | 5 - .../model/FraudServiceRequest.java | 34 -- .../frauddetection/model/LoanApplication.java | 36 -- .../sampleJerseyProject/settings.gradle | 2 - .../shouldMarkClientAsFraud.groovy | 27 -- .../shouldMarkClientAsNotFraud.groovy | 28 -- .../model/FraudCheckStatus.java | 5 - .../com/blogspot/toomuchcoding/MvcSpec.groovy | 15 - .../gradle/wrapper/gradle-wrapper.properties | 6 - .../model/FraudCheckStatus.java | 5 - .../sampleProject/settings.gradle | 2 - .../1_shouldMarkClientAsNotFraud.groovy | 28 -- .../2_shouldMarkClientAsFraud.groovy | 27 -- .../model/FraudCheckStatus.java | 5 - .../com/blogspot/toomuchcoding/MvcSpec.groovy | 15 - .../gradle/wrapper/gradle-wrapper.properties | 6 - .../frauddetection/Application.java | 17 - .../model/FraudCheckStatus.java | 5 - .../model/FraudServiceResponse.java | 27 -- .../model/LoanApplicationStatus.java | 5 - .../scenarioProject/settings.gradle | 2 - accurest-messaging/README.adoc | 25 -- .../accurest-messaging-camel/build.gradle | 16 - .../camel/AccurestCamelConfiguration.java | 22 - .../camel/AccurestCamelMessageBuilder.java | 31 -- .../messaging/camel/CamelMessage.java | 40 -- .../accurest-messaging-core/build.gradle | 8 - .../accurest/messaging/AccurestFilter.java | 14 - .../accurest/messaging/AccurestMessage.java | 32 -- .../messaging/AccurestMessageBuilder.java | 22 - .../accurest/messaging/AccurestMessaging.java | 34 -- .../messaging/AccurestObjectMapper.java | 30 -- .../messaging/noop/NoOpAccurestMessage.java | 30 -- .../noop/NoOpAccurestMessageBuilder.java | 21 - .../messaging/noop/NoOpAccurestMessaging.java | 42 -- .../build.gradle | 16 - .../AccurestIntegrationConfiguration.java | 22 - .../AccurestIntegrationMessageBuilder.java | 29 -- .../AccurestIntegrationMessaging.java | 84 ---- .../integration/IntegrationMessage.java | 38 -- .../main/resources/META-INF/spring.factories | 3 - .../accurest-messaging-stream/build.gradle | 17 - .../AccurestStreamAutoConfiguration.java | 24 -- .../stream/AccurestStreamMessageBuilder.java | 29 -- .../messaging/stream/StreamMessage.java | 39 -- .../main/resources/META-INF/spring.factories | 3 - .../accurest/util/AssertionUtil.groovy | 12 - asciidoctor.css | 399 ++++++++++++++++++ build.gradle | 153 +------ docs/build.gradle | 45 +- docs/src/docs/asciidoc/index.adoc | 19 - docs/src/docs/asciidoc/messaging.adoc | 148 ------- docs/src/docs/asciidoc/migration.adoc | 23 - docs/src/docs/asciidoc/stubrunner_msg.adoc | 58 --- docs/src/main/asciidoc/README.adoc | 17 + .../src/{docs => main}/asciidoc/contract.adoc | 58 +-- .../{docs => main}/asciidoc/images/Deps.png | Bin .../{docs => main}/asciidoc/images/Stubs1.png | Bin .../{docs => main}/asciidoc/images/Stubs2.png | Bin docs/src/main/asciidoc/index.adoc | 1 + .../{docs => main}/asciidoc/introduction.adoc | 25 +- docs/src/main/asciidoc/messaging.adoc | 150 +++++++ docs/src/{docs => main}/asciidoc/rest.adoc | 102 ++--- .../spring-cloud-contract-verifier.adoc | 20 + .../{docs => main}/asciidoc/stubrunner.adoc | 38 +- docs/src/main/asciidoc/stubrunner_msg.adoc | 61 +++ docs/src/main/ruby/generate_readme.sh | 37 ++ generateReadme.sh | 3 + gradle.properties | 22 +- gradle/release.gradle | 127 +++--- gradle/releaseRoot.gradle | 16 - gradle/wrapper/gradle-wrapper.properties | 4 +- docs.sh => publishDocs.sh | 0 samples/messaging-camel/build.gradle | 26 -- .../accurest/samples/camel/BookDeleted.groovy | 14 - .../samples/camel/BookReturned.groovy | 14 - .../camel/CamelMessagingApplication.groovy | 12 - samples/messaging-integration/build.gradle | 22 - .../samples/messaging/BookDeleted.groovy | 14 - .../samples/messaging/BookReturned.groovy | 14 - .../IntegrationMessagingApplication.groovy | 14 - samples/messaging-spring/build.gradle | 25 -- .../samples/spring/BookDeleted.groovy | 14 - .../samples/spring/BookReturned.groovy | 14 - .../spring/SpringMessagingApplication.groovy | 14 - .../AccurestSpringMessageBuilder.groovy | 35 -- .../config/AccurestSpringMessaging.groovy | 77 ---- .../config/ManualAccurestConfiguration.groovy | 18 - samples/messaging-stream/build.gradle | 22 - .../samples/messaging/BookDeleted.groovy | 14 - .../samples/messaging/BookReturned.groovy | 14 - .../samples/messaging/DeleteSink.groovy | 16 - .../StreamMessagingApplication.groovy | 16 - samples/samples-messaging-camel/build.gradle | 44 ++ .../verifier/samples/camel/BookDeleted.groovy | 30 ++ .../samples/camel/BookDeleter.groovy | 18 +- .../samples/camel/BookReturned.groovy | 30 ++ .../camel/BookRouteConfiguration.groovy | 18 +- .../samples/camel/BookService.groovy | 18 +- .../camel/CamelMessagingApplication.groovy | 28 ++ .../CamelMessagingApplicationSpec.groovy | 56 ++- .../build.gradle | 40 ++ .../samples/messaging/BookDeleted.groovy | 30 ++ .../samples/messaging/BookListener.groovy | 18 +- .../samples/messaging/BookReturned.groovy | 30 ++ .../samples/messaging/BookService.groovy | 18 +- .../IntegrationMessagingApplication.groovy | 30 ++ .../main/resources/integration-context.xml | 22 +- ...IntegrationMessagingApplicationSpec.groovy | 56 ++- samples/samples-messaging-spring/build.gradle | 43 ++ .../samples/spring/BookDeleted.groovy | 30 ++ .../samples/spring/BookListener.groovy | 18 +- .../samples/spring/BookReturned.groovy | 30 ++ .../samples/spring/BookService.groovy | 18 +- .../spring/SpringMessagingApplication.groovy | 30 ++ .../spring/SpringApplicationSpec.groovy | 56 ++- ...ontractVerifierSpringMessageBuilder.groovy | 51 +++ .../ContractVerifierSpringMessaging.groovy | 93 ++++ ...ManualContractVerifierConfiguration.groovy | 35 ++ .../spring/config/SpringMessage.groovy | 22 +- samples/samples-messaging-stream/build.gradle | 40 ++ .../samples/messaging/BookDeleted.groovy | 30 ++ .../samples/messaging/BookListener.groovy | 18 +- .../samples/messaging/BookReturned.groovy | 30 ++ .../samples/messaging/BookService.groovy | 18 +- .../samples/messaging/DeleteSink.groovy | 32 ++ .../StreamMessagingApplication.groovy | 32 ++ .../src/main/resources/application.yml | 0 .../StreamMessagingApplicationSpec.groovy | 56 ++- scripts/runTests.sh | 10 +- settings.gradle | 52 ++- .../README.adoc | 14 +- .../build.gradle | 40 ++ .../boot/HttpStubsController.groovy | 20 +- .../stubrunner/boot/StubRunnerBoot.groovy | 52 +++ .../stubrunner/boot/TriggerController.groovy | 20 +- .../main/resources/META-INF/spring.factories | 2 +- .../stubrunner/boot/StubRunnerBootSpec.groovy | 36 +- .../src/test/resources/application.yml | 2 + .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1788 bytes .../streamService-0.0.1-SNAPSHOT.pom | 25 ++ .../stubs/streamService/maven-metadata.xml | 28 ++ .../README.adoc | 16 +- .../build.gradle | 35 ++ .../stubrunner/junit/StubRunnerRule.java | 72 ++-- .../StubRunnerRuleCustomPortJUnitTest.java | 85 ++++ .../junit/StubRunnerRuleJUnitTest.java | 81 ++++ .../junit/StubRunnerRuleSpec.groovy | 58 +++ .../src/test/resources/logback.xml | 30 ++ ...udDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 25 ++ .../fraudDetectionServer/maven-metadata.xml | 28 ++ .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin .../loanIssuance-0.0.1-SNAPSHOT.pom | 25 ++ .../stubs/loanIssuance/maven-metadata.xml | 28 ++ .../README.adoc | 22 +- .../build.gradle | 45 ++ .../camel/StubRunnerCamelConfiguration.groovy | 51 +++ .../camel/StubRunnerCamelPredicate.groovy | 32 +- .../camel/StubRunnerCamelProcessor.groovy | 52 +++ .../main/resources/META-INF/spring.factories | 3 + .../messaging/camel/BookReturned.groovy | 32 ++ .../camel/CamelStubRunnerSpec.groovy | 36 +- .../src/test/resources/application.yml | 2 + .../camelService-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1797 bytes .../camelService-0.0.1-SNAPSHOT.pom | 25 ++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 28 ++ .../camelService/maven-metadata-local.xml | 28 ++ .../stubs/camelService/maven-metadata.xml | 28 ++ .../README.adoc | 22 +- .../build.gradle | 41 ++ .../StubRunnerIntegrationConfiguration.groovy | 32 +- ...tubRunnerIntegrationMessageSelector.groovy | 32 +- .../StubRunnerIntegrationTransformer.groovy | 48 +++ .../main/resources/META-INF/spring.factories | 3 + .../messaging/integration/BookReturned.groovy | 32 ++ .../IntegrationStubRunnerSpec.groovy | 54 ++- .../src/test/resources/application.yml | 2 + .../test/resources/integration-context.xml | 16 + ...ntegrationService-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1788 bytes .../integrationService-0.0.1-SNAPSHOT.pom | 25 ++ .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 28 ++ .../maven-metadata-local.xml | 28 ++ .../integrationService/maven-metadata.xml | 28 ++ .../README.adoc | 22 +- .../build.gradle | 43 ++ .../StubRunnerStreamConfiguration.groovy | 32 +- .../StubRunnerStreamMessageSelector.groovy | 32 +- .../stream/StubRunnerStreamTransformer.groovy | 48 +++ .../main/resources/META-INF/spring.factories | 3 + .../messaging/stream/BookReturned.groovy | 32 ++ .../stream/StreamStubRunnerSpec.groovy | 54 ++- .../src/test/resources/application.yml | 2 +- .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 28 ++ .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 0 -> 1809 bytes .../streamService-0.0.1-SNAPSHOT.pom | 25 ++ .../streamService/maven-metadata-local.xml | 28 ++ .../stubs/streamService/maven-metadata.xml | 28 ++ .../README.adoc | 2 +- .../build.gradle | 20 +- .../spring/cloud/StubMapperProperties.java | 20 +- .../cloud/StubRunnerDiscoveryClient.java | 26 +- .../cloud/StubRunnerServiceInstance.java | 20 +- ...tubRunnerSpringCloudAutoConfiguration.java | 24 +- .../StubRunnerRibbonAutoConfiguration.java | 20 +- .../StubRunnerRibbonBeanPostProcessor.java | 24 +- .../ribbon/StubRunnerRibbonConfiguration.java | 18 +- .../ribbon/StubRunnerRibbonServerList.java | 37 +- .../main/resources/META-INF/spring.factories | 4 + ...nerSpringCloudAutoConfigurationSpec.groovy | 20 +- .../src/test/resources/application.yml | 2 +- .../src/test/resources/logback.xml | 30 ++ ...udDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 25 ++ .../fraudDetectionServer/maven-metadata.xml | 28 ++ .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin .../loanIssuance-0.0.1-SNAPSHOT.pom | 25 ++ .../stubs/loanIssuance/maven-metadata.xml | 28 ++ .../README.adoc | 2 +- .../build.gradle | 38 ++ .../spring/StubRunnerConfiguration.java | 46 +- .../main/resources/META-INF/spring.factories | 2 +- .../spring/StubRunnerConfigurationSpec.groovy | 57 +++ .../src/test/resources/application.yml | 2 + .../src/test/resources/logback.xml | 30 ++ ...udDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 25 ++ .../fraudDetectionServer/maven-metadata.xml | 28 ++ .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin .../loanIssuance-0.0.1-SNAPSHOT.pom | 25 ++ .../stubs/loanIssuance/maven-metadata.xml | 28 ++ .../README.adoc | 8 +- .../build.gradle | 26 +- .../stubrunner/AetherFactories.groovy | 18 +- .../stubrunner/AetherStubDownloader.groovy | 36 +- .../contract/stubrunner/Arguments.groovy | 43 ++ .../stubrunner/AvailablePortScanner.groovy | 18 +- .../stubrunner/BatchStubRunner.groovy | 28 +- .../stubrunner/BatchStubRunnerFactory.groovy | 59 +++ .../stubrunner/GroovyDslWrapper.groovy | 39 ++ .../MessageNotMatchingException.groovy | 28 ++ .../contract}/stubrunner/RunningStubs.groovy | 18 +- .../stubrunner/StubConfiguration.groovy | 21 +- .../cloud/contract/stubrunner/StubData.groovy | 31 ++ .../contract/stubrunner/StubDownloader.groovy | 28 ++ .../contract/stubrunner/StubFinder.groovy | 49 +++ .../stubrunner/StubRepository.groovy | 49 ++- .../contract}/stubrunner/StubRunner.groovy | 38 +- .../stubrunner/StubRunnerExecutor.groovy | 58 ++- .../stubrunner/StubRunnerFactory.groovy | 28 +- .../stubrunner/StubRunnerMain.groovy | 18 +- .../StubRunnerMessagingTrigger.groovy | 35 ++ .../stubrunner/StubRunnerOptions.groovy | 18 +- .../StubRunnerOptionsBuilder.groovy | 20 +- .../contract/stubrunner/StubRunning.groovy | 25 ++ .../contract}/stubrunner/StubServer.groovy | 24 +- .../contract}/stubrunner/StubTrigger.groovy | 18 +- .../WiremockMappingDescriptor.groovy | 43 ++ .../stubrunner/util/StringUtils.groovy | 18 +- .../stubrunner/util/StubsParser.groovy | 20 +- .../stubrunner/util/ZipCategory.groovy | 18 +- .../accurestStubrunnerGrapeConfig.xml | 28 ++ .../AvailablePortScannerSpec.groovy | 18 +- .../stubrunner/BatchStubRunnerSpec.groovy | 18 +- .../stubrunner/MappingDescriptorSpec.groovy | 39 ++ .../stubrunner/RunningStubsSpec.groovy | 18 +- .../stubrunner/StubConfigurationSpec.groovy | 37 ++ .../stubrunner/StubRepositorySpec.groovy | 18 +- .../stubrunner/StubRunnerExecutorSpec.groovy | 20 +- .../stubrunner/StubRunnerFactorySpec.groovy | 22 +- .../StubRunnerOptionsBuilderSpec.groovy | 18 +- .../stubrunner/StubRunnerSpec.groovy | 18 +- .../stubrunner/StubServerSpec.groovy | 20 +- .../stubrunner/util/ZipCategorySpec.groovy | 40 ++ .../mappings/spring/cloud}/bar/bar.json | 0 .../spring/cloud}/foo/bar/foobar.json | 0 .../mappings/spring/cloud}/foo/foo.json | 0 .../projects/brokers/brokers.json | 5 + .../brokers/nested/anotherDescriptor.json | 5 + .../projects/descriptor.json | 5 + .../src/test/resources/emptyrepo}/.gitkeep | 0 .../src/test/resources/file.zip | Bin .../src/test/resources/logback.xml | 30 ++ .../mappings/lv/spring/cloud}/bye/lv_bye.json | 0 .../mappings/pl/spring/cloud}/bye/pl_bye.json | 0 .../spring/cloud}/bye/pl_overridden_bye.json | 0 .../spring/cloud}/bye/admin/admin.json | 0 .../mappings/spring/cloud}/bye/bye.json | 0 .../mappings/spring/cloud}/hello/README.md | 0 .../spring/cloud}/hello/admin/admin.json | 0 .../mappings/spring/cloud}/hello/hello.json | 0 .../mappings/spring/cloud}/ping/ping.json | 0 spring-cloud-contract-verifier/build.gradle | 118 ++++++ .../main/groovy/nl/flotsam/xeger/Xeger.java | 0 .../converter/SingleFileConverter.groovy | 44 ++ ...ConversionContractVerifierException.groovy | 33 ++ .../DslToWireMockClientConverter.groovy | 38 ++ .../wiremock/DslToWireMockConverter.groovy | 45 ++ .../wiremock/RecursiveFilesConverter.groovy | 40 +- .../wiremock/WireMockToDslConverter.groovy | 35 +- .../groovy/nl/flotsam/xeger/XegerTest.java | 0 .../nl/flotsam/xeger/XegerUtilsTest.java | 0 .../DslToWireMockClientConverterSpec.groovy | 44 +- .../RecursiveFilesConverterSpec.groovy | 29 +- .../WireMockToDslConverterSpec.groovy | 88 ++-- .../WiremockScenarioConverterSpec.groovy | 26 +- .../scenario/main_scenario/01_login.groovy | 27 ++ .../scenario/main_scenario/02_showCart.groovy | 27 ++ .../scenario/main_scenario/03_logout.groovy | 27 ++ .../converter/source/dir1/dsl1.groovy | 30 ++ .../converter/source/dir1/dsl1b.groovy | 30 ++ .../converter/source/dir2/dsl2.groovy | 30 ++ .../resources/converter/source/dslRoot.groovy | 30 ++ .../verifier/ContractVerifierException.groovy | 34 ++ .../cloud/contract/verifier}/FileSaver.groovy | 26 +- .../contract/verifier}/TestGenerator.groovy | 55 ++- .../verifier}/builder/BlockBuilder.groovy | 32 +- .../verifier}/builder/ClassBuilder.groovy | 45 +- .../JUnitMessagingMethodBodyBuilder.groovy | 54 ++- .../builder/JUnitMethodBodyBuilder.groovy | 44 +- .../JaxRsClientJUnitMethodBodyBuilder.groovy | 50 ++- ...kMethodRequestProcessingBodyBuilder.groovy | 43 +- .../builder/MessagingMethodBodyBuilder.groovy | 42 +- .../builder/MethodBodyBuilder.groovy | 186 +++++++- .../verifier/builder/MethodBuilder.groovy | 95 +++++ .../MockMvcJUnitMethodBodyBuilder.groovy | 69 +++ ...kMethodRequestProcessingBodyBuilder.groovy | 33 +- .../RequestProcessingMethodBodyBuilder.groovy | 89 +++- .../builder}/SingleTestGenerator.groovy | 87 ++-- .../SpockMessagingMethodBodyBuilder.groovy | 44 +- ...kMethodRequestProcessingBodyBuilder.groovy | 38 +- .../ContractVerifierConfigProperties.groovy | 36 +- .../verifier}/config/TestFramework.groovy | 24 +- .../contract/verifier/config/TestMode.groovy | 41 ++ .../contract/verifier/dsl/Contract.groovy | 93 ++++ .../verifier}/dsl/internal/Body.groovy | 23 +- .../dsl/internal/ClientDslProperty.groovy | 32 ++ .../verifier}/dsl/internal/Common.groovy | 22 +- .../verifier/dsl/internal/DslProperty.groovy | 45 ++ .../dsl/internal/ExecutionProperty.groovy | 45 ++ .../verifier/dsl/internal/Header.groovy | 44 ++ .../verifier}/dsl/internal/Headers.groovy | 29 +- .../verifier}/dsl/internal/Input.groovy | 42 +- .../dsl/internal/JSONCompareMode.groovy | 26 ++ .../dsl/internal/MatchingStrategy.groovy | 24 +- .../verifier}/dsl/internal/Multipart.groovy | 18 +- .../dsl/internal/NamedProperty.groovy | 48 +++ .../dsl/internal/OptionalProperty.groovy | 41 ++ .../dsl/internal/OutputMessage.groovy | 18 +- .../dsl/internal/QueryParameter.groovy | 25 +- .../dsl/internal/QueryParameters.groovy | 39 ++ .../dsl/internal/RegexPatterns.groovy | 24 +- .../verifier}/dsl/internal/Request.groovy | 24 +- .../verifier}/dsl/internal/Response.groovy | 25 +- .../dsl/internal/ServerDslProperty.groovy | 36 ++ .../contract/verifier/dsl/internal/Url.groovy | 53 +++ .../verifier/dsl/internal/UrlPath.groovy | 41 ++ .../wiremock/BaseWireMockStubStrategy.groovy | 126 ++++++ .../WireMockRequestStubStrategy.groovy | 65 ++- .../WireMockResponseStubStrategy.groovy | 39 +- .../dsl/wiremock}/WireMockStubStrategy.groovy | 32 +- .../verifier}/file/ContractFileScanner.groovy | 44 +- .../verifier/file/ContractMetadata.groovy | 53 +++ .../verifier/util/BodyAsStringUtil.groovy | 45 +- .../contract/verifier/util/ContentType.groovy | 36 ++ .../verifier}/util/ContentUtils.groovy | 30 +- .../util/ContractVerifierDslConverter.groovy | 44 ++ .../util/DelegatingJsonVerifiable.java | 23 +- .../FinishedDelegatingJsonVerifiable.java | 38 ++ .../contract/verifier/util/JsonPaths.groovy | 29 ++ .../util/JsonToJsonPathsConverter.groovy | 24 +- .../verifier}/util/MapConverter.groovy | 44 +- .../verifier/util/MethodBuffering.java | 29 ++ .../util/MethodBufferingJsonVerifiable.java | 23 +- .../contract/verifier/util/NamesUtil.groovy | 111 +++++ .../verifier/util/RegexpBuilders.groovy | 155 +++++++ .../verifier/util/ShouldTraverse.java | 33 ++ .../verifier/util/ValidateUtils.groovy | 69 +++ .../stubs/wiremocks/other/sample.json | 0 .../resources/stubs/wiremocks/sample.json | 0 .../verifier/GeneratorScannerSpec.groovy | 53 +++ .../cloud/contract/verifier/MainTest.groovy | 32 ++ .../verifier/builder/BookReturned.groovy | 30 ++ .../builder/ContractHttpDocsSpec.groovy | 64 +-- .../JaxRsClientMethodBuilderSpec.groovy | 151 ++++--- .../MessagingMethodBodyBuilderSpec.groovy | 95 +++-- .../MockMvcMethodBodyBuilderSpec.groovy | 269 ++++++------ .../builder}/SingleTestGeneratorSpec.groovy | 48 ++- .../dsl/WireMockGroovyDslSpec.groovy | 125 +++--- .../verifier/dsl/WireMockStubVerifier.groovy | 39 ++ .../dsl/internal/ExecutionPropertySpec.groovy | 35 ++ .../dsl/internal/RegexPatternsSpec.groovy | 18 +- .../file/ContractFileScannerSpec.groovy | 30 +- .../util/JsonToJsonPathsConverterSpec.groovy | 18 +- .../directory/with/scenario/01_login.groovy | 16 + .../with/scenario/02_showCart.groovy | 16 + .../directory/with/scenario/03_logout.groovy | 16 + .../with/stubs/different/diff.groovy | 16 + .../with/stubs/other/different/diff.groovy | 16 + .../directory/with/stubs/other/other.groovy | 16 + .../directory/with/stubs/other/sample.groovy | 16 + .../with/stubs/package/exceptions/test.groovy | 16 + .../stubs/package/v1/exceptions/testv1.groovy | 16 + .../stubs/package/v2/exceptions/testv2.groovy | 16 + .../with/stubs/stubsRepositoryIndicator | 0 .../test/resources/dsl/basic/sampleDsl.groovy | 48 +++ .../src/test/resources/main.json | 0 .../strange_[3.3.3]_directory/02_login.groovy | 16 + .../bar/03_login.groovy | 16 + .../foo/01_login.groovy | 16 + .../plugin/GenerateServerTestsTask.groovy | 61 +++ ...erateWireMockClientStubsFromDslTask.groovy | 49 +++ ...ngCloudContractVerifierGradlePlugin.groovy | 114 +++++ .../contract-verifier.properties | 17 + .../plugin/BasicFunctionalSpec.groovy | 42 +- .../ContractVerifierIntegrationSpec.groovy | 40 +- .../plugin/MessagingProjectSpec.groovy | 47 +++ .../plugin/SampleJerseyProjectSpec.groovy | 46 ++ .../verifier/plugin/SampleProjectSpec.groovy | 46 ++ .../plugin/ScenarioProjectSpec.groovy | 46 ++ .../functionalTest/bootSimple/build.gradle | 14 +- .../bootSimple/gradle.properties | 22 + .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 22 + .../functionalTest/bootSimple/gradlew | 0 .../functionalTest/bootSimple/gradlew.bat | 0 .../pairId/collerate_PlacesFrom_Tweet.groovy | 36 ++ .../pairId/moreComplexVersion.groovy | 43 ++ .../functionalTest/bootSimple/settings.gradle | 17 + .../twitter/place/PairIdController.groovy | 20 +- .../cloud}/twitter/place/Tweet.java | 2 +- .../twitter/places/AcceptanceSpec.groovy | 39 ++ .../twitter/places/BaseMockMvcSpec.groovy | 39 ++ .../src/test/resources/logback-test.groovy | 30 ++ .../messagingProject/build.gradle | 16 +- .../messagingProject/gradle.properties | 22 + .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 22 + .../functionalTest/messagingProject/gradlew | 0 .../messagingProject/gradlew.bat | 0 .../repository/mappings/a_foo.groovy | 28 ++ .../repository/mappings/bookDeleted.groovy | 31 ++ .../repository/mappings/bookReturned1.groovy | 30 ++ .../repository/mappings/bookReturned2.groovy | 38 ++ .../messagingProject/settings.gradle | 17 + .../cloud/samples/book/BookDeleted.groovy | 30 ++ .../cloud}/samples/book/BookListener.groovy | 18 +- .../cloud/samples/book/BookReturned.groovy | 30 ++ .../cloud}/samples/book/BookService.groovy | 18 +- .../IntegrationMessagingApplication.groovy | 38 ++ .../main/resources/integration-context.xml | 22 +- .../samples/book/MessagingBaseSpec.groovy | 18 +- .../samples/book/MessagingBaseTest.java | 18 +- .../sampleJerseyProject/build.gradle | 30 +- .../shouldMarkClientAsFraud.groovy | 45 ++ .../shouldMarkClientAsNotFraud.groovy | 46 ++ .../cloud}/frauddetection/Application.java | 2 +- .../FraudDetectionController.java | 10 +- .../frauddetection/FraudRestApplication.java | 2 +- .../frauddetection/model/FraudCheck.java | 2 +- .../model/FraudCheckResult.java | 2 +- .../model/FraudCheckStatus.java | 5 + .../src/main/resources/application.yml | 0 .../org/springframework/cloud}/MvcSpec.groovy | 22 +- .../org/springframework/cloud}/MvcTest.java | 6 +- .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 22 + .../sampleJerseyProject/gradlew | 0 .../sampleJerseyProject/gradlew.bat | 0 .../loanApplicationService/mappings/.gitkeep | 0 .../cloud/frauddetection/Application.java | 33 ++ .../LoanApplicationService.java | 30 +- .../cloud/frauddetection/model/Client.java | 30 ++ .../model/FraudCheckStatus.java | 21 + .../model/FraudServiceRequest.java | 50 +++ .../model/FraudServiceResponse.java | 43 ++ .../frauddetection/model/LoanApplication.java | 52 +++ .../model/LoanApplicationResult.java | 18 +- .../model/LoanApplicationStatus.java | 21 + .../src/main/resources/application.yml | 0 .../cloud}/LoanApplicationServiceSpec.groovy | 30 +- .../shouldMarkClientAsFraud.json | 0 .../shouldMarkClientAsNotFraud.json | 0 .../sampleJerseyProject/settings.gradle | 18 + .../functionalTest/sampleProject/build.gradle | 30 +- .../shouldMarkClientAsFraud.groovy | 44 ++ .../shouldMarkClientAsNotFraud.groovy | 45 ++ .../frauddetection/Application.java | 5 +- .../FraudDetectionController.java | 10 +- .../frauddetection/model/FraudCheck.java | 2 +- .../model/FraudCheckResult.java | 2 +- .../model/FraudCheckStatus.java | 5 + .../src/main/resources/application.yml | 0 .../org/springframework/cloud/MvcSpec.groovy | 31 ++ .../org/springframework/cloud}/MvcTest.java | 4 +- .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 22 + .../functionalTest/sampleProject/gradlew | 0 .../functionalTest/sampleProject/gradlew.bat | 0 .../loanApplicationService/mappings/.gitkeep | 0 .../cloud}/frauddetection/Application.java | 5 +- .../LoanApplicationService.java | 14 +- .../cloud}/frauddetection/model/Client.java | 2 +- .../model/FraudCheckStatus.java | 5 + .../model/FraudServiceRequest.java | 2 +- .../model/FraudServiceResponse.java | 2 +- .../frauddetection/model/LoanApplication.java | 2 +- .../model/LoanApplicationResult.java | 2 +- .../model/LoanApplicationStatus.java | 2 +- .../src/main/resources/application.yml | 0 .../cloud}/LoanApplicationServiceSpec.groovy | 30 +- .../shouldMarkClientAsFraud.json | 0 .../shouldMarkClientAsNotFraud.json | 0 .../sampleProject/settings.gradle | 18 + .../scenarioProject/build.gradle | 30 +- .../1_shouldMarkClientAsNotFraud.groovy | 45 ++ .../2_shouldMarkClientAsFraud.groovy | 45 ++ .../cloud}/frauddetection/Application.java | 5 +- .../FraudDetectionController.java | 10 +- .../frauddetection/model/FraudCheck.java | 2 +- .../model/FraudCheckResult.java | 2 +- .../model/FraudCheckStatus.java | 5 + .../src/main/resources/application.yml | 0 .../org/springframework/cloud/MvcSpec.groovy | 31 ++ .../org/springframework/cloud}/MvcTest.java | 4 +- .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 22 + .../functionalTest/scenarioProject/gradlew | 0 .../scenarioProject/gradlew.bat | 0 .../loanApplicationService/mappings}/.gitkeep | 0 .../cloud}/frauddetection/Application.java | 5 +- .../LoanApplicationService.java | 14 +- .../cloud}/frauddetection/model/Client.java | 2 +- .../model/FraudCheckStatus.java | 5 + .../model/FraudServiceRequest.java | 2 +- .../model/FraudServiceResponse.java | 2 +- .../frauddetection/model/LoanApplication.java | 2 +- .../model/LoanApplicationResult.java | 2 +- .../model/LoanApplicationStatus.java | 2 +- .../src/main/resources/application.yml | 0 .../cloud}/LoanApplicationServiceSpec.groovy | 30 +- .../shouldMarkClientAsFraud.json | 0 .../shouldMarkClientAsNotFraud.json | 0 .../scenarioProject/settings.gradle | 18 + .../README.adoc | 23 + .../build.gradle | 34 ++ .../messaging/camel/CamelMessage.java | 56 +++ .../ContractVerifierCamelConfiguration.java | 37 ++ .../ContractVerifierCamelMessageBuilder.java | 48 +++ .../camel/ContractVerifierCamelMessaging.java | 46 +- .../main/resources/META-INF/spring.factories | 3 + .../build.gradle | 34 ++ ...tractVerifierIntegrationConfiguration.java | 36 ++ ...ractVerifierIntegrationMessageBuilder.java | 45 ++ .../ContractVerifierIntegrationMessaging.java | 102 +++++ .../integration/IntegrationMessage.java | 54 +++ .../main/resources/META-INF/spring.factories | 3 + .../build.gradle | 24 ++ .../messaging/ContractVerifierFilter.java | 30 ++ .../messaging/ContractVerifierMessage.java | 48 +++ .../ContractVerifierMessageBuilder.java | 38 ++ .../messaging/ContractVerifierMessaging.java | 51 +++ .../ContractVerifierMessagingUtil.java | 28 +- .../ContractVerifierObjectMapper.java | 46 ++ .../noop/NoOpContractVerifierMessage.java | 46 ++ .../NoOpContractVerifierMessageBuilder.java | 38 ++ .../noop/NoOpContractVerifierMessaging.java | 58 +++ .../build.gradle | 35 ++ ...ntractVerifierStreamAutoConfiguration.java | 38 ++ .../ContractVerifierStreamMessageBuilder.java | 46 ++ .../ContractVerifierStreamMessaging.java | 43 +- .../messaging/stream/StreamMessage.java | 54 +++ .../main/resources/META-INF/spring.factories | 3 + .../verifier/util/AssertionUtil.groovy | 28 ++ stub-runner/stub-runner-boot/build.gradle | 22 - .../stubrunner/boot/StubRunnerBoot.groovy | 15 - .../stubrunner/boot/StubRunnerConfig.groovy | 28 -- .../main/resources/META-INF/spring.factories | 3 - .../src/test/resources/application.yml | 2 - .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 1746 -> 0 bytes .../streamService-0.0.1-SNAPSHOT.pom | 9 - .../stubs/streamService/maven-metadata.xml | 12 - stub-runner/stub-runner-junit/build.gradle | 17 - .../AccurestRuleCustomPortJUnitTest.java | 68 --- .../junit/AccurestRuleJUnitTest.java | 64 --- .../stubrunner/junit/AccurestRuleSpec.groovy | 42 -- .../src/test/resources/logback.xml | 14 - .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 9 - .../fraudDetectionServer/maven-metadata.xml | 12 - .../loanIssuance-0.0.1-SNAPSHOT.pom | 9 - .../stubs/loanIssuance/maven-metadata.xml | 12 - .../stub-runner-messaging-camel/build.gradle | 26 -- .../camel/StubRunnerCamelConfiguration.groovy | 35 -- .../camel/StubRunnerCamelProcessor.groovy | 36 -- .../messaging/camel/BookReturned.groovy | 16 - .../src/test/resources/application.yml | 2 - .../camelService-0.0.1-SNAPSHOT-stubs.jar | Bin 1754 -> 0 bytes .../camelService-0.0.1-SNAPSHOT.pom | 9 - .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 - .../camelService/maven-metadata-local.xml | 12 - .../stubs/camelService/maven-metadata.xml | 12 - .../build.gradle | 23 - .../StubRunnerIntegrationTransformer.groovy | 32 -- .../main/resources/META-INF/spring.factories | 3 - .../messaging/integration/BookReturned.groovy | 16 - .../src/test/resources/application.yml | 2 - ...ntegrationService-0.0.1-SNAPSHOT-stubs.jar | Bin 1746 -> 0 bytes .../integrationService-0.0.1-SNAPSHOT.pom | 9 - .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 - .../maven-metadata-local.xml | 12 - .../integrationService/maven-metadata.xml | 12 - .../stub-runner-messaging-stream/build.gradle | 24 -- .../stream/StubRunnerStreamTransformer.groovy | 32 -- .../main/resources/META-INF/spring.factories | 3 - .../messaging/stream/BookReturned.groovy | 16 - .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 12 - .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 1756 -> 0 bytes .../streamService-0.0.1-SNAPSHOT.pom | 9 - .../streamService/maven-metadata-local.xml | 12 - .../stubs/streamService/maven-metadata.xml | 12 - .../main/resources/META-INF/spring.factories | 4 - .../src/test/resources/logback.xml | 14 - .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 9 - .../fraudDetectionServer/maven-metadata.xml | 12 - .../loanIssuance-0.0.1-SNAPSHOT.pom | 9 - .../stubs/loanIssuance/maven-metadata.xml | 12 - stub-runner/stub-runner-spring/build.gradle | 20 - .../main/resources/META-INF/spring.factories | 3 - .../spring/StubRunnerConfigurationSpec.groovy | 41 -- .../src/test/resources/application.yml | 2 - .../src/test/resources/logback.xml | 14 - .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 9 - .../fraudDetectionServer/maven-metadata.xml | 12 - .../loanIssuance-0.0.1-SNAPSHOT.pom | 9 - .../stubs/loanIssuance/maven-metadata.xml | 12 - .../accurest/stubrunner/Arguments.groovy | 27 -- .../stubrunner/BatchStubRunnerFactory.groovy | 43 -- .../stubrunner/GroovyDslWrapper.groovy | 23 - .../MessageNotMatchingException.groovy | 12 - .../accurest/stubrunner/StubData.groovy | 15 - .../accurest/stubrunner/StubDownloader.groovy | 12 - .../accurest/stubrunner/StubFinder.groovy | 33 -- .../StubRunnerMessagingTrigger.groovy | 18 - .../accurest/stubrunner/StubRunning.groovy | 9 - .../WiremockMappingDescriptor.groovy | 27 -- .../accurestStubrunnerGrapeConfig.xml | 12 - .../stubrunner/MappingDescriptorSpec.groovy | 23 - .../stubrunner/StubConfigurationSpec.groovy | 21 - .../stubrunner/util/ZipCategorySpec.groovy | 24 -- .../projects/brokers/brokers.json | 5 - .../brokers/nested/anotherDescriptor.json | 5 - .../projects/descriptor.json | 5 - .../src/test/resources/logback.xml | 14 - 747 files changed, 13363 insertions(+), 6399 deletions(-) create mode 100644 README.adoc delete mode 100644 README.md delete mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/ConversionAccurestException.groovy delete mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverter.groovy delete mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWireMockConverter.groovy delete mode 100644 accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy delete mode 100644 accurest-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy delete mode 100644 accurest-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy delete mode 100644 accurest-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy delete mode 100644 accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy delete mode 100644 accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy delete mode 100644 accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy delete mode 100644 accurest-converters/src/test/resources/converter/source/dslRoot.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/AccurestException.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy delete mode 100755 accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ClientDslProperty.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/DslProperty.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JSONCompareMode.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OptionalProperty.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ServerDslProperty.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/AccurestDslConverter.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBuffering.java delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/ShouldTraverse.java delete mode 100644 accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy delete mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy delete mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy delete mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/builder/BookReturned.groovy delete mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy delete mode 100644 accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/scenario/01_login.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/stubs/different/diff.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/stubs/other/different/diff.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/stubs/other/other.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/stubs/other/sample.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy delete mode 100644 accurest-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy delete mode 100644 accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy delete mode 100644 accurest-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy delete mode 100644 accurest-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy delete mode 100644 accurest-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy delete mode 100644 accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy delete mode 100644 accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateServerTestsTask.groovy delete mode 100644 accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy delete mode 100644 accurest-gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties delete mode 100644 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestGradlePluginTest.groovy delete mode 100755 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy delete mode 100755 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy delete mode 100755 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy delete mode 100755 accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties delete mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties delete mode 100755 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookDeleted.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookReturned.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/IntegrationMessagingApplication.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java delete mode 100644 accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle delete mode 100644 accurest-messaging/README.adoc delete mode 100644 accurest-messaging/accurest-messaging-camel/build.gradle delete mode 100644 accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelConfiguration.java delete mode 100644 accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java delete mode 100644 accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/CamelMessage.java delete mode 100644 accurest-messaging/accurest-messaging-core/build.gradle delete mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestFilter.java delete mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessage.java delete mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessageBuilder.java delete mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java delete mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestObjectMapper.java delete mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessage.java delete mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java delete mode 100644 accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java delete mode 100644 accurest-messaging/accurest-messaging-integration/build.gradle delete mode 100644 accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationConfiguration.java delete mode 100644 accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java delete mode 100644 accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java delete mode 100644 accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/IntegrationMessage.java delete mode 100644 accurest-messaging/accurest-messaging-integration/src/main/resources/META-INF/spring.factories delete mode 100644 accurest-messaging/accurest-messaging-stream/build.gradle delete mode 100644 accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamAutoConfiguration.java delete mode 100644 accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java delete mode 100644 accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java delete mode 100644 accurest-messaging/accurest-messaging-stream/src/main/resources/META-INF/spring.factories delete mode 100644 accurest-testing-utils/src/main/groovy/io/codearte/accurest/util/AssertionUtil.groovy create mode 100644 asciidoctor.css delete mode 100644 docs/src/docs/asciidoc/index.adoc delete mode 100644 docs/src/docs/asciidoc/messaging.adoc delete mode 100644 docs/src/docs/asciidoc/migration.adoc delete mode 100644 docs/src/docs/asciidoc/stubrunner_msg.adoc create mode 100644 docs/src/main/asciidoc/README.adoc rename docs/src/{docs => main}/asciidoc/contract.adoc (56%) rename docs/src/{docs => main}/asciidoc/images/Deps.png (100%) rename docs/src/{docs => main}/asciidoc/images/Stubs1.png (100%) rename docs/src/{docs => main}/asciidoc/images/Stubs2.png (100%) create mode 120000 docs/src/main/asciidoc/index.adoc rename docs/src/{docs => main}/asciidoc/introduction.adoc (77%) create mode 100644 docs/src/main/asciidoc/messaging.adoc rename docs/src/{docs => main}/asciidoc/rest.adoc (68%) create mode 100644 docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc rename docs/src/{docs => main}/asciidoc/stubrunner.adoc (55%) create mode 100644 docs/src/main/asciidoc/stubrunner_msg.adoc create mode 100755 docs/src/main/ruby/generate_readme.sh create mode 100755 generateReadme.sh delete mode 100644 gradle/releaseRoot.gradle rename docs.sh => publishDocs.sh (100%) delete mode 100644 samples/messaging-camel/build.gradle delete mode 100644 samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleted.groovy delete mode 100644 samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookReturned.groovy delete mode 100644 samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplication.groovy delete mode 100644 samples/messaging-integration/build.gradle delete mode 100644 samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy delete mode 100644 samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy delete mode 100644 samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplication.groovy delete mode 100644 samples/messaging-spring/build.gradle delete mode 100644 samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookDeleted.groovy delete mode 100644 samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookReturned.groovy delete mode 100644 samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/SpringMessagingApplication.groovy delete mode 100644 samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessageBuilder.groovy delete mode 100644 samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy delete mode 100644 samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/ManualAccurestConfiguration.groovy delete mode 100644 samples/messaging-stream/build.gradle delete mode 100644 samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy delete mode 100644 samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy delete mode 100644 samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/DeleteSink.groovy delete mode 100644 samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplication.groovy create mode 100644 samples/samples-messaging-camel/build.gradle create mode 100644 samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy rename samples/{messaging-camel/src/main/groovy/io/codearte/accurest => samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/camel/BookDeleter.groovy (56%) create mode 100644 samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy rename samples/{messaging-camel/src/main/groovy/io/codearte/accurest => samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/camel/BookRouteConfiguration.groovy (64%) rename samples/{messaging-camel/src/main/groovy/io/codearte/accurest => samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/camel/BookService.groovy (52%) create mode 100644 samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy rename samples/{messaging-camel/src/test/groovy/io/codearte/accurest => samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier}/samples/camel/CamelMessagingApplicationSpec.groovy (58%) create mode 100644 samples/samples-messaging-integration/build.gradle create mode 100644 samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy rename samples/{messaging-integration/src/main/groovy/io/codearte/accurest => samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/messaging/BookListener.groovy (66%) create mode 100644 samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy rename samples/{messaging-integration/src/main/groovy/io/codearte/accurest => samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/messaging/BookService.groovy (61%) create mode 100644 samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy rename samples/{messaging-integration => samples-messaging-integration}/src/main/resources/integration-context.xml (50%) rename samples/{messaging-integration/src/test/groovy/io/codearte/accurest => samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier}/samples/messaging/IntegrationMessagingApplicationSpec.groovy (61%) create mode 100644 samples/samples-messaging-spring/build.gradle create mode 100644 samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy rename samples/{messaging-spring/src/main/groovy/io/codearte/accurest => samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/spring/BookListener.groovy (75%) create mode 100644 samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy rename samples/{messaging-spring/src/main/groovy/io/codearte/accurest => samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/spring/BookService.groovy (63%) create mode 100644 samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy rename samples/{messaging-spring/src/test/groovy/io/codearte/accurest => samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier}/samples/spring/SpringApplicationSpec.groovy (56%) create mode 100644 samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy create mode 100644 samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy create mode 100644 samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy rename samples/{messaging-spring/src/test/groovy/io/codearte/accurest => samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier}/samples/spring/config/SpringMessage.groovy (55%) create mode 100644 samples/samples-messaging-stream/build.gradle create mode 100644 samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy rename samples/{messaging-stream/src/main/groovy/io/codearte/accurest => samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/messaging/BookListener.groovy (72%) create mode 100644 samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy rename samples/{messaging-stream/src/main/groovy/io/codearte/accurest => samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier}/samples/messaging/BookService.groovy (60%) create mode 100644 samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy create mode 100644 samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy rename samples/{messaging-stream => samples-messaging-stream}/src/main/resources/application.yml (100%) rename samples/{messaging-stream/src/test/groovy/io/codearte/accurest => samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier}/samples/messaging/StreamMessagingApplicationSpec.groovy (55%) rename {stub-runner/stub-runner-boot => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot}/README.adoc (66%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/build.gradle rename {stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract}/stubrunner/boot/HttpStubsController.groovy (55%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy rename {stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract}/stubrunner/boot/TriggerController.groovy (69%) rename {stub-runner/stub-runner-messaging/stub-runner-messaging-camel => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot}/src/main/resources/META-INF/spring.factories (60%) rename {stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract}/stubrunner/boot/StubRunnerBootSpec.groovy (62%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml rename {stub-runner/stub-runner-junit => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit}/README.adoc (59%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/build.gradle rename stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java (65%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml rename {stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier}/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar (100%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml rename {stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier}/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar (100%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml rename {stub-runner/stub-runner-messaging/stub-runner-messaging-camel => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel}/README.adoc (61%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy rename {stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract}/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy (57%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy rename {stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract}/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy (84%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml rename {stub-runner/stub-runner-messaging/stub-runner-messaging-integration => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration}/README.adoc (61%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle rename {stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract}/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy (64%) rename {stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract}/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy (57%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy rename {stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract}/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy (72%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml rename {stub-runner/stub-runner-messaging/stub-runner-messaging-integration => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration}/src/test/resources/integration-context.xml (50%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml rename {stub-runner/stub-runner-messaging/stub-runner-messaging-stream => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream}/README.adoc (64%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle rename {stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract}/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy (73%) rename {stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract}/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy (58%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy rename {stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract}/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy (72%) rename {stub-runner/stub-runner-messaging/stub-runner-messaging-stream => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream}/src/test/resources/application.yml (66%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml rename {stub-runner/stub-runner-spring-cloud => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud}/README.adoc (94%) rename {stub-runner/stub-runner-spring-cloud => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud}/build.gradle (55%) rename {stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/StubMapperProperties.java (66%) rename {stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java (71%) rename {stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/StubRunnerServiceInstance.java (57%) rename {stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java (64%) rename {stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java (53%) rename {stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java (67%) rename {stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java (56%) rename {stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java (70%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories rename {stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract}/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy (74%) rename {stub-runner/stub-runner-spring-cloud => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud}/src/test/resources/application.yml (56%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml rename {stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier}/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar (100%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml rename {stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier}/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar (100%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml rename {stub-runner/stub-runner-spring => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring}/README.adoc (80%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/build.gradle rename {stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract}/stubrunner/spring/StubRunnerConfiguration.java (60%) rename {accurest-messaging/accurest-messaging-camel => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring}/src/main/resources/META-INF/spring.factories (53%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml rename {stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier}/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar (100%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml rename {stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier}/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar (100%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml rename {stub-runner/stub-runner => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner}/README.adoc (84%) rename {stub-runner/stub-runner => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner}/build.gradle (75%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/AetherFactories.groovy (76%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/AetherStubDownloader.groovy (81%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/AvailablePortScanner.groovy (76%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/BatchStubRunner.groovy (76%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/RunningStubs.groovy (71%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubConfiguration.groovy (84%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubRepository.groovy (55%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubRunner.groovy (66%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerExecutor.groovy (58%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerFactory.groovy (57%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerMain.groovy (81%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerOptions.groovy (71%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerOptionsBuilder.groovy (80%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubServer.groovy (72%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/StubTrigger.groovy (54%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/util/StringUtils.groovy (85%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/util/StubsParser.groovy (69%) rename {stub-runner/stub-runner/src/main/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract}/stubrunner/util/ZipCategory.groovy (72%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/AvailablePortScannerSpec.groovy (71%) rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/BatchStubRunnerSpec.groovy (67%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/RunningStubsSpec.groovy (72%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/StubRepositorySpec.groovy (58%) rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerExecutorSpec.groovy (72%) rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerFactorySpec.groovy (59%) rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerOptionsBuilderSpec.groovy (65%) rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/StubRunnerSpec.groovy (63%) rename {stub-runner/stub-runner/src/test/groovy/io/codearte/accurest => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract}/stubrunner/StubServerSpec.groovy (62%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy rename {stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud}/bar/bar.json (100%) rename {stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud}/foo/bar/foobar.json (100%) rename {stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud}/foo/foo.json (100%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/emptyrepo}/.gitkeep (100%) rename {stub-runner/stub-runner => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner}/src/test/resources/file.zip (100%) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/logback.xml rename {stub-runner/stub-runner/src/test/resources/repository/mappings/lv/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/lv/spring/cloud}/bye/lv_bye.json (100%) rename {stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud}/bye/pl_bye.json (100%) rename {stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud}/bye/pl_overridden_bye.json (100%) rename {stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud}/bye/admin/admin.json (100%) rename {stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud}/bye/bye.json (100%) rename {stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud}/hello/README.md (100%) rename {stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud}/hello/admin/admin.json (100%) rename {stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud}/hello/hello.json (100%) rename {stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg => spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud}/ping/ping.json (100%) create mode 100644 spring-cloud-contract-verifier/build.gradle rename {accurest-converters => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters}/src/main/groovy/nl/flotsam/xeger/Xeger.java (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy rename {accurest-converters/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier}/wiremock/RecursiveFilesConverter.groovy (57%) rename {accurest-converters/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier}/wiremock/WireMockToDslConverter.groovy (83%) rename {accurest-converters => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters}/src/test/groovy/nl/flotsam/xeger/XegerTest.java (100%) rename {accurest-converters => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters}/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java (100%) rename {accurest-converters/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier}/wiremock/DslToWireMockClientConverterSpec.groovy (77%) rename {accurest-converters/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier}/wiremock/RecursiveFilesConverterSpec.groovy (78%) rename {accurest-converters/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier}/wiremock/WireMockToDslConverterSpec.groovy (78%) rename {accurest-converters/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier}/wiremock/WiremockScenarioConverterSpec.groovy (65%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/ContractVerifierException.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/FileSaver.groovy (50%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/TestGenerator.groovy (51%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/BlockBuilder.groovy (55%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/ClassBuilder.groovy (71%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/JUnitMessagingMethodBodyBuilder.groovy (68%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/JUnitMethodBodyBuilder.groovy (69%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/JaxRsClientJUnitMethodBodyBuilder.groovy (66%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy (69%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/MessagingMethodBodyBuilder.groovy (56%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/MethodBodyBuilder.groovy (52%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy (55%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/RequestProcessingMethodBodyBuilder.groovy (57%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder}/SingleTestGenerator.groovy (56%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/SpockMessagingMethodBodyBuilder.groovy (71%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/builder/SpockMethodRequestProcessingBodyBuilder.groovy (66%) rename accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy (59%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/config/TestFramework.groovy (66%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/Contract.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/Body.groovy (59%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ClientDslProperty.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/Common.groovy (83%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/DslProperty.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionProperty.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Header.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/Headers.groovy (54%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/Input.groovy (58%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/JSONCompareMode.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/MatchingStrategy.groovy (59%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/Multipart.groovy (66%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/NamedProperty.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OptionalProperty.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/OutputMessage.groovy (70%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/QueryParameter.groovy (50%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameters.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/RegexPatterns.groovy (69%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/Request.groovy (83%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/Response.groovy (67%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ServerDslProperty.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Url.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/UrlPath.groovy create mode 100755 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest/dsl => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock}/WireMockRequestStubStrategy.groovy (78%) rename {accurest-core/src/main/groovy/io/codearte/accurest/dsl => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock}/WireMockResponseStubStrategy.groovy (54%) rename {accurest-core/src/main/groovy/io/codearte/accurest/dsl => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock}/WireMockStubStrategy.groovy (60%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/file/ContractFileScanner.groovy (58%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy rename accurest-core/src/main/groovy/io/codearte/accurest/builder/BodyAsString.groovy => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy (51%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/util/ContentUtils.groovy (91%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/util/DelegatingJsonVerifiable.java (91%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/util/JsonToJsonPathsConverter.groovy (90%) rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/util/MapConverter.groovy (59%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java rename {accurest-core/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier}/util/MethodBufferingJsonVerifiable.java (56%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ValidateUtils.groovy rename {accurest-core => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core}/src/main/resources/stubs/wiremocks/other/sample.json (100%) rename {accurest-core => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core}/src/main/resources/stubs/wiremocks/sample.json (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier}/builder/ContractHttpDocsSpec.groovy (83%) rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier}/builder/JaxRsClientMethodBuilderSpec.groovy (64%) rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier}/builder/MessagingMethodBodyBuilderSpec.groovy (71%) rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier}/builder/MockMvcMethodBodyBuilderSpec.groovy (76%) rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder}/SingleTestGeneratorSpec.groovy (67%) rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier}/dsl/WireMockGroovyDslSpec.groovy (84%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier}/dsl/internal/RegexPatternsSpec.groovy (73%) rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier}/file/ContractFileScannerSpec.groovy (61%) rename {accurest-core/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier}/util/JsonToJsonPathsConverterSpec.groovy (96%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy rename {accurest-core => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core}/src/test/resources/directory/with/stubs/stubsRepositoryIndicator (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy rename {accurest-core => spring-cloud-contract-verifier/spring-cloud-contract-verifier-core}/src/test/resources/main.json (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties rename {accurest-gradle-plugin/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier}/plugin/BasicFunctionalSpec.groovy (64%) rename accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy (70%) create mode 100755 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy create mode 100755 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy create mode 100755 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy create mode 100755 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/bootSimple/build.gradle (88%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar (100%) create mode 100755 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/bootSimple/gradlew (100%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/bootSimple/gradlew.bat (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle rename {accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud}/twitter/place/PairIdController.groovy (56%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud}/twitter/place/Tweet.java (69%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/messagingProject/build.gradle (85%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar (100%) create mode 100755 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/messagingProject/gradlew (100%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/messagingProject/gradlew.bat (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy rename {accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud}/samples/book/BookListener.groovy (67%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy rename {accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud}/samples/book/BookService.groovy (61%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml (52%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud}/samples/book/MessagingBaseSpec.groovy (56%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud}/samples/book/MessagingBaseTest.java (62%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleJerseyProject/build.gradle (75%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/Application.java (92%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/FraudDetectionController.java (73%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/FraudRestApplication.java (83%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/model/FraudCheck.java (88%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/model/FraudCheckResult.java (92%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml (100%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud}/MvcSpec.groovy (65%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud}/MvcTest.java (91%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleJerseyProject/gradlew (100%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat (100%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject}/loanApplicationService/mappings/.gitkeep (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/LoanApplicationService.java (62%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/LoanApplicationResult.java (53%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml (100%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud}/LoanApplicationServiceSpec.groovy (58%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json (100%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleProject/build.gradle (75%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework}/frauddetection/Application.java (72%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework}/frauddetection/FraudDetectionController.java (76%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework}/frauddetection/model/FraudCheck.java (88%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework}/frauddetection/model/FraudCheckResult.java (92%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud}/MvcTest.java (63%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleProject/gradlew (100%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleProject/gradlew.bat (100%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject}/loanApplicationService/mappings/.gitkeep (100%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/Application.java (72%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/LoanApplicationService.java (79%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/Client.java (73%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/FraudServiceRequest.java (91%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/FraudServiceResponse.java (90%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/LoanApplication.java (91%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/LoanApplicationResult.java (93%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/LoanApplicationStatus.java (58%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml (100%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud}/LoanApplicationServiceSpec.groovy (58%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json (100%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/scenarioProject/build.gradle (76%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/Application.java (72%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/FraudDetectionController.java (76%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/model/FraudCheck.java (88%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud}/frauddetection/model/FraudCheckResult.java (92%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud}/MvcTest.java (63%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/scenarioProject/gradlew (100%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/scenarioProject/gradlew.bat (100%) rename {stub-runner/stub-runner/src/test/resources/emptyrepo => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings}/.gitkeep (100%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/Application.java (72%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/LoanApplicationService.java (79%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/Client.java (73%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/FraudServiceRequest.java (91%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/FraudServiceResponse.java (90%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/LoanApplication.java (91%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/LoanApplicationResult.java (93%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud}/frauddetection/model/LoanApplicationStatus.java (58%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml (100%) rename {accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud}/LoanApplicationServiceSpec.groovy (59%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json (100%) rename {accurest-gradle-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin}/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json (100%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/README.adoc create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java rename accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java => spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java (51%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java rename accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessagingUtil.java => spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java (60%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java rename accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java => spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java (60%) create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories create mode 100644 spring-cloud-contract-verifier/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy delete mode 100644 stub-runner/stub-runner-boot/build.gradle delete mode 100644 stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBoot.groovy delete mode 100644 stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerConfig.groovy delete mode 100644 stub-runner/stub-runner-boot/src/main/resources/META-INF/spring.factories delete mode 100644 stub-runner/stub-runner-boot/src/test/resources/application.yml delete mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar delete mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-junit/build.gradle delete mode 100644 stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java delete mode 100644 stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java delete mode 100644 stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/logback.xml delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/BookReturned.groovy delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/application.yml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/resources/META-INF/spring.factories delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/BookReturned.groovy delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/BookReturned.groovy delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml delete mode 100644 stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-spring/build.gradle delete mode 100644 stub-runner/stub-runner-spring/src/main/resources/META-INF/spring.factories delete mode 100644 stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/application.yml delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/logback.xml delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom delete mode 100644 stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/Arguments.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MessageNotMatchingException.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMessagingTrigger.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunning.groovy delete mode 100644 stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/WiremockMappingDescriptor.groovy delete mode 100644 stub-runner/stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml delete mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy delete mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubConfigurationSpec.groovy delete mode 100644 stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/util/ZipCategorySpec.groovy delete mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json delete mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json delete mode 100644 stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json delete mode 100644 stub-runner/stub-runner/src/test/resources/logback.xml diff --git a/.travis.yml b/.travis.yml index 599d7dc7f0..b63ed069cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,25 +4,9 @@ dist: trusty before_install: - "export JAVA_OPTS='-Xmx1024m -XX:MaxPermSize=256m'" - - "rm -rf $HOME/.m2/repository/io/codearte/accurest/stubs" - - "mkdir $HOME/.m2/repository/io/codearte/accurest/ --parents" - - "cp -r stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs $HOME/.m2/repository/io/codearte/accurest/" jdk: - oraclejdk8 install: ./gradlew assemble -s -script: ./gradlew check funcTest install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh && jdk_switcher use $TRAVIS_JDK_VERSION && ./gradlew uploadSnapshotArchives -x check -s - -matrix: - include: - # Automatic snapshot release only in Java 7 build - - jdk: oraclejdk7 - env: - - DO_RELEASE=true - -env: - global: - - secure: NbEQ9t5nGKW0LKmOSV4rTiEbYJARM2rynQBdSXkoILbp+nNaCD6uN41tUu8HrjgbjUDMepFUU+hmGQ47Q2vz5L3NzvW+oHBLgrIu6uAimpdR8qyBE899MBKPE19LsvUOeE9B9TydJgYlY+UEYgxwssUwxsN0RqyY4EErQWMNC8k= - - secure: zCjkMhjF5TbZehNmOK7EV68J35tuc0etWG/ia0eVTjgIv2kp9islJZ3+Jm/gDgkcv2Ydq3oAU2jFbVkUPSSstV3L5KANsighm2qn9tVzRrbTCfM55zcBhnoE0oZHTPNrLoScz0X5sM8Xuvi6ChjGf+lqAxnFW6tFMjx+1uhUIXU= - +script: ./gradlew check funcTest install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000000..98061ed476 --- /dev/null +++ b/README.adoc @@ -0,0 +1,190 @@ +// Do not edit this file (e.g. go instead to src/main/asciidoc) + +:core_path: ../../../.. +:verifier_root_path: {core_path}/spring-cloud-contract-verifier +:verifier_core_path: {verifier_root_path}/spring-cloud-contract-verifier-core +:stubrunner_core_path: {core_path}/spring-cloud-contract-stub-runner +:documentation_url: http://codearte.github.io/accurest + += Spring Cloud Contract Verifier + +== Introduction + +Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped +with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: + +* JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). +Test code must still be written by hand, test data is produced by Spring Cloud Contract Verifier. +* Messaging routes if you're using one. We're integrating with Spring Integration, Spring Cloud Stream and Apache Camel. You can however set your own integrations if you want to +* Acceptance tests (in JUnit or Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). +Full test is generated by Spring Cloud Contract Verifier. + +Spring Cloud Contract Verifier moves TDD to the level of software architecture. + +=== Why? + +Let us assume that we have a system comprising of multiple microservices: + +image::Deps.png[Microservices Architecture] + +==== Testing issues + +If we wanted to test the application in top left corner if it can communicate with other services then we could do one of two things: + +- deploy all microservices and perform end to end tests +- mock other microservices in unit / integration tests + +Both have their advantages but also a lot of disadvantages. Let's focus on the latter. + +*Deploy all microservices and perform end to end tests* + +Advantages: + +- simulates production +- tests real communication between services + +Disadvantages: + +- to test one microservice we would have to deploy 6 microservices, a couple of databases etc. +- the environment where the tests would be conducted would be locked for a single suite of tests (i.e. nobody else would be able to run the tests in the meantime). +- long to run +- very late feedback +- extremely hard to debug + +*Mock other microservices in unit / integration tests* + +Advantages: + +- very fast feedback +- no infrastructure requirements + +Disadvantages: + +- the implementor of the service creates stubs thus they might have nothing to do with the reality +- you can go to production with passing tests and failing production + +To solve the aforementioned issues Spring Cloud Contract Verifier with Stub Runner were created. Their main idea is to give you very fast feedback, without the need +to set up the whole world of microservices. + +image::Stubs1.png[Stubbed Services] + +If you work on stubs then the only applications you need are those that your application is using directly. + +image::Stubs2.png[Stubbed Services] + +Spring Cloud Contract Verifier gives you the certainty that the stubs that you're using were created by the service that you're calling. Also if you can use them it means that they were +tested against the producer's side. In other words - you can trust those stubs. + + +=== Purposes + +The main purposes of Spring Cloud Contract Verifier with Stub Runner are: + + - to ensure that WireMock / Messaging stubs (used when developing the client) are doing exactly what actual server-side implementation will do, + - to promote ATDD method and Microservices architectural style, + - to provide a way to publish changes in contracts that are immediately visible on both sides, + - to generate boilerplate test code used on the server side. + +=== Client Side + +During the tests you want to have a Wiremock instance / Messaging route 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 and 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 + +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. + +=== Dependencies + +Spring Cloud Contract Verifier and Stub Runner are using the following libraries + +- http://wiremock.org/[WireMock] +- https://github.com/jayway/JsonPath[Jayway JSONPath] +- https://github.com/marcingrzejszczak/jsonassert[JSONAssert from Marcin Grzejszczak] + +=== Additional links + +Below you can find some resources related to Spring Cloud Contract Verifier and Stub Runner. Note that some can be outdated since the Spring Cloud Contract Verifier project +is under constant development. + +==== Videos + +*Olga Maciaszek-Sharma talking about Accurest (Spring Cloud Contract Verifier predecessor)* + +video::daafmTYFoDU[youtube] + +*Marcin Grzejszczak and Jakub Kubryński talking about Accurest (Spring Cloud Contract Verifier predecessor)* + +video::130779882[vimeo] + +==== Readings + +- http://www.slideshare.net/MarcinGrzejszczak/stick-to-the-rules-consumer-driven-contracts-201507-confitura[Slides from Marcin Grzejszczak's talk about Accurest] +- http://toomuchcoding.com/blog/categories/accurest/[Accurest related articles from Marcin Grzejszczak's blog] + +=== Samples + +Here you can find some https://github.com/Codearte/accurest-samples[working samples]. Check the readme of each project for more information. + +== Documentation + +You can read more about Spring Cloud Contract Verifier by reading the {documentation_url}[docs] + +== Contributing + +Spring Cloud is released under the non-restrictive Apache 2.0 license, +and follows a very standard Github development process, using Github +tracker for issues and merging pull requests into master. If you want +to contribute even something trivial please do not hesitate, but +follow the guidelines below. + +=== Sign the Contributor License Agreement +Before we accept a non-trivial patch or pull request we will need you to sign the +https://support.springsource.com/spring_committer_signup[contributor's agreement]. +Signing the contributor's agreement does not grant anyone commit rights to the main +repository, but it does mean that we can accept your contributions, and you will get an +author credit if we do. Active contributors might be asked to join the core team, and +given the ability to merge pull requests. + +=== Code of Conduct +This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of +conduct]. By participating, you are expected to uphold this code. Please report +unacceptable behavior to spring-code-of-conduct@pivotal.io. + +=== Code Conventions and Housekeeping +None of these is essential for a pull request, but they will all help. They can also be +added after the original pull request but before a merge. + +* Use the Spring Framework code format conventions. If you use Eclipse + you can import formatter settings using the + `eclipse-code-formatter.xml` file from the + https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring + Cloud Build] project. If using IntelliJ, you can use the + http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter + Plugin] to import the same file. +* Make sure all new `.java` files to have a simple Javadoc class comment with at least an + `@author` tag identifying you, and preferably at least a paragraph on what the class is + for. +* Add the ASF license header comment to all new `.java` files (copy from existing files + in the project) +* Add yourself as an `@author` to the .java files that you modify substantially (more + than cosmetic changes). +* Add some Javadocs and, if you change the namespace, some XSD doc elements. +* A few unit tests would help a lot as well -- someone has to do it. +* If no-one else is using your branch, please rebase it against the current master (or + other target branch in the main project). +* When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions], + if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit + message (where XXXX is the issue number). \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index e74e3047a0..0000000000 --- a/README.md +++ /dev/null @@ -1,47 +0,0 @@ -Accurest -======== - -[![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) -[![Join the chat at https://gitter.im/Codearte/accurest](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Codearte/accurest?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) - -Consumer Driven Contracts verifier for Java - -To make a long story short - Accurest is a tool for Consumer Driven Contract (CDC) development. Accurest ships an easy DSL for describing REST contracts for JVM-based applications. - Since version 1.0.7 it also supports messaging. - -The contract DSL is used by Accurest for two things: - -1. generating WireMock's JSON stub definitions / stubbed messaging endpoints, allowing rapid development of the consumer side, -generating JUnit / Spock's acceptance tests for the server - to verify if your API implementation is compliant with the contract. -2. moving TDD to an architecture level. - -For more information please go to the [Documentation](http://codearte.github.io/accurest/) - -## Requirements - -### Wiremock - -In order to use Accurest with Wiremock you have to have __Wiremock in version at least 2.0.0-beta__ . Of course the higher the better :) - -## Additional projects - -### Stub Runner - -Allows you to download WireMock stubs from the provided Maven repository and runs them in WireMock servers. - -### Stub Runner JUnit - -Stub Runner with JUnit rules - -### Stub Runner Spring - -Spring Configuration that automatically starts stubs upon Spring Context build up - -### Stub Runner Spring Cloud - -Spring Cloud AutoConfiguration that automatically starts stubs upon Spring Context build up and allows you to call the stubs -as if they were registered in your service discovery - -### [Accurest Maven Plugin](https://github.com/Codearte/accurest-maven-plugin) - -Maven project support with standalone Accurest Stub Runner and Accurest Contracts to Wiremock mappings converter 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 deleted file mode 100644 index d4b35175a8..0000000000 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/ConversionAccurestException.groovy +++ /dev/null @@ -1,12 +0,0 @@ -package io.codearte.accurest.wiremock - -import groovy.transform.CompileStatic -import io.codearte.accurest.AccurestException - -@CompileStatic -class ConversionAccurestException extends AccurestException { - - ConversionAccurestException(String message, Throwable cause) { - super(message, cause) - } -} 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 deleted file mode 100644 index 616595e8bb..0000000000 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverter.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package io.codearte.accurest.wiremock - -import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.WireMockStubStrategy -import io.codearte.accurest.file.Contract - -import java.nio.charset.StandardCharsets - -@CompileStatic -class DslToWireMockClientConverter extends DslToWireMockConverter { - - @Override - String convertContent(String rootName, Contract contract) { - String dslContent = contract.path.getText(StandardCharsets.UTF_8.toString()) - return new WireMockStubStrategy(rootName, contract, createGroovyDSLfromStringContent(dslContent)).toWireMockClientStub() - } -} 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 deleted file mode 100644 index 0279bbcebe..0000000000 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/DslToWireMockConverter.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package io.codearte.accurest.wiremock - -import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.util.AccurestDslConverter - -@CompileStatic -abstract class DslToWireMockConverter implements SingleFileConverter { - - @Override - boolean canHandleFileName(String fileName) { - return fileName.endsWith('.groovy') - } - - @Override - String generateOutputFileNameForInput(String inputFileName) { - return inputFileName.replaceAll('.groovy', '.json') - } - - protected GroovyDsl createGroovyDSLfromStringContent(String groovyDslAsString) { - return AccurestDslConverter.convert(groovyDslAsString) - } -} diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy b/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy deleted file mode 100644 index fda8aa2e82..0000000000 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/SingleFileConverter.groovy +++ /dev/null @@ -1,14 +0,0 @@ -package io.codearte.accurest.wiremock - -import groovy.transform.CompileStatic -import io.codearte.accurest.file.Contract - -@CompileStatic -interface SingleFileConverter { - - boolean canHandleFileName(String fileName) - - String convertContent(String rootName, Contract content) - - String generateOutputFileNameForInput(String inputFileName) -} \ No newline at end of file diff --git a/accurest-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy b/accurest-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy deleted file mode 100644 index 1a30790fc3..0000000000 --- a/accurest-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy +++ /dev/null @@ -1,9 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('POST') - url '/login' - } - response { - status 200 - } -} diff --git a/accurest-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy b/accurest-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy deleted file mode 100644 index 712c7ef584..0000000000 --- a/accurest-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy +++ /dev/null @@ -1,9 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('GET') - url '/cart' - } - response { - status 200 - } -} diff --git a/accurest-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy b/accurest-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy deleted file mode 100644 index 33e948e602..0000000000 --- a/accurest-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy +++ /dev/null @@ -1,9 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('POST') - url '/logout' - } - response { - status 200 - } -} diff --git a/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy b/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy deleted file mode 100644 index d72463cde2..0000000000 --- a/accurest-converters/src/test/resources/converter/source/dir1/dsl1.groovy +++ /dev/null @@ -1,12 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } -} diff --git a/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy b/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy deleted file mode 100644 index d72463cde2..0000000000 --- a/accurest-converters/src/test/resources/converter/source/dir1/dsl1b.groovy +++ /dev/null @@ -1,12 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } -} diff --git a/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy b/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy deleted file mode 100644 index d72463cde2..0000000000 --- a/accurest-converters/src/test/resources/converter/source/dir2/dsl2.groovy +++ /dev/null @@ -1,12 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } -} diff --git a/accurest-converters/src/test/resources/converter/source/dslRoot.groovy b/accurest-converters/src/test/resources/converter/source/dslRoot.groovy deleted file mode 100644 index d72463cde2..0000000000 --- a/accurest-converters/src/test/resources/converter/source/dslRoot.groovy +++ /dev/null @@ -1,12 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - urlPattern $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/AccurestException.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/AccurestException.groovy deleted file mode 100644 index b9fac01145..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/AccurestException.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package io.codearte.accurest - -/** - * @author Jakub Kubrynski - */ -class AccurestException extends RuntimeException { - - AccurestException(String message) { - super(message) - } - - AccurestException(String message, Throwable cause) { - super(message, cause) - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy deleted file mode 100644 index 71c76b7f86..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBuilder.groovy +++ /dev/null @@ -1,65 +0,0 @@ -package io.codearte.accurest.builder - -import groovy.util.logging.Slf4j -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 io.codearte.accurest.util.NamesUtil -/** - * @author Jakub Kubrynski - */ -@Slf4j -class MethodBuilder { - - private final String methodName - private final GroovyDsl stubContent - private final AccurestConfigProperties configProperties - private final boolean ignored - - private MethodBuilder(String methodName, GroovyDsl stubContent, AccurestConfigProperties configProperties, boolean ignored) { - this.ignored = ignored - this.stubContent = stubContent - this.methodName = methodName - this.configProperties = configProperties - } - - 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) - } - - void appendTo(BlockBuilder blockBuilder) { - if (configProperties.targetFramework == TestFramework.JUNIT) { - blockBuilder.addLine('@Test') - } - if (ignored) { - blockBuilder.addLine('@Ignore') - } - blockBuilder.addLine(configProperties.targetFramework.methodModifier + "validate_$methodName() throws Exception {") - getMethodBodyBuilder().appendTo(blockBuilder) - blockBuilder.addLine('}') - } - - private MethodBodyBuilder getMethodBodyBuilder() { - if (stubContent.input || 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) - } - if (configProperties.testMode == TestMode.JAXRSCLIENT) { - if (configProperties.targetFramework == TestFramework.JUNIT){ - return new JaxRsClientJUnitMethodBodyBuilder(stubContent) - } - return new JaxRsClientSpockMethodRequestProcessingBodyBuilder(stubContent) - } - return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent) - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy deleted file mode 100644 index d3bd3acbe7..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcJUnitMethodBodyBuilder.groovy +++ /dev/null @@ -1,46 +0,0 @@ -package io.codearte.accurest.builder - -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.dsl.internal.ExecutionProperty -import io.codearte.accurest.dsl.internal.Header - -import java.util.regex.Pattern - -/** - * @author Olga Maciaszek-Sharma - * @since 2016-02-17 - */ -class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { - - MockMvcJUnitMethodBodyBuilder(GroovyDsl stubDefinition) { - super(stubDefinition) - } - - @Override - protected void validateResponseCodeBlock(BlockBuilder bb) { - bb.addLine("assertThat(response.statusCode()).isEqualTo($response.status.serverValue);") - } - - @Override - protected void validateResponseHeadersBlock(BlockBuilder bb) { - response.headers?.collect { Header header ->\ - processHeaderElement(bb, header.name, header.serverValue) - } - } - - @Override - protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) { - blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(value)}") - } - - @Override - protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) { - blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(pattern)}") - } - - @Override - protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { - blockBuilder.addLine("${exec.insertValue("response.header(\"$property\")")};") - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy deleted file mode 100644 index 5d1f339bc8..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestMode.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package io.codearte.accurest.config - -/** - * @author Jakub Kubrynski - */ -enum TestMode { - /** - * Uses Spring's MockMvc - */ - MOCKMVC, - - /** - * Uses direct HTTP invocations - */ - EXPLICIT, - - /** - * Uses JAX-RS client - */ - JAXRSCLIENT -} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy deleted file mode 100644 index ee5c0392c7..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/Accurest.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package io.codearte.accurest.dsl - -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString -import groovy.transform.TypeChecked -/** - * A better name for GroovyDsl - * - * @author Marcin Grzejszczak - */ -@TypeChecked -@EqualsAndHashCode -@ToString(includeFields = true, includePackage = false, includeNames = true, includeSuper = true) -class Accurest extends GroovyDsl { -} 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 deleted file mode 100755 index ac7376dc38..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/BaseWireMockStubStrategy.groovy +++ /dev/null @@ -1,109 +0,0 @@ -package io.codearte.accurest.dsl - -import groovy.json.JsonBuilder -import groovy.transform.TypeChecked -import io.codearte.accurest.dsl.internal.DslProperty -import io.codearte.accurest.dsl.internal.Header -import io.codearte.accurest.dsl.internal.Headers -import io.codearte.accurest.util.ContentType -import io.codearte.accurest.util.ContentUtils -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.MapConverter.transformValues - -@TypeChecked -abstract class BaseWireMockStubStrategy { - - protected getStubSideValue(Object object) { - return MapConverter.getStubSideValues(object) - } - - private static Closure transform = { - it instanceof DslProperty ? transformValues(it.clientValue, transform) : it - } - - 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()]] - } - - public String parseBody(Object value, ContentType contentType) { - return parseBody(value.toString(), contentType) - } - - public Boolean parseBody(Boolean value, ContentType contentType) { - return value - } - - public String parseBody(Map map, ContentType contentType) { - def transformedMap = MapConverter.getStubSideValues(map) - return parseBody(toJson(transformedMap), contentType) - } - - public String parseBody(List list, ContentType contentType) { - List result = [] - list.each { - if (it instanceof Map) { - result += MapConverter.getStubSideValues(it) - } else { - result += parseBody(it, contentType) - } - } - return parseBody(toJson(result), contentType) - } - - public String parseBody(GString value, ContentType contentType) { - Object processedValue = extractValue(value, contentType, { DslProperty dslProperty -> dslProperty.clientValue }) - if (processedValue instanceof GString) { - return parseBody(processedValue.toString(), contentType) - } - return parseBody(processedValue, contentType) - } - - public String parseBody(String value, ContentType contentType) { - return value - } - - private static toJson(Object value) { - return new JsonBuilder(value).toString() - } - - protected ContentType tryToGetContentType(Object body, Headers headers) { - ContentType contentType = ContentUtils.recognizeContentTypeFromHeader(headers) - if (contentType == ContentType.UNKNOWN) { - if (!body) { - return ContentType.UNKNOWN - } - return ContentUtils.getClientContentType(body) - } - return contentType - } -} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy deleted file mode 100644 index 3cd0e993ed..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/GroovyDsl.groovy +++ /dev/null @@ -1,67 +0,0 @@ -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 - -@TypeChecked -@EqualsAndHashCode -@ToString(includeFields = true, includePackage = false, includeNames = true) -class GroovyDsl { - - Integer priority - Request request - Response response - String label - String description - Input input - OutputMessage outputMessage - - static GroovyDsl make(Closure closure) { - GroovyDsl dsl = new GroovyDsl() - closure.delegate = dsl - closure() - return dsl - } - - void priority(int priority) { - this.priority = priority - } - - void label(String label) { - this.label = label - } - - void description(String description) { - this.description = description - } - - void request(@DelegatesTo(Request) Closure closure) { - this.request = new Request() - closure.delegate = request - closure() - } - - void response(@DelegatesTo(Response) Closure closure) { - this.response = new Response() - closure.delegate = response - closure() - } - - void input(@DelegatesTo(Input) Closure closure) { - this.input = new Input() - closure.delegate = input - closure() - } - - void outputMessage(@DelegatesTo(OutputMessage) Closure closure) { - this.outputMessage = new OutputMessage() - closure.delegate = outputMessage - closure() - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ClientDslProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ClientDslProperty.groovy deleted file mode 100644 index 007550b890..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ClientDslProperty.groovy +++ /dev/null @@ -1,11 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.CompileStatic - -@CompileStatic -class ClientDslProperty extends DslProperty { - - ClientDslProperty(Object singleValue) { - super(singleValue) - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/DslProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/DslProperty.groovy deleted file mode 100644 index f9da9227e5..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/DslProperty.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString - -@CompileStatic -@EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false, includeNames = true) -class DslProperty { - - final T clientValue - final T serverValue - - DslProperty(T clientValue, T serverValue) { - this.clientValue = clientValue - this.serverValue = serverValue - } - - DslProperty(T singleValue) { - this.clientValue = singleValue - this.serverValue = singleValue - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy deleted file mode 100644 index 866afdc18c..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ExecutionProperty.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.CompileStatic - -@CompileStatic -class ExecutionProperty { - - private static final String PLACEHOLDER_VALUE = '\\$it' - - final String executionCommand - - ExecutionProperty(String executionCommand) { - this.executionCommand = executionCommand - } - - String insertValue(String valueToInsert) { - return executionCommand.replaceAll(PLACEHOLDER_VALUE, valueToInsert) - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy deleted file mode 100644 index b72037cd03..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Header.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package io.codearte.accurest.dsl.internal -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString - -@EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) -@CompileStatic -class Header extends DslProperty { - - String name - - Header(String name, DslProperty dslProperty) { - super(dslProperty.clientValue, dslProperty.serverValue) - this.name = name - } - - Header(String name, Object value) { - super(value) - this.name = name - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JSONCompareMode.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JSONCompareMode.groovy deleted file mode 100644 index 8929aa9bdc..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JSONCompareMode.groovy +++ /dev/null @@ -1,5 +0,0 @@ -package io.codearte.accurest.dsl.internal - -enum JSONCompareMode { - STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER -} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy deleted file mode 100644 index b6b6f79eee..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/JsonStructureConverter.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.json.JsonOutput -import groovy.transform.CompileStatic -import io.codearte.accurest.util.MapConverter - -import java.util.regex.Pattern - -@CompileStatic -class JsonStructureConverter { - - public static final String TEMPORARY_PLACEHOLDER = '###PLACEHOLDER###' - public static final Pattern TEMPORARY_PATTERN_HOLDER = Pattern.compile(TEMPORARY_PLACEHOLDER) - - static Object convertJsonStructureToObjectUnderstandingStructure(Object parsedJson, - Closure retrievePlaceholders, - Closure performAdditionalLogicOnSerializedJson, - Closure convertSerializedJsonToSth) { - LinkedList queue = new LinkedList<>() - def transformedJson = MapConverter.transformValues(parsedJson, { - if(retrievePlaceholders(it)) { - queue.push(it) - return TEMPORARY_PLACEHOLDER - } - return it - }) - String jsonAsString = JsonOutput.toJson(transformedJson) - String transformedJsonAsString = performAdditionalLogicOnSerializedJson(jsonAsString) - return convertSerializedJsonToSth(queue, transformedJsonAsString) - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy deleted file mode 100644 index 70c6d30879..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/NamedProperty.groovy +++ /dev/null @@ -1,25 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString - -@ToString(includePackage = false, includeFields = true, includeNames = true) -@EqualsAndHashCode(includeFields = true) -@CompileStatic -class NamedProperty { - - private static final String NAME = 'name' - private static final String CONTENT = 'content' - DslProperty name - DslProperty value - - NamedProperty(DslProperty name, DslProperty value) { - this.name = name - this.value = value - } - - NamedProperty(Map namedMap) { - this(namedMap?.get(NAME), namedMap?.get(CONTENT)) - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OptionalProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OptionalProperty.groovy deleted file mode 100644 index 877c31c661..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OptionalProperty.groovy +++ /dev/null @@ -1,13 +0,0 @@ -package io.codearte.accurest.dsl.internal - -class OptionalProperty { - final Object value - - OptionalProperty(Object value) { - this.value = value - } - - String optionalPattern() { - return "($value)?" - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy deleted file mode 100644 index b4cc1d74c4..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameters.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString -import groovy.transform.TypeChecked - -@EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) -@TypeChecked -class QueryParameters { - - List parameters = [] - - void parameter(Map singleParameter) { - Map.Entry first = singleParameter.entrySet().first() - parameters << new QueryParameter(first?.key, first?.value) - } - - void parameter(String parameterName, Object parameterValue) { - parameters << new QueryParameter(parameterName, parameterValue) - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ServerDslProperty.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ServerDslProperty.groovy deleted file mode 100644 index 659fba901e..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/ServerDslProperty.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString - -@CompileStatic -@EqualsAndHashCode(includeFields = true) -@ToString(includePackage = false) -class ServerDslProperty extends DslProperty { - - ServerDslProperty(Object singleValue) { - super(singleValue) - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy deleted file mode 100644 index 09eae6d094..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Url.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString - -import static io.codearte.accurest.util.ValidateUtils.validateServerValueIsAvailable - -@ToString(includePackage = false, includeFields = true, includeNames = true) -@EqualsAndHashCode(includeFields = true) -@CompileStatic -class Url extends DslProperty { - - QueryParameters queryParameters - - Url(DslProperty prop) { - super(prop.clientValue, prop.serverValue) - validateServerValueIsAvailable(prop.serverValue, "Url") - } - - Url(Object url) { - super(url) - validateServerValueIsAvailable(url, "Url") - } - - void queryParameters(@DelegatesTo(QueryParameters) Closure closure) { - this.queryParameters = new QueryParameters() - closure.delegate = queryParameters - closure() - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy deleted file mode 100644 index 4b77520cc3..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/UrlPath.groovy +++ /dev/null @@ -1,20 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode -import groovy.transform.ToString - -@ToString(includePackage = false, includeFields = true, includeNames = true) -@EqualsAndHashCode(includeFields = true) -@CompileStatic -class UrlPath extends Url { - - UrlPath(String path) { - super(path) - } - - UrlPath(DslProperty path) { - super(path) - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy deleted file mode 100644 index d5cbcfea1c..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/file/Contract.groovy +++ /dev/null @@ -1,30 +0,0 @@ -package io.codearte.accurest.file - -import java.nio.file.Path - -/** - * @author Jakub Kubrynski - */ -class Contract { - final Path path; - final boolean ignored; - final int groupSize - final Integer order; - - Contract(Path path, boolean ignored, int groupSize, Integer order) { - this.groupSize = groupSize - this.path = path - this.ignored = ignored - this.order = order - } - - @Override - public String toString() { - return "Contract{" + - "fileName=" + path.fileName + - ", ignored=" + ignored + - ", groupSize=" + groupSize + - ", order=" + order + - '}'; - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/AccurestDslConverter.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/AccurestDslConverter.groovy deleted file mode 100644 index 5f865ba24b..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/AccurestDslConverter.groovy +++ /dev/null @@ -1,26 +0,0 @@ -package io.codearte.accurest.util - -import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.GroovyDsl -import org.codehaus.groovy.control.CompilerConfiguration - -/** - * Converts to Groovy DSL - * - * @author Marcin Grzejszczak - */ -@CompileStatic -class AccurestDslConverter { - - static GroovyDsl convert(String dsl) { - return groovyShell().evaluate(dsl) as GroovyDsl - } - - static GroovyDsl convert(File dsl) { - return groovyShell().evaluate(dsl) as GroovyDsl - } - - private static GroovyShell groovyShell() { - return new GroovyShell(AccurestDslConverter.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding: 'UTF-8')) - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy deleted file mode 100644 index a9243058af..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentType.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package io.codearte.accurest.util - -enum ContentType { - - JSON("application/json"), - XML("application/xml"), - UNKNOWN("application/octet-stream") - - final String mimeType - - ContentType(String mimeType) { - this.mimeType = mimeType - } - -} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java deleted file mode 100644 index 8b89f4ea4b..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/FinishedDelegatingJsonVerifiable.java +++ /dev/null @@ -1,17 +0,0 @@ -package io.codearte.accurest.util; - -import java.util.LinkedList; - -import com.toomuchcoding.jsonassert.JsonVerifiable; - -/** - * @author Marcin Grzejszczak - */ -class FinishedDelegatingJsonVerifiable extends DelegatingJsonVerifiable { - - FinishedDelegatingJsonVerifiable(JsonVerifiable delegate, - LinkedList methodsBuffer) { - super(delegate, methodsBuffer); - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy deleted file mode 100644 index d3786b757e..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonPaths.groovy +++ /dev/null @@ -1,6 +0,0 @@ -package io.codearte.accurest.util - -class JsonPaths extends HashSet { - -} - diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBuffering.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBuffering.java deleted file mode 100644 index 606ae4518e..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBuffering.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.codearte.accurest.util; - -/** - * @author Marcin Grzejszczak - */ -public interface MethodBuffering { - - String method(); -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy deleted file mode 100644 index 8e4d9037ee..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/NamesUtil.groovy +++ /dev/null @@ -1,60 +0,0 @@ -package io.codearte.accurest.util - -/** - * @author Jakub Kubrynski - */ -class NamesUtil { - - static String beforeLast(String string, String separator) { - if (string?.indexOf(separator) > -1) { - return string.substring(0, string.lastIndexOf(separator)) - } - return '' - } - - static String afterLast(String string, String separator) { - if (string?.indexOf(separator) > -1) { - return string.substring(string.lastIndexOf(separator) + 1) - } - return string - } - - static String afterLastDot(String string) { - return afterLast(string, '.') - } - - static String camelCase(String className) { - if (!className) { - return className - } - String firstChar = className.charAt(0).toLowerCase() as String - return firstChar + className.substring(1) - } - - static String capitalize(String className) { - if (!className) { - return className - } - String firstChar = className.charAt(0).toUpperCase() as String - return firstChar + className.substring(1) - } - - static String toLastDot(String string) { - if (string?.indexOf('.') > -1) { - return string.substring(0, string.lastIndexOf('.')) - } - return string - } - - static String packageToDirectory(String packageName) { - return packageName.replace('.' as char, File.separatorChar) - } - - static String directoryToPackage(String directory) { - return directory.replace(File.separator, '.') - } - - static String convertIllegalPackageChars(String packageName) { - return packageName.replace('-', '_') - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy deleted file mode 100644 index 6c8b703fca..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/RegexpBuilders.groovy +++ /dev/null @@ -1,91 +0,0 @@ -package io.codearte.accurest.util - -import io.codearte.accurest.dsl.internal.DslProperty -import org.codehaus.groovy.runtime.GStringImpl - -import java.util.regex.Pattern - -import static io.codearte.accurest.util.ContentUtils.extractValue -import static org.apache.commons.lang3.StringEscapeUtils.escapeJson - -public class RegexpBuilders { - - public static String buildGStringRegexpForStubSide(GString gString) { - new GStringImpl( - gString.values.collect(this.&buildGStringRegexpForStubSide) as Object[], - gString.strings.collect(this.&escapeSpecialRegexChars) as String[] - ) - } - - public static String buildGStringRegexpForStubSide(Pattern pattern) { - return pattern.pattern() - } - - public static String buildGStringRegexpForStubSide(DslProperty dslProperty) { - return buildGStringRegexpForStubSide(dslProperty.clientValue) - } - - public static String buildGStringRegexpForStubSide(Object o) { - return escapeSpecialRegexChars(o.toString()) - } - - public static String buildGStringRegexpForTestSide(GString gString) { - new GStringImpl( - gString.values.collect(this.&buildGStringRegexpForTestSide) as Object[], - gString.strings.collect(this.&escapeSpecialRegexChars) as String[] - ) - } - - public static String buildGStringRegexpForTestSide(Pattern pattern) { - return pattern.pattern() - } - - public static String buildGStringRegexpForTestSide(DslProperty dslProperty) { - return buildGStringRegexpForTestSide(dslProperty.clientValue) - } - - public static String buildGStringRegexpForTestSide(Object o) { - return o.toString().replaceAll('\\\\', '\\\\\\\\') - } - - private final static Pattern SPECIAL_REGEX_CHARS = Pattern.compile('[{}()\\[\\].+*?^$\\\\|]') - - private static String escapeSpecialRegexChars(String str) { - return SPECIAL_REGEX_CHARS.matcher(str).replaceAll('\\\\\\\\$0') - } - - private final static String WS = /\s*/ - - public static String buildJSONRegexpMatch(GString gString) { - return buildJSONRegexpMatch(extractValue(gString, ContentType.JSON, { DslProperty dslProperty -> dslProperty.clientValue })) - } - - public static String buildJSONRegexpMatch(Map jsonMap) { - return WS + "\\{" + jsonMap.collect(this.&buildJSONRegexpMatch).join(",") + "\\}" + WS - } - - public static String buildJSONRegexpMatch(List jsonList) { - return WS + "\\[" + jsonList.collect(this.&buildJSONRegexpMatch).join(",") + "\\]" + WS - } - - public static String buildJSONRegexpMatch(Map.Entry entry) { - return buildJSONRegexpMatchString(escapeJson(entry.key)) + ":" + buildJSONRegexpMatch(entry.value) - } - - public static String buildJSONRegexpMatch(Object value) { - return buildJSONRegexpMatchStringOptionalQuotes(escapeJson(value.toString())) - } - - public static String buildJSONRegexpMatch(Pattern pattern) { - return buildJSONRegexpMatchStringOptionalQuotes(pattern.pattern()) - } - - public static String buildJSONRegexpMatchString(String value) { - return WS + '"' + value + '"' + WS - } - - public static String buildJSONRegexpMatchStringOptionalQuotes(String value) { - return WS + '"?' + value + '"?' + WS - } - -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ShouldTraverse.java b/accurest-core/src/main/groovy/io/codearte/accurest/util/ShouldTraverse.java deleted file mode 100644 index a4590e504e..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ShouldTraverse.java +++ /dev/null @@ -1,12 +0,0 @@ -package io.codearte.accurest.util; - -/** - * @author Marcin Grzejszczak - */ -class ShouldTraverse { - final Object value; - - ShouldTraverse(Object value) { - this.value = value; - } -} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy b/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy deleted file mode 100644 index 46e9706cfe..0000000000 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ValidateUtils.groovy +++ /dev/null @@ -1,46 +0,0 @@ -package io.codearte.accurest.util - -import groovy.transform.TypeChecked -import io.codearte.accurest.dsl.internal.DslProperty -import io.codearte.accurest.dsl.internal.MatchingStrategy - -import java.util.regex.Pattern - -import static io.codearte.accurest.dsl.internal.MatchingStrategy.Type.ABSENT -import static io.codearte.accurest.dsl.internal.MatchingStrategy.Type.EQUAL_TO - -@TypeChecked -class ValidateUtils { - - static Object validateServerValueIsAvailable(Object value) { - validateServerValueIsAvailable(value, "Server value") - return value - } - - static Object validateServerValueIsAvailable(Object value, String msg) { - validateServerValue(value, msg) - return value - } - - static void validateServerValue(Pattern pattern, String msg) { - throw new IllegalStateException("$msg can't be a pattern for the server side") - } - - static List ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE = [EQUAL_TO, ABSENT] - - static void validateServerValue(MatchingStrategy matchingStrategy, String msg) { - if (!ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE.contains(matchingStrategy.type)) { - throw new IllegalStateException("$msg can't be of a matching type: $matchingStrategy.type for the server side") - } - validateServerValue(matchingStrategy.serverValue, msg) - } - - static void validateServerValue(DslProperty value, String msg) { - validateServerValue(value.serverValue, msg) - } - - static void validateServerValue(Object value, String msg) { - // OK - } - -} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy deleted file mode 100644 index 77e2804805..0000000000 --- a/accurest-core/src/test/groovy/io/codearte/accurest/GeneratorScannerSpec.groovy +++ /dev/null @@ -1,36 +0,0 @@ -package io.codearte.accurest - -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.config.TestFramework -import spock.lang.Specification - -class GeneratorScannerSpec extends Specification { - - private SingleTestGenerator classGenerator = Mock(SingleTestGenerator) - - def "should find all .json files and generate 6 classes for them"() { - given: - File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) - AccurestConfigProperties properties = new AccurestConfigProperties() - properties.contractsDslDir = resource.parentFile - TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) - when: - testGenerator.generateTestClasses("com.ofg") - then: - 6 * classGenerator.buildClass(_, _, _) >> "qwerty" - } - - def "should create class with full package"() { - given: - AccurestConfigProperties properties = new AccurestConfigProperties(targetFramework: TestFramework.SPOCK) - properties.contractsDslDir = new File(this.getClass().getResource("/directory/with/stubs/package").toURI()) - TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) - when: - testGenerator.generateTestClasses("com.ofg") - then: - 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg') >> "spec" - 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v1') >> "spec1" - 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'com.ofg.v2') >> "spec2" - } - -} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy deleted file mode 100644 index dd0ab8cf10..0000000000 --- a/accurest-core/src/test/groovy/io/codearte/accurest/MainTest.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package io.codearte.accurest - -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) { - AccurestConfigProperties properties = new AccurestConfigProperties( - contractsDslDir: new File('/home/devel/projects/codearte/accurest/accurest-core/src/test/resources/dsl'), - generatedTestSourcesDir: new File('/tmp/accurest'), - targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', - staticImports: ['com.pupablada.Test.*'], imports: ['org.innapypa.Test'], excludedFiles: ["**/other"]) - println new TestGenerator(properties).generate() - } -} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/BookReturned.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/builder/BookReturned.groovy deleted file mode 100644 index 9c2656d426..0000000000 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/BookReturned.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy deleted file mode 100644 index bb4ec0e18d..0000000000 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockStubVerifier.groovy +++ /dev/null @@ -1,22 +0,0 @@ -package io.codearte.accurest.dsl - -import com.github.tomakehurst.wiremock.stubbing.StubMapping -import io.codearte.accurest.file.Contract - -import java.util.regex.Pattern - -trait WireMockStubVerifier { - - void stubMappingIsValidWireMockStub(String mappingDefinition) { - StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) - stubMapping.request.bodyPatterns.findAll { it.matches }.every { - Pattern.compile(it.matches) - } - assert !mappingDefinition.contains('io.codearte.accurest.dsl.internal') - } - - void stubMappingIsValidWireMockStub(GroovyDsl contractDsl) { - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) - } - -} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy b/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy deleted file mode 100644 index 35e0fbe83a..0000000000 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/ExecutionPropertySpec.groovy +++ /dev/null @@ -1,19 +0,0 @@ -package io.codearte.accurest.dsl.internal - -import spock.lang.Specification - -class ExecutionPropertySpec extends Specification { - - def 'should insert passed value in place of $it placeholder'() { - given: - String commandToExecute = 'commandToExecute($it)' - ExecutionProperty executionProperty = new ExecutionProperty(commandToExecute) - and: - String valueToInsert = 'someObject.itsValue' - when: - String commandWithInsertedValue = executionProperty.insertValue(valueToInsert) - then: - 'commandToExecute(someObject.itsValue)' == commandWithInsertedValue - } - -} diff --git a/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy b/accurest-core/src/test/resources/directory/with/scenario/01_login.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy b/accurest-core/src/test/resources/directory/with/scenario/02_showCart.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy b/accurest-core/src/test/resources/directory/with/scenario/03_logout.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/stubs/different/diff.groovy b/accurest-core/src/test/resources/directory/with/stubs/different/diff.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/different/diff.groovy b/accurest-core/src/test/resources/directory/with/stubs/other/different/diff.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/other.groovy b/accurest-core/src/test/resources/directory/with/stubs/other/other.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/stubs/other/sample.groovy b/accurest-core/src/test/resources/directory/with/stubs/other/sample.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy b/accurest-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy b/accurest-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy b/accurest-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy b/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy deleted file mode 100644 index 4405a9920e..0000000000 --- a/accurest-core/src/test/resources/dsl/basic/sampleDsl.groovy +++ /dev/null @@ -1,30 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method('PUT') - headers { - header 'Content-Type': 'application/json' - } - body("""\ - { - "name": "Jan", - "id": "${value(client('abc'), server('def'))}", - } - """ - ) - url $(client('/[0-9]{2}'), server('/12')) - } - response { - status 200 - body("""\ - { - "name": "Jan", - "id": "${value(client('123'), server('321'))}", - "surname": "${value(client('Kowalsky'), server('$checkIfSurnameValid($value)'))}" - } - """ - ) - headers { - header 'Content-Type': 'text/plain' - } - } -} diff --git a/accurest-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy b/accurest-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy b/accurest-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/accurest-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy b/accurest-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy deleted file mode 100644 index e69de29bb2..0000000000 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 deleted file mode 100644 index 658f63bb30..0000000000 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/AccurestGradlePlugin.groovy +++ /dev/null @@ -1,89 +0,0 @@ -package io.codearte.accurest.plugin - -import io.codearte.accurest.config.AccurestConfigProperties -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.Task -/** - * @author Jakub Kubrynski - */ -class AccurestGradlePlugin implements Plugin { - - private static final String GENERATE_SERVER_TESTS_TASK_NAME = 'generateAccurest' - private static final String DSL_TO_WIREMOCK_CLIENT_TASK_NAME = 'generateWireMockClientStubs' - - private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin - private static final String GROUP_NAME = "Verification" - - private Project project - - @Override - void apply(Project project) { - this.project = project - AccurestConfigProperties extension = project.extensions.create('accurest', AccurestConfigProperties) - - project.check.dependsOn(GENERATE_SERVER_TESTS_TASK_NAME) - - setConfigurationDefaults(extension) - createGenerateTestsTask(extension) - createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) - deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() - project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.10-beta") - project.dependencies.add("testCompile", "com.toomuchcoding.jsonassert:jsonassert:${extension.getJsonAssertVersion()}") - project.dependencies.add("testCompile", "org.assertj:assertj-core:2.3.0") - - project.afterEvaluate { - def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) - if (hasIdea) { - project.idea { - module { - testSourceDirs += extension.generatedTestSourcesDir - testSourceDirs += extension.contractsDslDir - } - } - } - } - } - - void setConfigurationDefaults(AccurestConfigProperties extension) { - extension.with { - generatedTestSourcesDir = project.file("${project.buildDir}/generated-test-sources/accurest") - contractsDslDir = defaultAccurestContractsDir() //TODO: Use sourceset - basePackageForTests = 'io.codearte.accurest.tests' - } - } - - private File defaultAccurestContractsDir() { - project.file("${project.rootDir}/src/test/resources/accurest") - } - - private void createGenerateTestsTask(AccurestConfigProperties extension) { - Task task = project.tasks.create(GENERATE_SERVER_TESTS_TASK_NAME, GenerateServerTestsTask) - task.description = "Generate server tests from GroovyDSL" - task.group = GROUP_NAME - task.conventionMapping.with { - contractsDslDir = { extension.contractsDslDir } - generatedTestSourcesDir = { extension.generatedTestSourcesDir } - configProperties = { extension } - } - } - - private void createAndConfigureGenerateWireMockClientStubsFromDslTask(AccurestConfigProperties extension) { - Task task = project.tasks.create(DSL_TO_WIREMOCK_CLIENT_TASK_NAME, GenerateWireMockClientStubsFromDslTask) - task.description = "Generate WireMock client stubs from GroovyDSL" - task.group = GROUP_NAME - task.conventionMapping.with { - contractsDslDir = { extension.contractsDslDir } - stubsOutputDir = { extension.stubsOutputDir } - configProperties = { extension } - } - } - - private void deprecatedCreateAndConfigureGenerateWiremockClientStubsFromDslTask() { - Task task = project.tasks.create('generateWiremockClientStubs') - task.dependsOn('generateWireMockClientStubs') - task.description = "DEPRECATED - Generates WireMock client stubs. - DEPRECATED - use 'generateWireMockClientStubs' task" - task.group = GROUP_NAME - task.doFirst {logger.warn("DEPRECATION WARNING. Task 'generateWiremockClientStubs' is deprecated. Use 'generateWireMockClientStubs' task instead.")} - } -} 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 deleted file mode 100644 index d6fe06a9fd..0000000000 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateServerTestsTask.groovy +++ /dev/null @@ -1,40 +0,0 @@ -package io.codearte.accurest.plugin - -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 -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -class GenerateServerTestsTask extends ConventionTask { - - @InputDirectory - File contractsDslDir - @OutputDirectory - File generatedTestSourcesDir - - //TODO: How to deal with @Input*, @Output* and that domain object? - AccurestConfigProperties configProperties - - @TaskAction - void generate() { - project.logger.info("Accurest Plugin: Invoking test sources generation") - - project.sourceSets.test.groovy { - project.logger.info("Registering ${getConfigProperties().generatedTestSourcesDir} as test source directory") - srcDir getConfigProperties().generatedTestSourcesDir - } - - try { - //TODO: What with that? How to pass? - TestGenerator generator = new TestGenerator(getConfigProperties()) - int generatedClasses = generator.generate() - project.logger.info("Generated {} test classes", generatedClasses) - } catch (AccurestException e) { - throw new GradleException("Accurest Plugin exception: ${e.message}", e) - } - } -} diff --git a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy deleted file mode 100644 index 3a7825fbda..0000000000 --- a/accurest-gradle-plugin/src/main/groovy/io/codearte/accurest/plugin/GenerateWireMockClientStubsFromDslTask.groovy +++ /dev/null @@ -1,28 +0,0 @@ -package io.codearte.accurest.plugin - -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.wiremock.DslToWireMockClientConverter -import io.codearte.accurest.wiremock.RecursiveFilesConverter -import org.gradle.api.internal.ConventionTask -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -//TODO: Implement as an incremental task: https://gradle.org/docs/current/userguide/custom_tasks.html#incremental_tasks ? -class GenerateWireMockClientStubsFromDslTask extends ConventionTask { - - @InputDirectory - File contractsDslDir - @OutputDirectory - File stubsOutputDir - - AccurestConfigProperties configProperties - - @TaskAction - void generate() { - logger.info("Accurest Plugin: Invoking GroovyDSL to WireMock client stubs conversion") - logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), getConfigProperties()) - converter.processFiles() - } -} diff --git a/accurest-gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties b/accurest-gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties deleted file mode 100644 index edfd566c2c..0000000000 --- a/accurest-gradle-plugin/src/main/resources/META-INF/gradle-plugins/accurest.properties +++ /dev/null @@ -1 +0,0 @@ -implementation-class=io.codearte.accurest.plugin.AccurestGradlePlugin \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestGradlePluginTest.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestGradlePluginTest.groovy deleted file mode 100644 index e5ef0640ff..0000000000 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestGradlePluginTest.groovy +++ /dev/null @@ -1,22 +0,0 @@ -package io.codearte.accurest.plugin - -import org.gradle.api.Project -import org.gradle.testfixtures.ProjectBuilder -import spock.lang.Ignore -import spock.lang.Specification - -/** - * @author Jakub Kubrynski - */ -@Ignore -class AccurestGradlePluginTest extends Specification { - - def void greeterPluginAddsGreetingTaskToProject() { - when: - Project project = ProjectBuilder.builder().build() - project.apply plugin: 'accurest' - - then: - project.tasks.generateAccurest - } -} diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy deleted file mode 100755 index 0bb8b9697b..0000000000 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/MessagingProjectSpec.groovy +++ /dev/null @@ -1,31 +0,0 @@ -package io.codearte.accurest.plugin - -import spock.lang.Stepwise - -@Stepwise -class MessagingProjectSpec extends AccurestIntegrationSpec { - - def setup() { - setupForProject("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', "publishToMavenLocal") - jarContainsAccurestContracts('build/libs') - } - - 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', "publishToMavenLocal") - jarContainsAccurestContracts('build/libs') - } - -} diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy deleted file mode 100755 index 6a44c37fa1..0000000000 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleJerseyProjectSpec.groovy +++ /dev/null @@ -1,30 +0,0 @@ -package io.codearte.accurest.plugin - -import spock.lang.Stepwise - -@Stepwise -class SampleJerseyProjectSpec extends AccurestIntegrationSpec { - - def setup() { - setupForProject("functionalTest/sampleJerseyProject") - 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', "publishToMavenLocal") - jarContainsAccurestContracts('fraudDetectionService/build/libs') - } - - def "should pass basic flow for JUnit"() { - given: - switchToJunitTestFramework() - assert fileExists('build.gradle') - expect: - runTasksSuccessfully('check', "publishToMavenLocal") - jarContainsAccurestContracts('fraudDetectionService/build/libs') - } - -} diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy deleted file mode 100755 index 140a9d898a..0000000000 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/SampleProjectSpec.groovy +++ /dev/null @@ -1,30 +0,0 @@ -package io.codearte.accurest.plugin - -import spock.lang.Stepwise - -@Stepwise -class SampleProjectSpec extends AccurestIntegrationSpec { - - def setup() { - setupForProject("functionalTest/sampleProject") - 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', "publishToMavenLocal") - jarContainsAccurestContracts('fraudDetectionService/build/libs') - } - - def "should pass basic flow for JUnit"() { - given: - switchToJunitTestFramework() - assert fileExists('build.gradle') - expect: - runTasksSuccessfully('check', "publishToMavenLocal") - jarContainsAccurestContracts('fraudDetectionService/build/libs') - } - -} diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy b/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy deleted file mode 100755 index 939b71db70..0000000000 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/ScenarioProjectSpec.groovy +++ /dev/null @@ -1,30 +0,0 @@ -package io.codearte.accurest.plugin - -import spock.lang.Stepwise - -@Stepwise -class ScenarioProjectSpec extends AccurestIntegrationSpec { - - def setup() { - setupForProject("functionalTest/scenarioProject") - 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', "publishToMavenLocal") - jarContainsAccurestContracts('fraudDetectionService/build/libs') - } - - def "should pass basic flow for JUnit"() { - given: - assert fileExists('build.gradle') - expect: - switchToJunitTestFramework() - runTasksSuccessfully('check', "publishToMavenLocal") - jarContainsAccurestContracts('fraudDetectionService/build/libs') - } - -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties deleted file mode 100644 index 03c9b16bb8..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties +++ /dev/null @@ -1,6 +0,0 @@ -groupId=com.ofg -jacksonMapper=1.9.13 -restAssuredVersion=2.4.0 -springVersion=4.1.7.RELEASE - -springBootVersion=1.3.3.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties deleted file mode 100755 index cfa20637e3..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Sat Feb 21 20:13:29 CET 2015 -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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy deleted file mode 100644 index 826f71b791..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy +++ /dev/null @@ -1,18 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - priority 2 - request { - method 'PUT' - url '/api/12' - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - status 200 - } -} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy deleted file mode 100644 index 8348974b89..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/com/ofg/twitter-places-analyzer/pairId/moreComplexVersion.groovy +++ /dev/null @@ -1,25 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) - headers { - header 'Content-Type': 'application/json' - } - body '''\ - [{ - "text": "Gonna see you at Warsaw" - }] -''' - } - response { - headers { - header 'Content-Type': $(client('application/json'), server(regex('application/json.*'))) - header 'Location': $(client('https://localhost:8080'), server(execute('isEmpty($it)'))) - } - body ( - path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), - correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) - ) - status 200 - } -} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle deleted file mode 100644 index d227b869a2..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name='bootSimple' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy deleted file mode 100644 index 458e275daf..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/AcceptanceSpec.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package com.ofg.twitter.places - -import com.ofg.twitter.place.PairIdController -import org.springframework.http.MediaType -import org.springframework.test.web.servlet.MockMvc -import org.springframework.test.web.servlet.setup.MockMvcBuilders -import spock.lang.Specification - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status - -class AcceptanceSpec extends Specification { - - def "should have controller up and running"() { - given: - MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PairIdController()).build() - expect: - mockMvc.perform(put("/api/${1}"). - contentType(MediaType.APPLICATION_JSON). - content("""[{"text":"Gonna see you at Warsaw"}]""")). - andExpect(status().isOk()) - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy deleted file mode 100644 index 4e94ba6525..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package com.ofg.twitter.places - -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import com.ofg.twitter.place.PairIdController -import spock.lang.Specification - -// tag::base_class[] -abstract class BaseMockMvcSpec extends Specification { - - def setup() { - RestAssuredMockMvc.standaloneSetup(new PairIdController()) - } - - void isProperCorrelationId(Integer correlationId) { - assert correlationId == 123456 - } - - void isEmpty(String value) { - assert value == null - } - -} -// end::base_class[] diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy deleted file mode 100644 index 315c39c794..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy +++ /dev/null @@ -1,14 +0,0 @@ -import ch.qos.logback.classic.encoder.PatternLayoutEncoder -import ch.qos.logback.core.ConsoleAppender - -String console = "CONSOLE" -String logPattern = "%d{yyyy-MM-dd HH:mm:ss.SSSZ, Europe/Warsaw} | %-5level | %X{correlationId} | %thread | %logger{1} | %m%n" - -appender(console, ConsoleAppender) { - encoder(PatternLayoutEncoder) { - pattern = logPattern - } -} - -root(INFO, [console]) -logger("com.ofg", DEBUG) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties deleted file mode 100644 index 6910517f7c..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties +++ /dev/null @@ -1,6 +0,0 @@ -groupId=io.codearte -jacksonMapper=1.9.13 -restAssuredVersion=2.9.0 -springVersion=4.2.3.RELEASE - -springBootVersion=1.3.3.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties deleted file mode 100755 index a1f7bb3d56..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy deleted file mode 100644 index 6de37631ef..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy +++ /dev/null @@ -1,10 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - url '/foo' - method 'GET' - } - response { - status 200 - body 'bar' - } -} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy deleted file mode 100644 index aa319831a4..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy +++ /dev/null @@ -1,13 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - label 'some_label' - input { - messageFrom('delete') - messageBody([ - bookName: 'foo' - ]) - messageHeaders { - header('sample', 'header') - } - assertThat('bookWasDeleted()') - } -} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy deleted file mode 100644 index b21b1c7cd1..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy +++ /dev/null @@ -1,13 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - label 'some_label' - input { - triggeredBy('bookReturnedTriggered()') - } - outputMessage { - sentTo('output') - body('''{ "bookName" : "foo" }''') - headers { - header('BOOK-NAME', 'foo') - } - } -} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy deleted file mode 100644 index e6090df410..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy +++ /dev/null @@ -1,21 +0,0 @@ -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') - } - } -} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle deleted file mode 100644 index d227b869a2..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name='bootSimple' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookDeleted.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookDeleted.groovy deleted file mode 100644 index bf3cd9b68c..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookDeleted.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookReturned.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookReturned.groovy deleted file mode 100644 index 3b244a0395..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookReturned.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/IntegrationMessagingApplication.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/IntegrationMessagingApplication.groovy deleted file mode 100644 index ed28a54b59..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/IntegrationMessagingApplication.groovy +++ /dev/null @@ -1,22 +0,0 @@ -package io.codearte.accurest.samples.book - -import org.springframework.boot.SpringApplication -import org.springframework.boot.autoconfigure.SpringBootApplication -import org.springframework.context.annotation.ImportResource -import org.springframework.web.bind.annotation.RequestMapping -import org.springframework.web.bind.annotation.RestController - -@SpringBootApplication -@RestController -@ImportResource("classpath*:integration-context.xml") -class IntegrationMessagingApplication { - - @RequestMapping("/foo") - String foo() { - return "bar" - } - - static void main(String[] args) { - SpringApplication.run(IntegrationMessagingApplication.class, args) - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy deleted file mode 100644 index 44b1c08604..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy +++ /dev/null @@ -1,27 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":99999} - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status 200 - body( """{ - "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", - "rejectionReason": "Amount too high" -}""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy deleted file mode 100644 index 7bc64d0dac..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy +++ /dev/null @@ -1,28 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b87c365d51..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 8b2268d1ba..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Jan 28 00:32:44 CET 2015 -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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java deleted file mode 100644 index 5e91273eda..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public class Client { - - private String pesel; - - public String getPesel() { - return pesel; - } - - public void setPesel(String pesel) { - this.pesel = pesel; - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b87c365d51..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java deleted file mode 100644 index ac595998bc..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -import java.math.BigDecimal; - -public class FraudServiceRequest { - - private String clientPesel; - - private BigDecimal loanAmount; - - public FraudServiceRequest() { - } - - public FraudServiceRequest(LoanApplication loanApplication) { - this.clientPesel = loanApplication.getClient().getPesel(); - this.loanAmount = loanApplication.getAmount(); - } - - public String getClientPesel() { - return clientPesel; - } - - public void setClientPesel(String clientPesel) { - this.clientPesel = clientPesel; - } - - public BigDecimal getLoanAmount() { - return loanAmount; - } - - public void setLoanAmount(BigDecimal loanAmount) { - this.loanAmount = loanAmount; - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java deleted file mode 100644 index 816087988b..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -import java.math.BigDecimal; - -public class LoanApplication { - - private Client client; - - private BigDecimal amount; - - private String loanApplicationId; - - public Client getClient() { - return client; - } - - public void setClient(Client client) { - this.client = client; - } - - public BigDecimal getAmount() { - return amount; - } - - public void setAmount(BigDecimal amount) { - this.amount = amount; - } - - public String getLoanApplicationId() { - return loanApplicationId; - } - - public void setLoanApplicationId(String loanApplicationId) { - this.loanApplicationId = loanApplicationId; - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle deleted file mode 100644 index 6a42a6c7ce..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -include ':fraudDetectionService' -include ':loanApplicationService' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy deleted file mode 100644 index 44b1c08604..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy +++ /dev/null @@ -1,27 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":99999} - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status 200 - body( """{ - "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", - "rejectionReason": "Amount too high" -}""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy deleted file mode 100644 index 7bc64d0dac..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy +++ /dev/null @@ -1,28 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b87c365d51..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy deleted file mode 100644 index bcb6ef1579..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package com.blogspot.toomuchcoding - -import com.blogspot.toomuchcoding.frauddetection.FraudDetectionController -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) - } - - void assertThatRejectionReasonIsNull(def rejectionReason) { - assert !rejectionReason - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 8b2268d1ba..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Jan 28 00:32:44 CET 2015 -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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b87c365d51..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle deleted file mode 100644 index 6a42a6c7ce..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -include ':fraudDetectionService' -include ':loanApplicationService' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy deleted file mode 100644 index 7bc64d0dac..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy +++ /dev/null @@ -1,28 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method 'PUT' - url '/fraudcheck' - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":123.123 - } - """ - ) - headers { - header('Content-Type', 'application/vnd.fraud.v1+json') - } - - } - response { - status 200 - body( - fraudCheckStatus: "OK", - rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) - ) - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy deleted file mode 100644 index 44b1c08604..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy +++ /dev/null @@ -1,27 +0,0 @@ -io.codearte.accurest.dsl.GroovyDsl.make { - request { - method """PUT""" - url """/fraudcheck""" - body(""" - { - "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", - "loanAmount":99999} - """ - ) - headers { - header("""Content-Type""", """application/vnd.fraud.v1+json""") - } - - } - response { - status 200 - body( """{ - "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", - "rejectionReason": "Amount too high" -}""") - headers { - header('Content-Type': 'application/vnd.fraud.v1+json') - } - } - -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b87c365d51..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy deleted file mode 100644 index bcb6ef1579..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package com.blogspot.toomuchcoding - -import com.blogspot.toomuchcoding.frauddetection.FraudDetectionController -import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc -import spock.lang.Specification - -class MvcSpec extends Specification { - def setup() { - RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) - } - - void assertThatRejectionReasonIsNull(def rejectionReason) { - assert !rejectionReason - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 8b2268d1ba..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,6 +0,0 @@ -#Wed Jan 28 00:32:44 CET 2015 -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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java deleted file mode 100644 index 5a1a60244e..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; - -@Configuration -@EnableAutoConfiguration -@ComponentScan -public class Application { - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java deleted file mode 100644 index b87c365d51..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public enum FraudCheckStatus { - OK, FRAUD -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java deleted file mode 100644 index 9f3353ecbf..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public class FraudServiceResponse { - - private FraudCheckStatus fraudCheckStatus; - - private String rejectionReason; - - public FraudServiceResponse() { - } - - public FraudCheckStatus getFraudCheckStatus() { - return fraudCheckStatus; - } - - public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { - this.fraudCheckStatus = fraudCheckStatus; - } - - public String getRejectionReason() { - return rejectionReason; - } - - public void setRejectionReason(String rejectionReason) { - this.rejectionReason = rejectionReason; - } -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java deleted file mode 100644 index 7f7f86e0ea..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.blogspot.toomuchcoding.frauddetection.model; - -public enum LoanApplicationStatus { - LOAN_APPLIED, LOAN_APPLICATION_REJECTED -} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle b/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle deleted file mode 100644 index 6a42a6c7ce..0000000000 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle +++ /dev/null @@ -1,2 +0,0 @@ -include ':fraudDetectionService' -include ':loanApplicationService' diff --git a/accurest-messaging/README.adoc b/accurest-messaging/README.adoc deleted file mode 100644 index b59884a982..0000000000 --- a/accurest-messaging/README.adoc +++ /dev/null @@ -1,25 +0,0 @@ - = Accurest Messaging - -Accurest allows you to verify your application that uses messaging as means of communication. -All of our integrations are working with Spring but you can also set one yourself. - -== Integrations - -You can use one of the three integration configurations: - -- Apache Camel -- Spring Integration -- Spring Cloud Stream - -If you're using Spring Boot, the aforementioned test configurations will be appended automatically. - -== Manual Integration - -The `accurest-messaging-core` module contains 3 main interfaces: - -- AccurestMessage - describes a message received / sent to a channel / queue / topic etc. -- AccurestMessageBuilder - describes how to build a message -- AccurestMessaging - class that allows you to build, send and receive messages - -In the generated test the `AccurestMessaging` is injected via `@Inject` annotation thus you can - diff --git a/accurest-messaging/accurest-messaging-camel/build.gradle b/accurest-messaging/accurest-messaging-camel/build.gradle deleted file mode 100644 index f43e73d0b4..0000000000 --- a/accurest-messaging/accurest-messaging-camel/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -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:${camelVersion}" - compile 'org.slf4j:slf4j-api:1.6.0' -} \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelConfiguration.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelConfiguration.java deleted file mode 100644 index b96caf5ccc..0000000000 --- a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelConfiguration.java +++ /dev/null @@ -1,22 +0,0 @@ -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(); - } -} diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java deleted file mode 100644 index 58f5609fd6..0000000000 --- a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessageBuilder.java +++ /dev/null @@ -1,31 +0,0 @@ -package io.codearte.accurest.messaging.camel; - -import java.util.Map; - -import org.apache.camel.Message; -import org.apache.camel.impl.DefaultMessage; - -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; - -/** - * @author Marcin Grzejszczak - */ -public class AccurestCamelMessageBuilder implements AccurestMessageBuilder { - - @Override - public AccurestMessage create(T payload, Map headers) { - DefaultMessage message = new DefaultMessage(); - message.setBody(payload); - message.setHeaders(headers); - return new CamelMessage<>(message); - } - - @Override - public AccurestMessage create(Message message) { - if (message == null) { - return null; - } - return new CamelMessage<>(message); - } -} diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/CamelMessage.java b/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/CamelMessage.java deleted file mode 100644 index 6511617a89..0000000000 --- a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/CamelMessage.java +++ /dev/null @@ -1,40 +0,0 @@ -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 implements AccurestMessage { - - private final Message delegate; - - public CamelMessage(Message delegate) { - this.delegate = delegate; - } - - @Override - @SuppressWarnings("unchecked") - public T getPayload() { - return (T) delegate.getBody(); - } - - @Override - public Map getHeaders() { - return delegate.getHeaders(); - } - - @Override - public Object getHeader(String key) { - return getHeaders().get(key); - } - - @Override - public Message convert() { - return delegate; - } - -} diff --git a/accurest-messaging/accurest-messaging-core/build.gradle b/accurest-messaging/accurest-messaging-core/build.gradle deleted file mode 100644 index 8415bec8c7..0000000000 --- a/accurest-messaging/accurest-messaging-core/build.gradle +++ /dev/null @@ -1,8 +0,0 @@ -repositories { - jcenter() -} - -dependencies { - compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0' - compile 'javax.inject:javax.inject:1' -} \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestFilter.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestFilter.java deleted file mode 100644 index f41e544df0..0000000000 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestFilter.java +++ /dev/null @@ -1,14 +0,0 @@ -package io.codearte.accurest.messaging; - -/** - * Contract for filtering out messages that do not match the structure in the Accurest DSL - * - * @author Marcin Grzejszczak - */ -public interface AccurestFilter { - - /** - * @return @{code true} if the message should be passed through, @{code false} if the message should be filtered out, - */ - boolean matches(AccurestMessage message); -} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessage.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessage.java deleted file mode 100644 index 65710a537a..0000000000 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessage.java +++ /dev/null @@ -1,32 +0,0 @@ -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 { - - /** - * Returns a payload of type {@code PAYLOAD} - */ - PAYLOAD getPayload(); - - /** - * Returns a map of headers - */ - Map 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(); -} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessageBuilder.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessageBuilder.java deleted file mode 100644 index 3d0a0e37e4..0000000000 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessageBuilder.java +++ /dev/null @@ -1,22 +0,0 @@ -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 { - - /** - * Creates a {@link AccurestMessage} from payload and headers - */ - AccurestMessage create(PAYLOAD payload, Map headers); - - /** - * Creates a {@link AccurestMessage} from the {@code TYPE_TO_CONVERT_INTO} type - */ - AccurestMessage create(TYPE_TO_CONVERT_INTO typeToConvertInto); -} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java deleted file mode 100644 index 17ee2e40bf..0000000000 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessaging.java +++ /dev/null @@ -1,34 +0,0 @@ -package io.codearte.accurest.messaging; - -import java.util.Map; -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 extends AccurestMessageBuilder { - /** - * Sends the {@link AccurestMessage} to the given destination. - */ - void send(AccurestMessage message, String destination); - - /** - * Sends the given payload with headers, to the given destination. - */ - void send(PAYLOAD payload, Map headers, String destination); - - /** - * Receives the {@link AccurestMessage} from the given destination. You can provide the timeout - * for receiving that message. - */ - AccurestMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit); - - /** - * Receives the {@link AccurestMessage} from the given destination. A default timeout will be applied. - */ - AccurestMessage receiveMessage(String destination); -} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestObjectMapper.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestObjectMapper.java deleted file mode 100644 index 39740539ad..0000000000 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestObjectMapper.java +++ /dev/null @@ -1,30 +0,0 @@ -package io.codearte.accurest.messaging; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** - * Wrapper over {@link ObjectMapper} that won't try to parse - * String but will directly return it. - * - * @author Marcin Grzejszczak - */ -public class AccurestObjectMapper { - - private final ObjectMapper objectMapper; - - public AccurestObjectMapper(ObjectMapper objectMapper) { - this.objectMapper = objectMapper; - } - - public AccurestObjectMapper() { - this.objectMapper = new ObjectMapper(); - } - - public String writeValueAsString(Object payload) throws JsonProcessingException { - if (payload instanceof String) { - return payload.toString(); - } - return objectMapper.writeValueAsString(payload); - } -} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessage.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessage.java deleted file mode 100644 index 179a63d9b7..0000000000 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessage.java +++ /dev/null @@ -1,30 +0,0 @@ -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 getHeaders() { - return null; - } - - @Override - public Object getHeader(String key) { - return null; - } - - @Override - public Object convert() { - return null; - } -} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java deleted file mode 100644 index eadbc73b02..0000000000 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessageBuilder.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.codearte.accurest.messaging.noop; - -import java.util.Map; - -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; - -/** - * @author Marcin Grzejszczak - */ -public class NoOpAccurestMessageBuilder implements AccurestMessageBuilder { - @Override - public AccurestMessage create(Object o, Map headers) { - return new NoOpAccurestMessage(); - } - - @Override - public AccurestMessage create(Object o) { - return new NoOpAccurestMessage(); - } -} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java b/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java deleted file mode 100644 index 77d186bcd8..0000000000 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/noop/NoOpAccurestMessaging.java +++ /dev/null @@ -1,42 +0,0 @@ -package io.codearte.accurest.messaging.noop; - -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessaging; - -/** - * @author Marcin Grzejszczak - */ -public class NoOpAccurestMessaging implements AccurestMessaging { - @Override - public void send(AccurestMessage message, String destination) { - - } - - @Override - public void send(Object payload, Map headers, 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; - } -} diff --git a/accurest-messaging/accurest-messaging-integration/build.gradle b/accurest-messaging/accurest-messaging-integration/build.gradle deleted file mode 100644 index f2ed07c88c..0000000000 --- a/accurest-messaging/accurest-messaging-integration/build.gradle +++ /dev/null @@ -1,16 +0,0 @@ -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:${springVersion}" - compile 'org.slf4j:slf4j-api:1.6.0' -} \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationConfiguration.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationConfiguration.java deleted file mode 100644 index 214161b605..0000000000 --- a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationConfiguration.java +++ /dev/null @@ -1,22 +0,0 @@ -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(); - } -} diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java deleted file mode 100644 index 20dc976523..0000000000 --- a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessageBuilder.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.codearte.accurest.messaging.integration; - -import java.util.Map; - -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.support.MessageBuilder; - -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; - -/** - * @author Marcin Grzejszczak - */ -public class AccurestIntegrationMessageBuilder implements AccurestMessageBuilder> { - - @Override - public AccurestMessage> create(T payload, Map headers) { - return new IntegrationMessage<>(MessageBuilder.createMessage(payload, new MessageHeaders(headers))); - } - - @Override - public AccurestMessage> create(Message message) { - if (message == null) { - return null; - } - return new IntegrationMessage<>(message); - } -} diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java deleted file mode 100644 index b977036e36..0000000000 --- a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/AccurestIntegrationMessaging.java +++ /dev/null @@ -1,84 +0,0 @@ -package io.codearte.accurest.messaging.integration; - -import java.util.Map; -import java.util.concurrent.TimeUnit; - -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 io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; -import io.codearte.accurest.messaging.AccurestMessaging; - -/** - * @author Marcin Grzejszczak - */ -@Component -public class AccurestIntegrationMessaging implements AccurestMessaging> { - - 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 - @SuppressWarnings("unchecked") - public void send(T payload, Map headers, String destination) { - send(builder.create(payload, headers), destination); - } - - @Override - public void send(AccurestMessage> 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> 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> receiveMessage(String destination) { - return receiveMessage(destination, 5, TimeUnit.SECONDS); - } - - @Override - @SuppressWarnings("unchecked") - public AccurestMessage> create(T t, Map headers) { - return builder.create(t, headers); - } - - @Override - @SuppressWarnings("unchecked") - public AccurestMessage> create(Message message) { - return builder.create(message); - } -} diff --git a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/IntegrationMessage.java b/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/IntegrationMessage.java deleted file mode 100644 index 87b472f7dd..0000000000 --- a/accurest-messaging/accurest-messaging-integration/src/main/java/io/codearte/accurest/messaging/integration/IntegrationMessage.java +++ /dev/null @@ -1,38 +0,0 @@ -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 implements AccurestMessage> { - - private final Message delegate; - - public IntegrationMessage(Message 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 convert() { - return delegate; - } - -} diff --git a/accurest-messaging/accurest-messaging-integration/src/main/resources/META-INF/spring.factories b/accurest-messaging/accurest-messaging-integration/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 117d34083a..0000000000 --- a/accurest-messaging/accurest-messaging-integration/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.messaging.integration.AccurestIntegrationConfiguration diff --git a/accurest-messaging/accurest-messaging-stream/build.gradle b/accurest-messaging/accurest-messaging-stream/build.gradle deleted file mode 100644 index 4f8c9c7344..0000000000 --- a/accurest-messaging/accurest-messaging-stream/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -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.cloud:spring-cloud-stream:${springStreamVersion}" - // for MessageCollector - compile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" -} \ No newline at end of file diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamAutoConfiguration.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamAutoConfiguration.java deleted file mode 100644 index 243f856acb..0000000000 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamAutoConfiguration.java +++ /dev/null @@ -1,24 +0,0 @@ -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(); - } -} diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java deleted file mode 100644 index 7f4d994e0a..0000000000 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessageBuilder.java +++ /dev/null @@ -1,29 +0,0 @@ -package io.codearte.accurest.messaging.stream; - -import java.util.Map; - -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageHeaders; -import org.springframework.messaging.support.MessageBuilder; - -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; - -/** - * @author Marcin Grzejszczak - */ -public class AccurestStreamMessageBuilder implements AccurestMessageBuilder> { - - @Override - public AccurestMessage> create(T payload, Map headers) { - return new StreamMessage<>(MessageBuilder.createMessage(payload, new MessageHeaders(headers))); - } - - @Override - public AccurestMessage> create(Message message) { - if (message == null) { - return null; - } - return new StreamMessage<>(message); - } -} diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java b/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java deleted file mode 100644 index 9f0a3ba694..0000000000 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/StreamMessage.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.codearte.accurest.messaging.stream; - -import org.springframework.messaging.Message; -import org.springframework.messaging.MessageHeaders; - -import io.codearte.accurest.messaging.AccurestMessage; - -/** - * @author Marcin Grzejszczak - */ -public class StreamMessage implements AccurestMessage> { - - private final Message delegate; - - public StreamMessage(Message 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 convert() { - return delegate; - } - -} diff --git a/accurest-messaging/accurest-messaging-stream/src/main/resources/META-INF/spring.factories b/accurest-messaging/accurest-messaging-stream/src/main/resources/META-INF/spring.factories deleted file mode 100644 index b2ba657e44..0000000000 --- a/accurest-messaging/accurest-messaging-stream/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.messaging.stream.AccurestStreamAutoConfiguration diff --git a/accurest-testing-utils/src/main/groovy/io/codearte/accurest/util/AssertionUtil.groovy b/accurest-testing-utils/src/main/groovy/io/codearte/accurest/util/AssertionUtil.groovy deleted file mode 100644 index 4c632a4de3..0000000000 --- a/accurest-testing-utils/src/main/groovy/io/codearte/accurest/util/AssertionUtil.groovy +++ /dev/null @@ -1,12 +0,0 @@ -package io.codearte.accurest.util - -import org.skyscreamer.jsonassert.JSONAssert - -class AssertionUtil { - - private static boolean NON_STRICT = false - - public static void assertThatJsonsAreEqual(String expected, String actual) { - JSONAssert.assertEquals(expected, actual, NON_STRICT) - } -} diff --git a/asciidoctor.css b/asciidoctor.css new file mode 100644 index 0000000000..06d52e688a --- /dev/null +++ b/asciidoctor.css @@ -0,0 +1,399 @@ +/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */ +/* Remove the comments around the @import statement below when using this as a custom stylesheet */ +/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic|Noto+Serif:400,400italic,700,700italic|Droid+Sans+Mono:400";*/ +article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block} +audio,canvas,video{display:inline-block} +audio:not([controls]){display:none;height:0} +[hidden],template{display:none} +script{display:none!important} +html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%} +body{margin:0} +a{background:transparent} +a:focus{outline:thin dotted} +a:active,a:hover{outline:0} +h1{font-size:2em;margin:.67em 0} +abbr[title]{border-bottom:1px dotted} +b,strong{font-weight:bold} +dfn{font-style:italic} +hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0} +mark{background:#ff0;color:#000} +code,kbd,pre,samp{font-family:monospace;font-size:1em} +pre{white-space:pre-wrap} +q{quotes:"\201C" "\201D" "\2018" "\2019"} +small{font-size:80%} +sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} +sup{top:-.5em} +sub{bottom:-.25em} +img{border:0} +svg:not(:root){overflow:hidden} +figure{margin:0} +fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em} +legend{border:0;padding:0} +button,input,select,textarea{font-family:inherit;font-size:100%;margin:0} +button,input{line-height:normal} +button,select{text-transform:none} +button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer} +button[disabled],html input[disabled]{cursor:default} +input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0} +input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box} +input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none} +button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0} +textarea{overflow:auto;vertical-align:top} +table{border-collapse:collapse;border-spacing:0} +*,*:before,*:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box} +html,body{font-size:100%} +body{background:#fff;color:rgba(0,0,0,.8);padding:0;margin:0;font-family:"Noto Serif","DejaVu Serif",serif;font-weight:400;font-style:normal;line-height:1;position:relative;cursor:auto} +a:hover{cursor:pointer} +img,object,embed{max-width:100%;height:auto} +object,embed{height:100%} +img{-ms-interpolation-mode:bicubic} +#map_canvas img,#map_canvas embed,#map_canvas object,.map_canvas img,.map_canvas embed,.map_canvas object{max-width:none!important} +.left{float:left!important} +.right{float:right!important} +.text-left{text-align:left!important} +.text-right{text-align:right!important} +.text-center{text-align:center!important} +.text-justify{text-align:justify!important} +.hide{display:none} +.antialiased,body{-webkit-font-smoothing:antialiased} +img{display:inline-block;vertical-align:middle} +textarea{height:auto;min-height:50px} +select{width:100%} +p.lead,.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{font-size:1.21875em;line-height:1.6} +.subheader,.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{line-height:1.45;color:#7a2518;font-weight:400;margin-top:0;margin-bottom:.25em} +div,dl,dt,dd,ul,ol,li,h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6,pre,form,p,blockquote,th,td{margin:0;padding:0;direction:ltr} +a{color:#2156a5;text-decoration:underline;line-height:inherit} +a:hover,a:focus{color:#1d4b8f} +a img{border:none} +p{font-family:inherit;font-weight:400;font-size:1em;line-height:1.6;margin-bottom:1.25em;text-rendering:optimizeLegibility} +p aside{font-size:.875em;line-height:1.35;font-style:italic} +h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{font-family:"Open Sans","DejaVu Sans",sans-serif;font-weight:300;font-style:normal;color:#ba3925;text-rendering:optimizeLegibility;margin-top:1em;margin-bottom:.5em;line-height:1.0125em} +h1 small,h2 small,h3 small,#toctitle small,.sidebarblock>.content>.title small,h4 small,h5 small,h6 small{font-size:60%;color:#e99b8f;line-height:0} +h1{font-size:2.125em} +h2{font-size:1.6875em} +h3,#toctitle,.sidebarblock>.content>.title{font-size:1.375em} +h4,h5{font-size:1.125em} +h6{font-size:1em} +hr{border:solid #ddddd8;border-width:1px 0 0;clear:both;margin:1.25em 0 1.1875em;height:0} +em,i{font-style:italic;line-height:inherit} +strong,b{font-weight:bold;line-height:inherit} +small{font-size:60%;line-height:inherit} +code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;color:rgba(0,0,0,.9)} +ul,ol,dl{font-size:1em;line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit} +ul,ol,ul.no-bullet,ol.no-bullet{margin-left:1.5em} +ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0;font-size:1em} +ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit} +ul.square{list-style-type:square} +ul.circle{list-style-type:circle} +ul.disc{list-style-type:disc} +ul.no-bullet{list-style:none} +ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0} +dl dt{margin-bottom:.3125em;font-weight:bold} +dl dd{margin-bottom:1.25em} +abbr,acronym{text-transform:uppercase;font-size:90%;color:rgba(0,0,0,.8);border-bottom:1px dotted #ddd;cursor:help} +abbr{text-transform:none} +blockquote{margin:0 0 1.25em;padding:.5625em 1.25em 0 1.1875em;border-left:1px solid #ddd} +blockquote cite{display:block;font-size:.9375em;color:rgba(0,0,0,.6)} +blockquote cite:before{content:"\2014 \0020"} +blockquote cite a,blockquote cite a:visited{color:rgba(0,0,0,.6)} +blockquote,blockquote p{line-height:1.6;color:rgba(0,0,0,.85)} +@media only screen and (min-width:768px){h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2} +h1{font-size:2.75em} +h2{font-size:2.3125em} +h3,#toctitle,.sidebarblock>.content>.title{font-size:1.6875em} +h4{font-size:1.4375em}}table{background:#fff;margin-bottom:1.25em;border:solid 1px #dedede} +table thead,table tfoot{background:#f7f8f7;font-weight:bold} +table thead tr th,table thead tr td,table tfoot tr th,table tfoot tr td{padding:.5em .625em .625em;font-size:inherit;color:rgba(0,0,0,.8);text-align:left} +table tr th,table tr td{padding:.5625em .625em;font-size:inherit;color:rgba(0,0,0,.8)} +table tr.even,table tr.alt,table tr:nth-of-type(even){background:#f8f8f7} +table thead tr th,table tfoot tr th,table tbody tr td,table tr td,table tfoot tr td{display:table-cell;line-height:1.6} +h1,h2,h3,#toctitle,.sidebarblock>.content>.title,h4,h5,h6{line-height:1.2;word-spacing:-.05em} +h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title strong,h4 strong,h5 strong,h6 strong{font-weight:400} +.clearfix:before,.clearfix:after,.float-group:before,.float-group:after{content:" ";display:table} +.clearfix:after,.float-group:after{clear:both} +*:not(pre)>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background-color:#f7f7f8;-webkit-border-radius:4px;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed} +pre,pre>code{line-height:1.45;color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;text-rendering:optimizeSpeed} +.keyseq{color:rgba(51,51,51,.8)} +kbd{display:inline-block;color:rgba(0,0,0,.8);font-size:.75em;line-height:1.4;background-color:#f7f7f7;border:1px solid #ccc;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em white inset;box-shadow:0 1px 0 rgba(0,0,0,.2),0 0 0 .1em #fff inset;margin:-.15em .15em 0 .15em;padding:.2em .6em .2em .5em;vertical-align:middle;white-space:nowrap} +.keyseq kbd:first-child{margin-left:0} +.keyseq kbd:last-child{margin-right:0} +.menuseq,.menu{color:rgba(0,0,0,.8)} +b.button:before,b.button:after{position:relative;top:-1px;font-weight:400} +b.button:before{content:"[";padding:0 3px 0 2px} +b.button:after{content:"]";padding:0 2px 0 3px} +p a>code:hover{color:rgba(0,0,0,.9)} +#header,#content,#footnotes,#footer{width:100%;margin-left:auto;margin-right:auto;margin-top:0;margin-bottom:0;max-width:62.5em;*zoom:1;position:relative;padding-left:.9375em;padding-right:.9375em} +#header:before,#header:after,#content:before,#content:after,#footnotes:before,#footnotes:after,#footer:before,#footer:after{content:" ";display:table} +#header:after,#content:after,#footnotes:after,#footer:after{clear:both} +#content{margin-top:1.25em} +#content:before{content:none} +#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0} +#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #ddddd8} +#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #ddddd8;padding-bottom:8px} +#header .details{border-bottom:1px solid #ddddd8;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:-ms-flexbox;display:-webkit-flex;display:flex;-ms-flex-flow:row wrap;-webkit-flex-flow:row wrap;flex-flow:row wrap} +#header .details span:first-child{margin-left:-.125em} +#header .details span.email a{color:rgba(0,0,0,.85)} +#header .details br{display:none} +#header .details br+span:before{content:"\00a0\2013\00a0"} +#header .details br+span.author:before{content:"\00a0\22c5\00a0";color:rgba(0,0,0,.85)} +#header .details br+span#revremark:before{content:"\00a0|\00a0"} +#header #revnumber{text-transform:capitalize} +#header #revnumber:after{content:"\00a0"} +#content>h1:first-child:not([class]){color:rgba(0,0,0,.85);border-bottom:1px solid #ddddd8;padding-bottom:8px;margin-top:0;padding-top:1rem;margin-bottom:1.25rem} +#toc{border-bottom:1px solid #efefed;padding-bottom:.5em} +#toc>ul{margin-left:.125em} +#toc ul.sectlevel0>li>a{font-style:italic} +#toc ul.sectlevel0 ul.sectlevel1{margin:.5em 0} +#toc ul{font-family:"Open Sans","DejaVu Sans",sans-serif;list-style-type:none} +#toc a{text-decoration:none} +#toc a:active{text-decoration:underline} +#toctitle{color:#7a2518;font-size:1.2em} +@media only screen and (min-width:768px){#toctitle{font-size:1.375em} +body.toc2{padding-left:15em;padding-right:0} +#toc.toc2{margin-top:0!important;background-color:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #efefed;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto} +#toc.toc2 #toctitle{margin-top:0;font-size:1.2em} +#toc.toc2>ul{font-size:.9em;margin-bottom:0} +#toc.toc2 ul ul{margin-left:0;padding-left:1em} +#toc.toc2 ul.sectlevel0 ul.sectlevel1{padding-left:0;margin-top:.5em;margin-bottom:.5em} +body.toc2.toc-right{padding-left:0;padding-right:15em} +body.toc2.toc-right #toc.toc2{border-right-width:0;border-left:1px solid #efefed;left:auto;right:0}}@media only screen and (min-width:1280px){body.toc2{padding-left:20em;padding-right:0} +#toc.toc2{width:20em} +#toc.toc2 #toctitle{font-size:1.375em} +#toc.toc2>ul{font-size:.95em} +#toc.toc2 ul ul{padding-left:1.25em} +body.toc2.toc-right{padding-left:0;padding-right:20em}}#content #toc{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} +#content #toc>:first-child{margin-top:0} +#content #toc>:last-child{margin-bottom:0} +#footer{max-width:100%;background-color:rgba(0,0,0,.8);padding:1.25em} +#footer-text{color:rgba(255,255,255,.8);line-height:1.44} +.sect1{padding-bottom:.625em} +@media only screen and (min-width:768px){.sect1{padding-bottom:1.25em}}.sect1+.sect1{border-top:1px solid #efefed} +#content h1>a.anchor,h2>a.anchor,h3>a.anchor,#toctitle>a.anchor,.sidebarblock>.content>.title>a.anchor,h4>a.anchor,h5>a.anchor,h6>a.anchor{position:absolute;z-index:1001;width:1.5ex;margin-left:-1.5ex;display:block;text-decoration:none!important;visibility:hidden;text-align:center;font-weight:400} +#content h1>a.anchor:before,h2>a.anchor:before,h3>a.anchor:before,#toctitle>a.anchor:before,.sidebarblock>.content>.title>a.anchor:before,h4>a.anchor:before,h5>a.anchor:before,h6>a.anchor:before{content:"\00A7";font-size:.85em;display:block;padding-top:.1em} +#content h1:hover>a.anchor,#content h1>a.anchor:hover,h2:hover>a.anchor,h2>a.anchor:hover,h3:hover>a.anchor,#toctitle:hover>a.anchor,.sidebarblock>.content>.title:hover>a.anchor,h3>a.anchor:hover,#toctitle>a.anchor:hover,.sidebarblock>.content>.title>a.anchor:hover,h4:hover>a.anchor,h4>a.anchor:hover,h5:hover>a.anchor,h5>a.anchor:hover,h6:hover>a.anchor,h6>a.anchor:hover{visibility:visible} +#content h1>a.link,h2>a.link,h3>a.link,#toctitle>a.link,.sidebarblock>.content>.title>a.link,h4>a.link,h5>a.link,h6>a.link{color:#ba3925;text-decoration:none} +#content h1>a.link:hover,h2>a.link:hover,h3>a.link:hover,#toctitle>a.link:hover,.sidebarblock>.content>.title>a.link:hover,h4>a.link:hover,h5>a.link:hover,h6>a.link:hover{color:#a53221} +.audioblock,.imageblock,.literalblock,.listingblock,.stemblock,.videoblock{margin-bottom:1.25em} +.admonitionblock td.content>.title,.audioblock>.title,.exampleblock>.title,.imageblock>.title,.listingblock>.title,.literalblock>.title,.stemblock>.title,.openblock>.title,.paragraph>.title,.quoteblock>.title,table.tableblock>.title,.verseblock>.title,.videoblock>.title,.dlist>.title,.olist>.title,.ulist>.title,.qlist>.title,.hdlist>.title{text-rendering:optimizeLegibility;text-align:left;font-family:"Noto Serif","DejaVu Serif",serif;font-size:1rem;font-style:italic} +table.tableblock>caption.title{white-space:nowrap;overflow:visible;max-width:0} +.paragraph.lead>p,#preamble>.sectionbody>.paragraph:first-of-type p{color:rgba(0,0,0,.85)} +table.tableblock #preamble>.sectionbody>.paragraph:first-of-type p{font-size:inherit} +.admonitionblock>table{border-collapse:separate;border:0;background:none;width:100%} +.admonitionblock>table td.icon{text-align:center;width:80px} +.admonitionblock>table td.icon img{max-width:none} +.admonitionblock>table td.icon .title{font-weight:bold;font-family:"Open Sans","DejaVu Sans",sans-serif;text-transform:uppercase} +.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #ddddd8;color:rgba(0,0,0,.6)} +.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0} +.exampleblock>.content{border-style:solid;border-width:1px;border-color:#e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;-webkit-border-radius:4px;border-radius:4px} +.exampleblock>.content>:first-child{margin-top:0} +.exampleblock>.content>:last-child{margin-bottom:0} +.sidebarblock{border-style:solid;border-width:1px;border-color:#e0e0dc;margin-bottom:1.25em;padding:1.25em;background:#f8f8f7;-webkit-border-radius:4px;border-radius:4px} +.sidebarblock>:first-child{margin-top:0} +.sidebarblock>:last-child{margin-bottom:0} +.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center} +.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0} +.literalblock pre,.listingblock pre:not(.highlight),.listingblock pre[class="highlight"],.listingblock pre[class^="highlight "],.listingblock pre.CodeRay,.listingblock pre.prettyprint{background:#f7f7f8} +.sidebarblock .literalblock pre,.sidebarblock .listingblock pre:not(.highlight),.sidebarblock .listingblock pre[class="highlight"],.sidebarblock .listingblock pre[class^="highlight "],.sidebarblock .listingblock pre.CodeRay,.sidebarblock .listingblock pre.prettyprint{background:#f2f1f1} +.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{-webkit-border-radius:4px;border-radius:4px;word-wrap:break-word;padding:1em;font-size:.8125em} +.literalblock pre.nowrap,.literalblock pre[class].nowrap,.listingblock pre.nowrap,.listingblock pre[class].nowrap{overflow-x:auto;white-space:pre;word-wrap:normal} +@media only screen and (min-width:768px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:.90625em}}@media only screen and (min-width:1280px){.literalblock pre,.literalblock pre[class],.listingblock pre,.listingblock pre[class]{font-size:1em}}.literalblock.output pre{color:#f7f7f8;background-color:rgba(0,0,0,.9)} +.listingblock pre.highlightjs{padding:0} +.listingblock pre.highlightjs>code{padding:1em;-webkit-border-radius:4px;border-radius:4px} +.listingblock pre.prettyprint{border-width:0} +.listingblock>.content{position:relative} +.listingblock code[data-lang]:before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:#999} +.listingblock:hover code[data-lang]:before{display:block} +.listingblock.terminal pre .command:before{content:attr(data-prompt);padding-right:.5em;color:#999} +.listingblock.terminal pre .command:not([data-prompt]):before{content:"$"} +table.pyhltable{border-collapse:separate;border:0;margin-bottom:0;background:none} +table.pyhltable td{vertical-align:top;padding-top:0;padding-bottom:0} +table.pyhltable td.code{padding-left:.75em;padding-right:0} +pre.pygments .lineno,table.pyhltable td:not(.code){color:#999;padding-left:0;padding-right:.5em;border-right:1px solid #ddddd8} +pre.pygments .lineno{display:inline-block;margin-right:.25em} +table.pyhltable .linenodiv{background:none!important;padding-right:0!important} +.quoteblock{margin:0 1em 1.25em 1.5em;display:table} +.quoteblock>.title{margin-left:-1.5em;margin-bottom:.75em} +.quoteblock blockquote,.quoteblock blockquote p{color:rgba(0,0,0,.85);font-size:1.15rem;line-height:1.75;word-spacing:.1em;letter-spacing:0;font-style:italic;text-align:justify} +.quoteblock blockquote{margin:0;padding:0;border:0} +.quoteblock blockquote:before{content:"\201c";float:left;font-size:2.75em;font-weight:bold;line-height:.6em;margin-left:-.6em;color:#7a2518;text-shadow:0 1px 2px rgba(0,0,0,.1)} +.quoteblock blockquote>.paragraph:last-child p{margin-bottom:0} +.quoteblock .attribution{margin-top:.5em;margin-right:.5ex;text-align:right} +.quoteblock .quoteblock{margin-left:0;margin-right:0;padding:.5em 0;border-left:3px solid rgba(0,0,0,.6)} +.quoteblock .quoteblock blockquote{padding:0 0 0 .75em} +.quoteblock .quoteblock blockquote:before{display:none} +.verseblock{margin:0 1em 1.25em 1em} +.verseblock pre{font-family:"Open Sans","DejaVu Sans",sans;font-size:1.15rem;color:rgba(0,0,0,.85);font-weight:300;text-rendering:optimizeLegibility} +.verseblock pre strong{font-weight:400} +.verseblock .attribution{margin-top:1.25rem;margin-left:.5ex} +.quoteblock .attribution,.verseblock .attribution{font-size:.9375em;line-height:1.45;font-style:italic} +.quoteblock .attribution br,.verseblock .attribution br{display:none} +.quoteblock .attribution cite,.verseblock .attribution cite{display:block;letter-spacing:-.05em;color:rgba(0,0,0,.6)} +.quoteblock.abstract{margin:0 0 1.25em 0;display:block} +.quoteblock.abstract blockquote,.quoteblock.abstract blockquote p{text-align:left;word-spacing:0} +.quoteblock.abstract blockquote:before,.quoteblock.abstract blockquote p:first-of-type:before{display:none} +table.tableblock{max-width:100%;border-collapse:separate} +table.tableblock td>.paragraph:last-child p>p:last-child,table.tableblock th>p:last-child,table.tableblock td>p:last-child{margin-bottom:0} +table.spread{width:100%} +table.tableblock,th.tableblock,td.tableblock{border:0 solid #dedede} +table.grid-all th.tableblock,table.grid-all td.tableblock{border-width:0 1px 1px 0} +table.grid-all tfoot>tr>th.tableblock,table.grid-all tfoot>tr>td.tableblock{border-width:1px 1px 0 0} +table.grid-cols th.tableblock,table.grid-cols td.tableblock{border-width:0 1px 0 0} +table.grid-all *>tr>.tableblock:last-child,table.grid-cols *>tr>.tableblock:last-child{border-right-width:0} +table.grid-rows th.tableblock,table.grid-rows td.tableblock{border-width:0 0 1px 0} +table.grid-all tbody>tr:last-child>th.tableblock,table.grid-all tbody>tr:last-child>td.tableblock,table.grid-all thead:last-child>tr>th.tableblock,table.grid-rows tbody>tr:last-child>th.tableblock,table.grid-rows tbody>tr:last-child>td.tableblock,table.grid-rows thead:last-child>tr>th.tableblock{border-bottom-width:0} +table.grid-rows tfoot>tr>th.tableblock,table.grid-rows tfoot>tr>td.tableblock{border-width:1px 0 0 0} +table.frame-all{border-width:1px} +table.frame-sides{border-width:0 1px} +table.frame-topbot{border-width:1px 0} +th.halign-left,td.halign-left{text-align:left} +th.halign-right,td.halign-right{text-align:right} +th.halign-center,td.halign-center{text-align:center} +th.valign-top,td.valign-top{vertical-align:top} +th.valign-bottom,td.valign-bottom{vertical-align:bottom} +th.valign-middle,td.valign-middle{vertical-align:middle} +table thead th,table tfoot th{font-weight:bold} +tbody tr th{display:table-cell;line-height:1.6;background:#f7f8f7} +tbody tr th,tbody tr th p,tfoot tr th,tfoot tr th p{color:rgba(0,0,0,.8);font-weight:bold} +p.tableblock>code:only-child{background:none;padding:0} +p.tableblock{font-size:1em} +td>div.verse{white-space:pre} +ol{margin-left:1.75em} +ul li ol{margin-left:1.5em} +dl dd{margin-left:1.125em} +dl dd:last-child,dl dd:last-child>:last-child{margin-bottom:0} +ol>li p,ul>li p,ul dd,ol dd,.olist .olist,.ulist .ulist,.ulist .olist,.olist .ulist{margin-bottom:.625em} +ul.unstyled,ol.unnumbered,ul.checklist,ul.none{list-style-type:none} +ul.unstyled,ol.unnumbered,ul.checklist{margin-left:.625em} +ul.checklist li>p:first-child>.fa-check-square-o:first-child,ul.checklist li>p:first-child>input[type="checkbox"]:first-child{margin-right:.25em} +ul.checklist li>p:first-child>input[type="checkbox"]:first-child{position:relative;top:1px} +ul.inline{margin:0 auto .625em auto;margin-left:-1.375em;margin-right:0;padding:0;list-style:none;overflow:hidden} +ul.inline>li{list-style:none;float:left;margin-left:1.375em;display:block} +ul.inline>li>*{display:block} +.unstyled dl dt{font-weight:400;font-style:normal} +ol.arabic{list-style-type:decimal} +ol.decimal{list-style-type:decimal-leading-zero} +ol.loweralpha{list-style-type:lower-alpha} +ol.upperalpha{list-style-type:upper-alpha} +ol.lowerroman{list-style-type:lower-roman} +ol.upperroman{list-style-type:upper-roman} +ol.lowergreek{list-style-type:lower-greek} +.hdlist>table,.colist>table{border:0;background:none} +.hdlist>table>tbody>tr,.colist>table>tbody>tr{background:none} +td.hdlist1{padding-right:.75em;font-weight:bold} +td.hdlist1,td.hdlist2{vertical-align:top} +.literalblock+.colist,.listingblock+.colist{margin-top:-.5em} +.colist>table tr>td:first-of-type{padding:0 .75em;line-height:1} +.colist>table tr>td:last-of-type{padding:.25em 0} +.thumb,.th{line-height:0;display:inline-block;border:solid 4px #fff;-webkit-box-shadow:0 0 0 1px #ddd;box-shadow:0 0 0 1px #ddd} +.imageblock.left,.imageblock[style*="float: left"]{margin:.25em .625em 1.25em 0} +.imageblock.right,.imageblock[style*="float: right"]{margin:.25em 0 1.25em .625em} +.imageblock>.title{margin-bottom:0} +.imageblock.thumb,.imageblock.th{border-width:6px} +.imageblock.thumb>.title,.imageblock.th>.title{padding:0 .125em} +.image.left,.image.right{margin-top:.25em;margin-bottom:.25em;display:inline-block;line-height:0} +.image.left{margin-right:.625em} +.image.right{margin-left:.625em} +a.image{text-decoration:none} +span.footnote,span.footnoteref{vertical-align:super;font-size:.875em} +span.footnote a,span.footnoteref a{text-decoration:none} +span.footnote a:active,span.footnoteref a:active{text-decoration:underline} +#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em} +#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em 0;border-width:1px 0 0 0} +#footnotes .footnote{padding:0 .375em;line-height:1.3;font-size:.875em;margin-left:1.2em;text-indent:-1.2em;margin-bottom:.2em} +#footnotes .footnote a:first-of-type{font-weight:bold;text-decoration:none} +#footnotes .footnote:last-of-type{margin-bottom:0} +#content #footnotes{margin-top:-.625em;margin-bottom:0;padding:.75em 0} +.gist .file-data>table{border:0;background:#fff;width:100%;margin-bottom:0} +.gist .file-data>table td.line-data{width:99%} +div.unbreakable{page-break-inside:avoid} +.big{font-size:larger} +.small{font-size:smaller} +.underline{text-decoration:underline} +.overline{text-decoration:overline} +.line-through{text-decoration:line-through} +.aqua{color:#00bfbf} +.aqua-background{background-color:#00fafa} +.black{color:#000} +.black-background{background-color:#000} +.blue{color:#0000bf} +.blue-background{background-color:#0000fa} +.fuchsia{color:#bf00bf} +.fuchsia-background{background-color:#fa00fa} +.gray{color:#606060} +.gray-background{background-color:#7d7d7d} +.green{color:#006000} +.green-background{background-color:#007d00} +.lime{color:#00bf00} +.lime-background{background-color:#00fa00} +.maroon{color:#600000} +.maroon-background{background-color:#7d0000} +.navy{color:#000060} +.navy-background{background-color:#00007d} +.olive{color:#606000} +.olive-background{background-color:#7d7d00} +.purple{color:#600060} +.purple-background{background-color:#7d007d} +.red{color:#bf0000} +.red-background{background-color:#fa0000} +.silver{color:#909090} +.silver-background{background-color:#bcbcbc} +.teal{color:#006060} +.teal-background{background-color:#007d7d} +.white{color:#bfbfbf} +.white-background{background-color:#fafafa} +.yellow{color:#bfbf00} +.yellow-background{background-color:#fafa00} +span.icon>.fa{cursor:default} +.admonitionblock td.icon [class^="fa icon-"]{font-size:2.5em;text-shadow:1px 1px 2px rgba(0,0,0,.5);cursor:default} +.admonitionblock td.icon .icon-note:before{content:"\f05a";color:#19407c} +.admonitionblock td.icon .icon-tip:before{content:"\f0eb";text-shadow:1px 1px 2px rgba(155,155,0,.8);color:#111} +.admonitionblock td.icon .icon-warning:before{content:"\f071";color:#bf6900} +.admonitionblock td.icon .icon-caution:before{content:"\f06d";color:#bf3400} +.admonitionblock td.icon .icon-important:before{content:"\f06a";color:#bf0000} +.conum[data-value]{display:inline-block;color:#fff!important;background-color:rgba(0,0,0,.8);-webkit-border-radius:100px;border-radius:100px;text-align:center;font-size:.75em;width:1.67em;height:1.67em;line-height:1.67em;font-family:"Open Sans","DejaVu Sans",sans-serif;font-style:normal;font-weight:bold} +.conum[data-value] *{color:#fff!important} +.conum[data-value]+b{display:none} +.conum[data-value]:after{content:attr(data-value)} +pre .conum[data-value]{position:relative;top:-.125em} +b.conum *{color:inherit!important} +.conum:not([data-value]):empty{display:none} +h1,h2{letter-spacing:-.01em} +dt,th.tableblock,td.content{text-rendering:optimizeLegibility} +p,td.content{letter-spacing:-.01em} +p strong,td.content strong{letter-spacing:-.005em} +p,blockquote,dt,td.content{font-size:1.0625rem} +p{margin-bottom:1.25rem} +.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em} +.exampleblock>.content{background-color:#fffef7;border-color:#e0e0dc;-webkit-box-shadow:0 1px 4px #e0e0dc;box-shadow:0 1px 4px #e0e0dc} +.print-only{display:none!important} +@media print{@page{margin:1.25cm .75cm} +*{-webkit-box-shadow:none!important;box-shadow:none!important;text-shadow:none!important} +a{color:inherit!important;text-decoration:underline!important} +a.bare,a[href^="#"],a[href^="mailto:"]{text-decoration:none!important} +a[href^="http:"]:not(.bare):after,a[href^="https:"]:not(.bare):after{content:"(" attr(href) ")";display:inline-block;font-size:.875em;padding-left:.25em} +abbr[title]:after{content:" (" attr(title) ")"} +pre,blockquote,tr,img{page-break-inside:avoid} +thead{display:table-header-group} +img{max-width:100%!important} +p,blockquote,dt,td.content{font-size:1em;orphans:3;widows:3} +h2,h3,#toctitle,.sidebarblock>.content>.title{page-break-after:avoid} +#toc,.sidebarblock,.exampleblock>.content{background:none!important} +#toc{border-bottom:1px solid #ddddd8!important;padding-bottom:0!important} +.sect1{padding-bottom:0!important} +.sect1+.sect1{border:0!important} +#header>h1:first-child{margin-top:1.25rem} +body.book #header{text-align:center} +body.book #header>h1:first-child{border:0!important;margin:2.5em 0 1em 0} +body.book #header .details{border:0!important;display:block;padding:0!important} +body.book #header .details span:first-child{margin-left:0!important} +body.book #header .details br{display:block} +body.book #header .details br+span:before{content:none!important} +body.book #toc{border:0!important;text-align:left!important;padding:0!important;margin:0!important} +body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-break-before:always} +.listingblock code[data-lang]:before{display:block} +#footer{background:none!important;padding:0 .9375em} +#footer-text{color:rgba(0,0,0,.6)!important;font-size:.9em} +.hide-on-print{display:none!important} +.print-only{display:block!important} +.hide-for-print{display:none!important} +.show-for-print{display:inherit!important}} \ No newline at end of file diff --git a/build.gradle b/build.gradle index 53eb33d85b..a59ec6dd9b 100644 --- a/build.gradle +++ b/build.gradle @@ -2,47 +2,31 @@ buildscript { repositories { mavenCentral() mavenLocal() + maven { url 'https://repo.spring.io/plugins-release' } if (project.hasProperty('fatJar')) jcenter() } dependencies { - classpath "pl.allegro.tech.build:axion-release-plugin:1.3.2" 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' } } -apply plugin: "pl.allegro.tech.build.axion-release" - -scmVersion { - tag { prefix = "accurest" } - createReleaseCommit = true - releaseCommitMessage { version, position -> "Release version: ${version}\n\n[ci skip]" } - hooks { - pre "fileUpdate", [file : "README.md", - pattern : { v, p -> /'io\.codearte\.accurest:accurest-gradle-plugin:.*'/ }, - replacement: { v, p -> "'io.codearte.accurest:accurest-gradle-plugin:$v'" }] - } +ext { + repoUser = project.findProperty('REPO_USERNAME') ?: '' + repoPass = project.findProperty('REPO_PASSWORD') ?: '' + projectsToSkipPublication = ['parent', 'samples', 'docs', 'root'] } allprojects { - project.version = scmVersion.version + project.version = findProperty('contractVerifierVersion') ?: '1.0.0.BUILD-SNAPSHOT' + apply from: "$rootDir/gradle/release.gradle" } -apply plugin: 'io.codearte.nexus-staging' - -nexusStaging { - packageGroup = "io.codearte" - stagingProfileId = '93c08fdebde1ff' -} - -apply from: "$rootDir/gradle/releaseRoot.gradle" - subprojects { apply plugin: 'groovy' - apply from: "$rootDir/gradle/release.gradle" - group = 'io.codearte.accurest' + group = 'org.springframework.cloud.contract' sourceCompatibility = 1.7 targetCompatibility = 1.7 @@ -51,9 +35,10 @@ subprojects { mavenLocal() mavenCentral() jcenter() - maven { - url "http://repo.spring.io/milestone" - } + maven { url "http://repo.spring.io/snapshot" } + maven { url "http://repo.spring.io/milestone" } + maven { url "http://repo.spring.io/libs-release-local" } + maven { url "http://repo.spring.io/libs-staging-local/" } } //Dependencies in all subprojects - http://solidsoft.wordpress.com/2014/11/13/gradle-tricks-display-dependencies-for-all-subprojects-in-multi-project-build/ @@ -87,106 +72,6 @@ subprojects { } } -project(':accurest-core') { - - dependencies { - compile 'org.slf4j:slf4j-api:1.6.0' - compile 'commons-io:commons-io:2.0' - compile 'org.apache.commons:commons-lang3:3.3' - compile "com.github.tomakehurst:wiremock:$wiremockVersion" - compile "com.toomuchcoding.jsonassert:jsonassert:$jsonassertVersion" - compile 'org.codehaus.groovy:groovy-all:2.4.4' - testCompile 'cglib:cglib-nodep:2.2' - testCompile 'org.objenesis:objenesis:2.1' - testCompile project(':accurest-testing-utils') - } - -} - -project(':accurest-testing-utils') { - - dependencies { - compile 'org.skyscreamer:jsonassert:1.2.3' - } - -} - -project(':accurest-converters') { - dependencies { - compile project(':accurest-core') - compile 'org.apache.commons:commons-lang3:3.0' - compile 'commons-io:commons-io:2.0' - compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger - testCompile "com.github.tomakehurst:wiremock:$wiremockVersion" - testCompile 'org.hamcrest:hamcrest-all:1.3' - } -} - -project(':accurest-gradle-plugin') { - - ext.messagingLibsDir ="$buildDir/messaging-libs" - ext.accurestGradlePluginLibsDir ="$buildDir/accurest-gradle-plugin-libs" - - ext.testSystemProperties = [ - 'accurest-gradle-plugin-libs-dir': accurestGradlePluginLibsDir, - 'messaging-libs-dir': messagingLibsDir - ] - - dependencies { - compile project(':accurest-core') - compile project(':accurest-converters') - compile gradleApi() - - testCompile gradleTestKit() - testCompile project(':accurest-testing-utils') - } - - configurations { - messagingLibs - accurestGradlePluginLibs - } - - dependencies { - messagingLibs project(':accurest-messaging-root:accurest-messaging-integration') - messagingLibs project(':accurest-messaging-root:accurest-messaging-core') - messagingLibs project(':accurest-testing-utils') - messagingLibs 'org.codehaus.groovy:groovy-all:2.4.5' - - accurestGradlePluginLibs project(':accurest-gradle-plugin') - } - - test { - exclude '**/*FunctionalSpec.*' - systemProperties = testSystemProperties - } - task funcTest(type: Test) { - include '**/*FunctionalSpec.*' - systemProperties = testSystemProperties - reports.html { - destination = file("${reporting.baseDir}/funcTests") - } - } - - task archiveMessagingLibsDependencies(type: Sync) { - from configurations.messagingLibs.resolvedConfiguration.resolvedArtifacts.collect { it.file } - into messagingLibsDir - } - - task archiveAccurestGradlePluginLibsDependencies(type: Sync) { - from configurations.accurestGradlePluginLibs.resolvedConfiguration.resolvedArtifacts.collect { it.file } - into accurestGradlePluginLibsDir - } - - // archive task needs to have jars ready - archiveMessagingLibsDependencies.dependsOn project(':accurest-messaging-root:accurest-messaging-integration').tasks.jar - archiveAccurestGradlePluginLibsDependencies.dependsOn project(':accurest-gradle-plugin').tasks.jar - - test.dependsOn archiveMessagingLibsDependencies, archiveAccurestGradlePluginLibsDependencies - funcTest.dependsOn archiveMessagingLibsDependencies, archiveAccurestGradlePluginLibsDependencies - - uploadArchives.dependsOn { funcTest } -} - configurations { all { resolutionStrategy { @@ -201,17 +86,3 @@ configurations { } } -// REMOVE AFTER https://issues.gradle.org/browse/GRADLE-3433 IS FIXED -buildscript { - repositories { - maven { - url "https://plugins.gradle.org/m2/" - } - } - dependencies { - classpath "gradle.plugin.com.palantir.ideatestfix:gradle-idea-test-fix:0.1.0" - } -} - -apply plugin: "com.palantir.idea-test-fix" - diff --git a/docs/build.gradle b/docs/build.gradle index 49f23f96d9..36a6fbf2b8 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -1,14 +1,53 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + plugins { id 'org.ajoberstar.github-pages' version '1.1.0' id 'org.asciidoctor.gradle.asciidoctor' version '1.5.1' id 'org.asciidoctor.convert' version '1.5.3' + id 'com.github.jruby-gradle.base' version '1.2.1' +} + + +apply plugin: 'org.asciidoctor.gradle.asciidoctor' +apply plugin: 'com.github.jruby-gradle.base' + +dependencies { + gems group: 'rubygems', name: 'asciidoctor', version: '1.5.3' } asciidoctorj { version = '1.5.4' } +task generateReadme(type: com.github.jrubygradle.JRubyExec) { + dependsOn jrubyPrepare + + description "Generates an output README.adoc" + script "${projectDir}/src/main/ruby/generate_readme.sh" + scriptArgs "-o${new File(project.rootDir, 'README.adoc')}" + gemWorkDir jrubyPrepare.outputDir +} + asciidoctor { + dependsOn jrubyPrepare + + sourceDir 'src/main/asciidoc' + setSourceDocumentName file('spring-cloud-contract-verifier.adoc') + backends 'html' attributes 'build-gradle': file('build.gradle'), 'endpoint-url': 'https://Codearte.github.io/accurest', 'source-highlighter': 'coderay', @@ -18,9 +57,13 @@ asciidoctor { 'setanchors': 'true', 'idprefix': '', 'idseparator': '-', - 'docinfo1': 'true' + 'docinfo1': 'true', + 'doctype' : 'article' + + gemPath = jrubyPrepare.outputDir } +generateReadme.dependsOn asciidoctor publishGhPages.dependsOn asciidoctor githubPages { diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc deleted file mode 100644 index 3e3dc3a980..0000000000 --- a/docs/src/docs/asciidoc/index.adoc +++ /dev/null @@ -1,19 +0,0 @@ -:messaging_version: 1.1.0 - -= Accurest - -_Adam Dudczak, Marcin Grzejszczak, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła_ - -include::introduction.adoc[] - -include::contract.adoc[] - -include::rest.adoc[] - -include::messaging.adoc[] - -include::stubrunner.adoc[] - -include::stubrunner_msg.adoc[] - -include::migration.adoc[] \ No newline at end of file diff --git a/docs/src/docs/asciidoc/messaging.adoc b/docs/src/docs/asciidoc/messaging.adoc deleted file mode 100644 index d6946f16ae..0000000000 --- a/docs/src/docs/asciidoc/messaging.adoc +++ /dev/null @@ -1,148 +0,0 @@ -== Accurest Messaging - -WARNING: Feature available since {messaging_version} - -Accurest allows you to verify your application that uses messaging as means of communication. -All of our integrations are working with Spring but you can also set one yourself. - -=== Integrations - -You can use one of the three integration configurations: - -- Apache Camel -- Spring Integration -- Spring Cloud Stream - -If you're using Spring Boot, the aforementioned test configurations will be appended automatically. - -You have to provide as a dependency one of the Accurest Messaging modules. Example for Gradle: - -[source,groovy,indent=0] ----- -// for Apache Camel -testCompile "io.codearte.accurest:accurest-messaging-camel:${accurestVersion}" -// for Spring Integration -testCompile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}" -// for Spring Cloud Stream -testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}" ----- - -=== Manual Integration - -The `accurest-messaging-core` module contains 3 main interfaces: - -- `AccurestMessage` - describes a message received / sent to a channel / queue / topic etc. -- `AccurestMessageBuilder` - describes how to build a message -- `AccurestMessaging` - class that allows you to build, send and receive messages -- `AccurestFilter` - interface to filter out the messages that do not follow the pattern from the DSL - -In the generated test the `AccurestMessaging` is injected via `@Inject` annotation thus you can use other injection -frameworks than Spring. - -You have to provide as a dependency the `accurest-messaging-core` module. Example for Gradle: - -[source,groovy,indent=0] ----- -testCompile "io.codearte.accurest:accurest-messaging-core:${accurestVersion}" ----- - -=== Publisher side test generation - -Having the `input` or `outputMessage` sections in your DSL will result in creation of tests on the publisher's side. By default -JUnit tests will be created, however there is also a possibility to create Spock tests. - -There are 3 main scenarios that we should take into consideration: - -- Scenario 1: there is no input message that produces an output one. The output message is triggered by a component -inside the application (e.g. scheduler) -- Scenario 2: the input message triggers an output message -- Scenario 3: the input message is consumed and there is no output message - -==== Scenario 1 (no input message) - -For the given contract: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl] ----- - -The following JUnit test will be created: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_junit_test] ----- - -And the following Spock test would be created: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_test] ----- - -==== Scenario 2 (output triggered by input) - -For the given contract: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_dsl] ----- - -The following JUnit test will be created: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_junit] ----- - -And the following Spock test would be created: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_spock] ----- - -==== Scenario 3 (no output message) - -For the given contract: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_dsl] ----- - -The following JUnit test will be created: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_junit] ----- - -And the following Spock test would be created: - -[source,groovy] ----- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_spock] ----- - -=== Consumer Stub Side generation - -Unlike the HTTP part - in Messaging we need to publish the Groovy DSL inside the JAR with a stub. Then it's parsed on the consumer side -and proper stubbed routes are created. - -For more infromation please consult the Stub Runner Messaging sections. - -==== Gradle Setup - -Example of Accurest Gradle setup: - -[source,groovy,indent=0] ----- -include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=jar_setup,indent=0] ----- - -==== Maven Setup - -Example of Maven can be found in the https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar[Accurest Maven Plugin README] diff --git a/docs/src/docs/asciidoc/migration.adoc b/docs/src/docs/asciidoc/migration.adoc deleted file mode 100644 index 98e1215e9a..0000000000 --- a/docs/src/docs/asciidoc/migration.adoc +++ /dev/null @@ -1,23 +0,0 @@ -== Migration Guide - -=== Migration to 0.4.7 -- in 0.4.7 we've fixed package name (coderate to codearte) so you've to do the same in your projects. This means replacing ```io.coderate.accurest.dsl.GroovyDsl``` with ```io.codearte.accurest.dsl.GroovyDsl``` - -=== Migration to 1.0.0-RC1 -- from 1.0.0 we're distinguish ignored contracts from excluded contracts: - - `excludedFiles` pattern tells Accurest to skip processing those files at all - - `ignoredFiles` pattern tells Accurest to generate contracts and tests, but tests will be marked as `@Ignore` - -- from 1.0.0 the `basePackageForTests` behaviour has changed - - prior to the change all DSL files had to be under `contractsDslDir`/`basePackageForTests`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - - now all DSL files have to be under `contractsDslDir`/*subpackage* resulting in `basePackageForTests`.*subpackage* test package creation - - If you don't migrate to the new approach you will have your tests under `contractsDslDir`.`contractsDslDir`.*subpackage* - -=== Migration to {messaging_version} -- from {messaging_version} we're setting JUnit as a default testing utility. You have to pass the following option to keep Spock -as your first choice: - -[source,groovy] ----- -include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=target_framework,indent=0] ----- \ No newline at end of file diff --git a/docs/src/docs/asciidoc/stubrunner_msg.adoc b/docs/src/docs/asciidoc/stubrunner_msg.adoc deleted file mode 100644 index 28f31d6211..0000000000 --- a/docs/src/docs/asciidoc/stubrunner_msg.adoc +++ /dev/null @@ -1,58 +0,0 @@ -== Stub Runner for Messaging - -WARNING: Feature available since {messaging_version} - -Stub Runner has the functionality to run the published stubs in memory. It can integrate with the following frameworks out of the box - -- Spring Integration -- Spring Cloud Stream -- Apache Camel - -It also provides points of entry to integrate with any other solution on the market. - -=== Stub triggering - -To trigger a message it's enough to use the `StubTigger` interface: - -[source,groovy] ----- -include::../../../../stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy[] ----- - -For convenience the `StubFinder` interface extends `StubTrigger` so it's enough to use only one in your tests. - -`StubTrigger` gives you the following options to trigger a message: - -==== Trigger by label - -[source,groovy] ----- -include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger,indent=0] ----- - -===== Trigger by group and artifact ids - -[source,groovy] ----- -include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] ----- - -===== Trigger by artifact ids - -[source,groovy] ----- -include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] ----- - -===== Trigger all messages - -[source,groovy] ----- -include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_all,indent=0] ----- - -include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc[] - -include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc[] - -include::../../../../stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc[] \ No newline at end of file diff --git a/docs/src/main/asciidoc/README.adoc b/docs/src/main/asciidoc/README.adoc new file mode 100644 index 0000000000..1a31f6af8e --- /dev/null +++ b/docs/src/main/asciidoc/README.adoc @@ -0,0 +1,17 @@ +:core_path: ../../../.. +:verifier_root_path: {core_path}/spring-cloud-contract-verifier +:verifier_core_path: {verifier_root_path}/spring-cloud-contract-verifier-core +:stubrunner_core_path: {core_path}/spring-cloud-contract-stub-runner +:documentation_url: http://codearte.github.io/accurest + += Spring Cloud Contract Verifier + +include::introduction.adoc[] + +== Documentation + +You can read more about Spring Cloud Contract Verifier by reading the {documentation_url}[docs] + +== Contributing + +include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[] diff --git a/docs/src/docs/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc similarity index 56% rename from docs/src/docs/asciidoc/contract.adoc rename to docs/src/main/asciidoc/contract.adoc index ad8c58b3f3..19e6be35f3 100644 --- a/docs/src/docs/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -1,27 +1,29 @@ +:core_path: ../../../.. +:verifier_root_path: {core_path}/spring-cloud-contract-verifier +:verifier_core_path: {verifier_root_path}/spring-cloud-contract-verifier-core + == Contract DSL -Contract DSL in Accurest is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only -a tiny subset of it (namely literals, method calls and closures). What's more, Accurest's DSL is designed to be programmer-readable without any knowledge of the DSL itself - +Contract DSL is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only +a tiny subset of it (namely literals, method calls and closures). What's more the DSL is designed to be programmer-readable without any knowledge of the DSL itself - it's statically typed. -TIP: Since {messaging_version} you can use the `io.codearte.accurest.dsl.Accurest` class in your DSL files. - Let's look at full example of a contract definition. [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy[tags=dsl_example,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy[tags=dsl_example,indent=0] ---- Not all features of the DSL are used in example above. If you didn't find what you are looking for, please check next paragraphs on this page. -> You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: `mvn io.codearte.accurest:accurest-maven-plugin:convert`. +> You can easily compile Contracts to WireMock stubs mapping using standalone maven command: `mvn org.springframework.cloud.contract:spring-cloud-contract-verifier-maven-plugin:convert`. === Limitations -WARNING: Accurest doesn't support XML properly. Please use JSON or help us implement this feature. +WARNING: Spring Cloud Contract Verifier doesn't support XML properly. Please use JSON or help us implement this feature. -WARNING: Accurest supports equality check on text response. Regular expressions are not yet available. +WARNING: Spring Cloud Contract Verifier supports equality check on text response. Regular expressions are not yet available. === HTTP Top-Level Elements @@ -29,23 +31,23 @@ Following methods can be called in the top-level closure of a contract definitio [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=http_dsl,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=http_dsl,indent=0] ---- === Request -HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of Accurest contract. +HTTP protocol requires only **method and address** to be specified in a request. The same information is mandatory in request definition of the Contract. [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=request,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=request,indent=0] ---- It is possible to specify whole `url` instead of just path, but `urlPath` is the recommended way as it makes the tests **host-independent**. [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=url,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=url,indent=0] ---- @@ -53,28 +55,28 @@ Request may contain **query parameters**, which are specified in a closure neste [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=urlpath,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=urlpath,indent=0] ---- It may contain additional **request headers**... [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=headers,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=headers,indent=0] ---- ...and a **request body**. [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=body,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=body,indent=0] ---- **Body's format** can also be specified explicitly by invoking one of format functions. [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=bodyAsXml,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=bodyAsXml,indent=0] ---- === Response @@ -83,7 +85,7 @@ Minimal response must contain **HTTP status code**. [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=response,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=response,indent=0] ---- Besides status response may contain **headers** and **body**, which are specified the same way as in the request (see previous paragraph). @@ -97,7 +99,7 @@ Please see the example below: [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=regex,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=regex,indent=0] ---- === Passing optional parameters @@ -111,7 +113,7 @@ Example: [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=optionals,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=optionals,indent=0] ---- By wrapping a part of the body with the `optional()` method you are in fact creating a regular expression that should be present 0 or more times. @@ -120,14 +122,14 @@ That way for the example above the following test would be generated if you pick [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=optionals_test,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=optionals_test,indent=0] ---- and the following stub: [source,javascript,indent=0] ---- -include::../../../../accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverterSpec.groovy[tags=wiremock,indent=0] +include::{verifier_root_path}/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy[tags=wiremock,indent=0] ---- === Executing custom methods on server side @@ -138,14 +140,14 @@ in the configuration. Please see the examples below: [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy[tags=method,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy[tags=method,indent=0] ---- ==== Base Mock Spec [source,groovy,indent=0] ---- -include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] +include::{verifier_root_path}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] ---- === JAX-RS support @@ -164,13 +166,11 @@ Example of a test API generated: [source,groovy,indent=0] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy[tags=jaxrs,indent=0] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy[tags=jaxrs,indent=0] ---- === Messaging Top-Level Elements -WARNING: Feature available since {messaging_version} - The DSL for messaging looks a little bit different than the one that focuses on HTTP. ==== Output triggered by a method @@ -179,7 +179,7 @@ The output message can be triggered by calling a method (e.g. a Scheduler was st [source,groovy] ---- -include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=method_trigger,indent=0] +include::../../../../samples/messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=method_trigger,indent=0] ---- In this case the output message will be sent to `output` if a method called `bookReturnedTriggered` will be executed. In the message *publisher's* side @@ -191,7 +191,7 @@ The output message can be triggered by receiving a message. [source,groovy] ---- -include::../../../../samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=message_trigger,indent=0] +include::../../../../samples/messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=message_trigger,indent=0] ---- In this case the output message will be sent to `output` if a proper message will be received on the `input` destination. In the message *publisher's* side @@ -205,5 +205,5 @@ as presented below (note you can use either `$` or `value` methods to provide `c [source,groovy] ---- -include::../../../../accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy[tags=consumer_producer] +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=consumer_producer] ---- \ No newline at end of file diff --git a/docs/src/docs/asciidoc/images/Deps.png b/docs/src/main/asciidoc/images/Deps.png similarity index 100% rename from docs/src/docs/asciidoc/images/Deps.png rename to docs/src/main/asciidoc/images/Deps.png diff --git a/docs/src/docs/asciidoc/images/Stubs1.png b/docs/src/main/asciidoc/images/Stubs1.png similarity index 100% rename from docs/src/docs/asciidoc/images/Stubs1.png rename to docs/src/main/asciidoc/images/Stubs1.png diff --git a/docs/src/docs/asciidoc/images/Stubs2.png b/docs/src/main/asciidoc/images/Stubs2.png similarity index 100% rename from docs/src/docs/asciidoc/images/Stubs2.png rename to docs/src/main/asciidoc/images/Stubs2.png diff --git a/docs/src/main/asciidoc/index.adoc b/docs/src/main/asciidoc/index.adoc new file mode 120000 index 0000000000..28dc0a7e0c --- /dev/null +++ b/docs/src/main/asciidoc/index.adoc @@ -0,0 +1 @@ +spring-cloud-contract-verifier.adoc \ No newline at end of file diff --git a/docs/src/docs/asciidoc/introduction.adoc b/docs/src/main/asciidoc/introduction.adoc similarity index 77% rename from docs/src/docs/asciidoc/introduction.adoc rename to docs/src/main/asciidoc/introduction.adoc index 08f45e5fa9..95c9b1f58f 100644 --- a/docs/src/docs/asciidoc/introduction.adoc +++ b/docs/src/main/asciidoc/introduction.adoc @@ -1,14 +1,15 @@ == Introduction -Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped -with __Contract Definition Language__ (DSL). Contract definitions are used by Accurest to produce following resources: +Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped +with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: * JSON stub definitions to be used by Wiremock when doing integration testing on the client code (__client tests__). -Test code must still be written by hand, test data is produced by Accurest. +Test code must still be written by hand, test data is produced by Spring Cloud Contract Verifier. * Messaging routes if you're using one. We're integrating with Spring Integration, Spring Cloud Stream and Apache Camel. You can however set your own integrations if you want to -* Acceptance tests (in JUnit or Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). Full test is generated by Accurest. +* Acceptance tests (in JUnit or Spock) used to verify if server-side implementation of the API is compliant with the contract (__server tests__). +Full test is generated by Spring Cloud Contract Verifier. -Accurest moves TDD to the level of software architecture. +Spring Cloud Contract Verifier moves TDD to the level of software architecture. === Why? @@ -52,7 +53,7 @@ Disadvantages: - the implementor of the service creates stubs thus they might have nothing to do with the reality - you can go to production with passing tests and failing production -To solve the aforementioned issues Accurest with Stub Runner were created. Their main idea is to give you very fast feedback, without the need +To solve the aforementioned issues Spring Cloud Contract Verifier with Stub Runner were created. Their main idea is to give you very fast feedback, without the need to set up the whole world of microservices. image::Stubs1.png[Stubbed Services] @@ -61,13 +62,13 @@ If you work on stubs then the only applications you need are those that your app image::Stubs2.png[Stubbed Services] -Accurest gives you the certainty that the stubs that you're using were created by the service that you're calling. Also if you can use them it means that they were +Spring Cloud Contract Verifier gives you the certainty that the stubs that you're using were created by the service that you're calling. Also if you can use them it means that they were tested against the producer's side. In other words - you can trust those stubs. === Purposes -The main purposes of Accurest with Stub Runner are: +The main purposes of Spring Cloud Contract Verifier with Stub Runner are: - to ensure that WireMock / Messaging stubs (used when developing the client) are doing exactly what actual server-side implementation will do, - to promote ATDD method and Microservices architectural style, @@ -97,7 +98,7 @@ for response verification. === Dependencies -Accurest and Stub Runner are using the following libraries +Spring Cloud Contract Verifier and Stub Runner are using the following libraries - http://wiremock.org/[WireMock] - https://github.com/jayway/JsonPath[Jayway JSONPath] @@ -105,16 +106,16 @@ Accurest and Stub Runner are using the following libraries === Additional links -Below you can find some resources related to Accurest and Stub Runner. Note that some can be outdated since the Accurest project +Below you can find some resources related to Spring Cloud Contract Verifier and Stub Runner. Note that some can be outdated since the Spring Cloud Contract Verifier project is under constant development. ==== Videos -*Olga Maciaszek-Sharma talking about Accurest* +*Olga Maciaszek-Sharma talking about Accurest (Spring Cloud Contract Verifier predecessor)* video::daafmTYFoDU[youtube] -*Marcin Grzejszczak and Jakub Kubryński talking about Accurest* +*Marcin Grzejszczak and Jakub Kubryński talking about Accurest (Spring Cloud Contract Verifier predecessor)* video::130779882[vimeo] diff --git a/docs/src/main/asciidoc/messaging.adoc b/docs/src/main/asciidoc/messaging.adoc new file mode 100644 index 0000000000..24bc2bc272 --- /dev/null +++ b/docs/src/main/asciidoc/messaging.adoc @@ -0,0 +1,150 @@ +:core_path: ../../../.. +:verifier_root_path: {core_path}/spring-cloud-contract-verifier +:verifier_core_path: {verifier_root_path}/spring-cloud-contract-verifier-core + +== Spring Cloud Contract Verifier Messaging + +Spring Cloud Contract Verifier allows you to verify your application that uses messaging as means of communication. +All of our integrations are working with Spring but you can also set one yourself. + +=== Integrations + +You can use one of the three integration configurations: + +- Apache Camel +- Spring Integration +- Spring Cloud Stream + +If you're using Spring Boot, the aforementioned test configurations will be appended automatically. + +You have to provide as a dependency one of the Spring Cloud Contract Verifier Messaging modules. Example for Gradle: + +[source,groovy,indent=0] +---- +// for Apache Camel +testCompile "org.springframework.cloud.contract:spring-cloud-contract-verifier-camel:${verifierVersion}" +// for Spring Integration +testCompile "org.springframework.cloud.contract:spring-cloud-contract-verifier-integration:${verifierVersion}" +// for Spring Cloud Stream +testCompile "org.springframework.cloud.contract:spring-cloud-contract-verifier-stream:${verifierVersion}" +---- + +=== Manual Integration + +The `spring-cloud-contract-verifier-messaging-core` module contains 3 main interfaces: + +- `ContractVerifierMessage` - describes a message received / sent to a channel / queue / topic etc. +- `ContractVerifierMessageBuilder` - describes how to build a message +- `ContractVerifierMessaging` - class that allows you to build, send and receive messages +- `ContractVerifierFilter` - interface to filter out the messages that do not follow the pattern from the DSL + +In the generated test the `ContractVerifierMessaging` is injected via `@Inject` annotation thus you can use other injection +frameworks than Spring. + +You have to provide as a dependency the `spring-cloud-contract-verifier-messaging-core` module. Example for Gradle: + +[source,groovy,indent=0] +---- +testCompile "org.springframework.cloud.contract:spring-cloud-contract-verifier-messaging-core:${verifierVersion}" +---- + +=== Publisher side test generation + +Having the `input` or `outputMessage` sections in your DSL will result in creation of tests on the publisher's side. By default +JUnit tests will be created, however there is also a possibility to create Spock tests. + +There are 3 main scenarios that we should take into consideration: + +- Scenario 1: there is no input message that produces an output one. The output message is triggered by a component +inside the application (e.g. scheduler) +- Scenario 2: the input message triggers an output message +- Scenario 3: the input message is consumed and there is no output message + +==== Scenario 1 (no input message) + +For the given contract: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_dsl] +---- + +The following JUnit test will be created: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_junit_test] +---- + +And the following Spock test would be created: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_method_test] +---- + +==== Scenario 2 (output triggered by input) + +For the given contract: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_dsl] +---- + +The following JUnit test will be created: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_junit] +---- + +And the following Spock test would be created: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_message_spock] +---- + +==== Scenario 3 (no output message) + +For the given contract: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_dsl] +---- + +The following JUnit test will be created: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_junit] +---- + +And the following Spock test would be created: + +[source,groovy] +---- +include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy[tags=trigger_no_output_spock] +---- + +=== Consumer Stub Side generation + +Unlike the HTTP part - in Messaging we need to publish the Groovy DSL inside the JAR with a stub. Then it's parsed on the consumer side +and proper stubbed routes are created. + +For more infromation please consult the Stub Runner Messaging sections. + +==== Gradle Setup + +Example of Spring Cloud Contract Verifier Gradle setup: + +[source,groovy,indent=0] +---- +include::{verifier_root_path}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=jar_setup,indent=0] +---- + +==== Maven Setup + +Example of Maven can be found in the https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar[Spring Cloud Contract Verifier Maven Plugin README] diff --git a/docs/src/docs/asciidoc/rest.adoc b/docs/src/main/asciidoc/rest.adoc similarity index 68% rename from docs/src/docs/asciidoc/rest.adoc rename to docs/src/main/asciidoc/rest.adoc index 27ccbec36a..6e7b614eb4 100644 --- a/docs/src/docs/asciidoc/rest.adoc +++ b/docs/src/main/asciidoc/rest.adoc @@ -1,10 +1,14 @@ -== Accurest HTTP +:core_path: ../../../.. +:verifier_root_path: {core_path}/spring-cloud-contract-verifier +:verifier_core_path: {verifier_root_path}/spring-cloud-contract-verifier-core + +== Spring Cloud Contract Verifier HTTP === Gradle Project ==== Prerequisites -In order to use Accurest with Wiremock you have to use gradle or maven plugin. +In order to use Spring Cloud Contract Verifier with Wiremock you have to use gradle or maven plugin. ===== Add gradle plugin @@ -15,12 +19,12 @@ buildscript { mavenCentral() } dependencies { - classpath 'io.codearte.accurest:accurest-gradle-plugin:${accurest_version}' + classpath 'org.springframework.cloud.contract:spring-cloud-contract-verifier-gradle-plugin:${verifier_version}' } } apply plugin: 'groovy' -apply plugin: 'accurest' +apply plugin: 'contract-verifier' dependencies { testCompile 'org.codehaus.groovy:groovy-all:2.4.6' @@ -47,8 +51,8 @@ repositories { [source,xml,indent=0] ---- - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin @@ -66,7 +70,7 @@ Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugi ===== Add stubs -By default Accurest is looking for stubs in `src/test/resources/accurest` directory. +By default Spring Cloud Contract Verifier is looking for stubs in `src/test/resources/contracts` 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. @@ -74,29 +78,29 @@ So with following structure [source,groovy,indent=0] ---- -src/test/resources/accurest/myservice/shouldCreateUser.groovy -src/test/resources/accurest/myservice/shouldReturnUser.groovy +src/test/resources/contracts/myservice/shouldCreateUser.groovy +src/test/resources/contracts/myservice/shouldReturnUser.groovy ---- -Accurest will create test class `defaultBasePackage.MyService` with two methods +Spring Cloud Contract Verifier will create test class `defaultBasePackage.MyService` with two methods - `shouldCreateUser()` - `shouldReturnUser()` ==== Run plugin -Plugin registers itself to be invoked before `check` 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. +Plugin registers itself to be invoked before `check` 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 `generateContractTests` task. ==== Configure plugin -To change default configuration just add `accurest` snippet to your Gradle config +To change default configuration just add `contractVerifier` snippet to your Gradle config [source,groovy,indent=0] ---- -accurest { +contractVerifier { testMode = 'MockMvc' baseClassForTests = 'org.mycompany.tests' - generatedTestSourcesDir = project.file('src/accurest') + generatedTestSourcesDir = project.file('src/generatedContract') } ---- @@ -105,22 +109,22 @@ accurest { - **testMode** - defines mode for acceptance tests. By default MockMvc which is based on Spring's MockMvc. It can also be changed to **JaxRsClient** or to **Explicit** for real HTTP calls. - **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 [] - - **basePackageForTests** - specifies base package for all generated tests. By default set to io.codearte.accurest.tests + - **basePackageForTests** - specifies base package for all generated tests. By default set to org.springframework.cloud.contract.verifier.tests - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` if using Spock tests. - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - **ignoredFiles** - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array [] - - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/resources/accurest` - - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `$buildDir/generated-test-sources/accurest` - - **stubsOutputDir** - dir where the generated Wiremock stubs from Groovy DSL should be placed + - **contractsDslDir** - directory containing contracts written using the GroovyDSL. By default `$rootDir/src/test/resources/contracts` + - **generatedTestSourcesDir** - test source directory where tests generated from Groovy DSL should be placed. By default `$buildDir/generated-test-sources/contractVerifier` + - **stubsOutputDir** - dir where the generated WireMock stubs from Groovy DSL should be placed - **targetFramework** - the target test framework to be used; currently Spock and JUnit are supported with JUnit being the default framework ===== Base class for tests -When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. +When using Spring Cloud Contract Verifier in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. [source,groovy,indent=0] ---- -include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/com/ofg/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] +include::{verifier_root_path}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] ---- In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class @@ -132,13 +136,13 @@ To ensure that provider side is complaint with defined contracts, you need to in [source,bash,indent=0] ---- -./gradlew generateAccurest test +./gradlew generateContractTests test ---- -==== Accurest on consumer side +==== Spring Cloud Contract Verifier on consumer side -In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. If you don't want to use Stub Runner then you need to copy contracts stored in -`src/test/resources/accurest` and generate WireMock json stubs using: +In consumer service you need to configure Spring Cloud Contract Verifier plugin in exactly the same way as in case of provider. If you don't want to use Stub Runner then you need to copy contracts stored in +`src/test/resources/contracts` and generate WireMock json stubs using: [source,bash,indent=0] ---- @@ -174,7 +178,7 @@ class LoanApplicationServiceSpec extends Specification { } ---- -Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. +Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Spring Cloud Contract Verifier. === Using in your Maven project @@ -183,8 +187,8 @@ Underneath LoanApplication makes a call to FraudDetection service. This request [source,xml,indent=0] ---- - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract.verifier + spring-cloud-contract-verifier-maven-plugin @@ -201,18 +205,18 @@ Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugi ==== Add stubs -By default Accurest is looking for stubs in `src/test/resources/accurest` directory. +By default Spring Cloud Contract Verifier is looking for stubs in `src/test/resources/contracts` 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 [source,groovy,indent=0] ---- -src/test/resources/accurest/myservice/shouldCreateUser.groovy -src/test/resources/accurest/myservice/shouldReturnUser.groovy +src/test/resources/contracts/myservice/shouldCreateUser.groovy +src/test/resources/contracts/myservice/shouldReturnUser.groovy ---- -Accurest will create test class `defaultBasePackage.MyService` with two methods +Spring Cloud Contract Verifier will create test class `defaultBasePackage.MyService` with two methods - `shouldCreateUser()` - `shouldReturnUser()` @@ -227,8 +231,8 @@ To change default configuration just add `configuration` section to plugin defin [source,xml,indent=0] ---- - io.codearte.accurest - accurest-maven-plugin + org.springframework.cloud.contract.verifier + spring-cloud-contract-verifier-maven-plugin @@ -239,8 +243,8 @@ To change default configuration just add `configuration` section to plugin defin - com.ofg.twitter.place - com.ofg.twitter.place.BaseMockMvcSpec + org.springframework.cloud.contract.verifier.twitter.place + org.springframework.cloud.contract.verifier.twitter.place.BaseMockMvcSpec ---- @@ -248,17 +252,17 @@ To change default configuration just add `configuration` section to plugin defin ===== Important configuration options - **testMode** - defines mode for acceptance tests. By default `MockMvc` which is based on Spring's MockMvc. It can also be changed to `JaxRsClient` or to `Explicit` for real HTTP calls. - - **basePackageForTests** - specifies base package for all generated tests. By default set to `io.codearte.accurest.tests`. + - **basePackageForTests** - specifies base package for all generated tests. By default set to `org.springframework.cloud.contract.verifier.tests`. - **ruleClassForTests** - specifies Rule which should be added to generated test classes. - **baseClassForTests** - base class for generated tests. By default `spock.lang.Specification` if using Spock tests. - - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/resources/accurest`. + - **contractsDir** - directory containing contracts written using the GroovyDSL. By default `/src/test/resources/contracts`. - **testFramework** - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework For complete information take a look at http://codearte.github.io/accurest-maven-plugin/plugin-info.html[Plugin Documentation] ===== Base class for tests - When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. + When using Spring Cloud Contract Verifier in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified. [source,groovy,indent=0] ---- @@ -279,7 +283,7 @@ In case of using `Explicit` mode, you can use base class to initialize the whole ==== Invoking generated tests -Accurest Maven Plugins generates verification code into directory `/generated-test-sources/accurest` and attach this directory to `testCompile` goal. +Spring Cloud Contract Verifier Maven Plugins generates verification code into directory `/generated-test-sources/contractVerifier` and attach this directory to `testCompile` goal. For Groovy Spock code use: @@ -305,7 +309,7 @@ For Groovy Spock code use: - ${project.build.directory}/generated-test-sources/accurest + ${project.build.directory}/generated-test-sources/contractVerifier **/*.groovy @@ -317,18 +321,18 @@ For Groovy Spock code use: To ensure that provider side is complaint with defined contracts, you need to invoke `mvn generateTest test` -==== Accurest on consumer side +==== Spring Cloud Contract Verifier on consumer side -In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/resources/accurest` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. +In consumer service you need to configure Spring Cloud Contract Verifier plugin in exactly the same way as in case of provider. You need to copy contracts stored in `src/test/resources/contracts` and generate Wiremock json stubs using: `mvn generateStubs` command. By default generated WireMock mapping is stored in directory `target/mappings`. Your project should create from this generated mappings additional artifact with classifier `stubs` for easy deploy to maven repository. Sample configuration: [source,xml,indent=0] ---- - io.codearte.accurest - accurest-maven-plugin - ${accurest-plugin.version} + org.springframework.cloud.contract.verifier + spring-cloud-contract-verifier-maven-plugin + ${verifier-plugin.version} @@ -367,11 +371,11 @@ class LoanApplicationServiceSpec extends Specification { } ---- -Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest. +Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Spring Cloud Contract Verifier. === Scenarios -It's possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore. +It's possible to handle scenarios with Spring Cloud Contract Verifier. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore. [source,indent=0] ---- @@ -382,10 +386,10 @@ my_contracts_dir\ 3_logout.groovy ---- -Such tree will cause Accurest generating Wiremock's scenario with name `scenario1` and three steps: +Such tree will cause Spring Cloud Contract Verifier generating Wiremock's scenario with name `scenario1` and three steps: - login marked as `Started` pointing to: - showCart marked as `Step1` pointing to: - logout marked as `Step2` which will close the scenario. More details about Wiremock scenarios can be found under [http://wiremock.org/stateful-behaviour.html](http://wiremock.org/stateful-behaviour.html) -Accurest will also generate tests with guaranteed order of execution. +Spring Cloud Contract Verifier will also generate tests with guaranteed order of execution. diff --git a/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc b/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc new file mode 100644 index 0000000000..8dc733a041 --- /dev/null +++ b/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc @@ -0,0 +1,20 @@ +:core_path: ../../../.. +:verifier_root_path: {core_path}/spring-cloud-contract-verifier +:verifier_core_path: {verifier_root_path}/spring-cloud-contract-verifier-core +:stubrunner_core_path: {core_path}/spring-cloud-contract-stub-runner + += Spring Cloud Contract Verifier + +_Adam Dudczak, Marcin Grzejszczak, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła_ + +include::introduction.adoc[] + +include::contract.adoc[] + +include::rest.adoc[] + +include::messaging.adoc[] + +include::stubrunner.adoc[] + +include::stubrunner_msg.adoc[] \ No newline at end of file diff --git a/docs/src/docs/asciidoc/stubrunner.adoc b/docs/src/main/asciidoc/stubrunner.adoc similarity index 55% rename from docs/src/docs/asciidoc/stubrunner.adoc rename to docs/src/main/asciidoc/stubrunner.adoc index 06aea3f697..3478146c9f 100644 --- a/docs/src/docs/asciidoc/stubrunner.adoc +++ b/docs/src/main/asciidoc/stubrunner.adoc @@ -1,6 +1,10 @@ -== Stub Runner +:core_path: ../../../.. +:verifier_root_path: {core_path}/spring-cloud-contract-verifier +:verifier_core_path: {verifier_root_path}/spring-cloud-contract-verifier-core -One of the issues that you could have encountered while using Accurest was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). +== Spring Cloud Contract Stub Runner + +One of the issues that you could have encountered while using Spring Cloud Contract Verifier was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). The same takes place in terms of client side generation for messaging. Copying the JSON files / setting the client side for messaging manually is out of the question. @@ -11,40 +15,40 @@ The easiest approach would be to centralize the way stubs are kept. For example ==== Gradle -Example of Accurest Gradle setup: +Example of Spring Cloud Contract Verifier Gradle setup: [source,groovy,indent=0] ---- -include::../../../../accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=jar_setup,indent=0] +include::{verifier_root_path}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle[tags=jar_setup,indent=0] ---- ==== Maven -Example of Maven can be found in the https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar[Accurest Maven Plugin README] +Example of Maven can be found in the https://github.com/Codearte/accurest-maven-plugin/=publishing-wiremock-stubs-projectf-stubsjar[Spring Cloud Contract Verifier Maven Plugin README] === Modules -Accurest comes with a new structure of modules +Spring Cloud Contract Stub Runner comes with a new structure of modules [source,indent=0] ---- -└── stub-runner - ├── stub-runner - ├── stub-runner-boot - ├── stub-runner-junit - ├── stub-runner-spring - └── stub-runner-spring-cloud +└── spring-cloud-contract-stub-runner + ├── spring-cloud-contract-stub-runner + ├── spring-cloud-contract-stub-runner-boot + ├── spring-cloud-contract-stub-runner-junit + ├── spring-cloud-contract-stub-runner-spring + └── spring-cloud-contract-stub-runner-spring-cloud ---- -include::../../../../stub-runner/stub-runner/README.adoc[] +include::../../../../spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/README.adoc[] -include::../../../../stub-runner/stub-runner-boot/README.adoc[] +include::../../../../spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc[] -include::../../../../stub-runner/stub-runner-junit/README.adoc[] +include::../../../../spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/README.adoc[] -include::../../../../stub-runner/stub-runner-spring/README.adoc[] +include::../../../../spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/README.adoc[] -include::../../../../stub-runner/stub-runner-spring-cloud/README.adoc[] +include::../../../../spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/README.adoc[] === Common properties for JUnit and Spring diff --git a/docs/src/main/asciidoc/stubrunner_msg.adoc b/docs/src/main/asciidoc/stubrunner_msg.adoc new file mode 100644 index 0000000000..194076d611 --- /dev/null +++ b/docs/src/main/asciidoc/stubrunner_msg.adoc @@ -0,0 +1,61 @@ +:core_path: ../../../.. +:verifier_root_path: {core_path}/spring-cloud-contract-verifier +:verifier_core_path: {verifier_root_path}/spring-cloud-contract-verifier-core +:stubrunner_core_path: {core_path}/spring-cloud-contract-stub-runner + +== Stub Runner for Messaging + +Stub Runner has the functionality to run the published stubs in memory. It can integrate with the following frameworks out of the box + +- Spring Integration +- Spring Cloud Stream +- Apache Camel + +It also provides points of entry to integrate with any other solution on the market. + +=== Stub triggering + +To trigger a message it's enough to use the `StubTrigger` interface: + +[source,groovy] +---- +include::{stubrunner_core_path}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy[] +---- + +For convenience the `StubFinder` interface extends `StubTrigger` so it's enough to use only one in your tests. + +`StubTrigger` gives you the following options to trigger a message: + +==== Trigger by label + +[source,groovy] +---- +include::{stubrunner_core_path}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger,indent=0] +---- + +===== Trigger by group and artifact ids + +[source,groovy] +---- +include::{stubrunner_core_path}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_group_artifact,indent=0] +---- + +===== Trigger by artifact ids + +[source,groovy] +---- +include::{stubrunner_core_path}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_artifact,indent=0] +---- + +===== Trigger all messages + +[source,groovy] +---- +include::{stubrunner_core_path}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_all,indent=0] +---- + +include::{stubrunner_core_path}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc[] + +include::{stubrunner_core_path}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc[] + +include::{stubrunner_core_path}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc[] \ No newline at end of file diff --git a/docs/src/main/ruby/generate_readme.sh b/docs/src/main/ruby/generate_readme.sh new file mode 100755 index 0000000000..6d0ce9dc54 --- /dev/null +++ b/docs/src/main/ruby/generate_readme.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby + +base_dir = File.join(File.dirname(__FILE__),'../../..') +src_dir = File.join(base_dir, "/src/main/asciidoc") +require 'asciidoctor' +require 'optparse' + +options = {} +file = "#{src_dir}/README.adoc" + +OptionParser.new do |o| + o.on('-o OUTPUT_FILE', 'Output file (default is stdout)') { |file| options[:to_file] = file unless file=='-' } + o.on('-h', '--help') { puts o; exit } + o.parse! +end + +file = ARGV[0] if ARGV.length>0 + +# Copied from https://github.com/asciidoctor/asciidoctor-extensions-lab/blob/master/scripts/asciidoc-coalescer.rb +doc = Asciidoctor.load_file file, safe: :unsafe, header_only: true, attributes: options[:attributes] +header_attr_names = (doc.instance_variable_get :@attributes_modified).to_a +header_attr_names.each {|k| doc.attributes[%(#{k}!)] = '' unless doc.attr? k } +attrs = doc.attributes +attrs['allow-uri-read'] = true +puts attrs + +out = "// Do not edit this file (e.g. go instead to src/main/asciidoc)\n\n" +doc = Asciidoctor.load_file file, safe: :unsafe, parse: false, attributes: attrs +out << doc.reader.read + +unless options[:to_file] + puts out +else + File.open(options[:to_file],'w+') do |file| + file.write(out) + end +end diff --git a/generateReadme.sh b/generateReadme.sh new file mode 100755 index 0000000000..1638d7b172 --- /dev/null +++ b/generateReadme.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./gradlew :docs:clean :docs:generateReadme --configure-on-demand \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index f9a69c8932..4f7bae8abc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,14 +1,32 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + nexusUsername = nexusPassword = wiremockVersion = 2.0.10-beta jsonassertVersion = 0.4.7 -BOM_VERSION=Brixton-1.0.0.RC1 +BOM_VERSION=Brixton-SR1 springBootVersion=1.3.3.RELEASE springVersion=4.2.5.RELEASE springIntegrationDslVersion=1.1.2.RELEASE springStreamVersion=1.0.0.RC2 springCloudVersion=1.1.0.RC2 camelVersion=2.17.0 -aetherVersion=1.1.0 \ No newline at end of file +aetherVersion=1.1.0 + +verifierVersion=1.0.0.BUILD-SNAPSHOT \ No newline at end of file diff --git a/gradle/release.gradle b/gradle/release.gradle index e1c6fb4494..2258dcdfea 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -1,59 +1,90 @@ -apply plugin: 'com.bmuschko.nexus' +apply plugin: 'maven' +apply plugin: 'signing' -modifyPom { - project { - name "$project.name" - packaging 'jar' - description 'RESTful Contract Verifier' - url 'https://github.com/Codearte/accurest' - inceptionYear '2014' - - scm { - connection 'scm:git:git@github.com:Codearte/accurest.git' - developerConnection 'scm:git:git@github.com:Codearte/accurest.git' - url 'https://github.com/Codearte/accurest' +ext { + resolveRepoName = { Project project -> + String version = project.version + String name = project.name + String resolvedRepoName = "libs-${resolveVersion(version)}-local" + if (name.contains("gradle")) { + resolvedRepoName = "plugins-${resolveVersion(version)}-local" } + logger.lifecycle("For project [$project.name] with " + + "version [$project.version] the resolved Artifactory repo is [$resolvedRepoName]") + return resolvedRepoName + } - licenses { - license { - name 'The Apache License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - } - } + resolveVersion = { String version -> + if (version.endsWith('BUILD-SNAPSHOT')) return 'snapshot' + if (version.matches('[0-9].[0-9].[0-9].M[0-9]+')) return 'milestone' + if (version.matches('[0-9].[0-9].[0-9].RC[0-9]+')) return 'milestone' + if (version.endsWith('RELEASE')) return 'release' + return 'snapshot' + } - developers { - developer { - id 'jkubrynski' - name 'Jakub Kubrynski' - email 'jk ATT codearte DOTT io' - } - developer { - id 'marcingrzejszczak' - name 'Marcin Grzejszczak' - email 'marcin ATT grzejszczak DOTT pl' + isReleaseVersion = !version.endsWith("SNAPSHOT") +} + +uploadArchives.dependsOn { [check] } + +ext { + repositoryUrl = "https://repo.spring.io/${repoPrefix()}-${resolveVersion(version)}-local" + snapshotRepositoryUrl = "https://repo.spring.io/${repoPrefix()}-snapshot-local" + repoUrl = isReleaseVersion ? repositoryUrl : snapshotRepositoryUrl +} + +afterEvaluate { + uploadArchives { + repositories { + mavenDeployer { + // POM signature + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + // Target repository + repository(url: repoUrl) { + authentication(userName: repoUser, password: repoPass) + } + pom.project { + name "$project.name" + packaging 'jar' + description 'Consumer Driven Contract Verifier and Stub Runner' + url 'https://github.com/Codearte/accurest' + inceptionYear '2014' + + scm { + connection 'scm:git:git@github.com:Codearte/accurest.git' + developerConnection 'scm:git:git@github.com:Codearte/accurest.git' + url 'https://github.com/Codearte/accurest' + } + + licenses { + license { + name 'The Apache License, Version 2.0' + url 'http://www.apache.org/licenses/LICENSE-2.0.txt' + } + } + + developers { + developer { + id 'jkubrynski' + name 'Jakub Kubrynski' + email 'jk ATT codearte DOTT io' + } + developer { + id 'marcingrzejszczak' + name 'Marcin Grzejszczak' + email 'marcin ATT grzejszczak DOTT pl' + } + } + } } } } } -uploadArchives.dependsOn { check } - - -task uploadSnapshotArchives { - if (shouldUploadSnapshotArchives) { - dependsOn { uploadArchives } - } - onlyIf { shouldUploadSnapshotArchives } +String repoPrefix() { + return project.name.contains('gradle') ? 'plugins' : 'libs' } -//for Travis to leverage secure variables -project.ext { - if (!hasProperty('nexusUsername') && System.env.NEXUS_USERNAME) { - nexusUsername = System.env.NEXUS_USERNAME - } - if (!hasProperty('nexusPassword') && System.env.NEXUS_PASSWORD) { - nexusPassword = System.env.NEXUS_PASSWORD - } -} - - +if (projectsToSkipPublication.any { project.name.contains(it) }) { + uploadArchives.enabled = false +} \ No newline at end of file diff --git a/gradle/releaseRoot.gradle b/gradle/releaseRoot.gradle deleted file mode 100644 index 667dcbcb82..0000000000 --- a/gradle/releaseRoot.gradle +++ /dev/null @@ -1,16 +0,0 @@ -assert project == rootProject - -project.ext { - isSnapshot = project.version.endsWith("-SNAPSHOT") - currentBranch = System.env.TRAVIS_BRANCH - isPr = !isNullOrFalse(System.env.TRAVIS_PULL_REQUEST) - doRelease = !isNullOrFalse(System.env.DO_RELEASE) - shouldUploadSnapshotArchives = isSnapshot && currentBranch == 'master' && !isPr && doRelease -} - -logger.lifecycle("Automatic snapshot release: {} (isSnapshot: {}, currentBranch: {}, isPr: {}, doRelease: {})", shouldUploadSnapshotArchives, isSnapshot, currentBranch, isPr, doRelease) - -private boolean isNullOrFalse(def env) { - env == null || env == "false" || (env instanceof Boolean && !env) -} - diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 91aa685ded..72e5e30b39 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Apr 12 23:29:55 EDT 2016 +#Wed Jun 15 17:19:08 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 +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14-bin.zip diff --git a/docs.sh b/publishDocs.sh similarity index 100% rename from docs.sh rename to publishDocs.sh diff --git a/samples/messaging-camel/build.gradle b/samples/messaging-camel/build.gradle deleted file mode 100644 index f358dbffd4..0000000000 --- a/samples/messaging-camel/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ -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:${springBootVersion}" - compile "org.apache.camel:camel-spring-boot-starter:${camelVersion}" - compile "org.apache.camel:camel-jms:${camelVersion}" - compile 'org.apache.activemq:activemq-camel:5.12.1' - compile 'org.apache.activemq:activemq-pool:5.12.1' - compile "org.apache.camel:camel-jackson:${camelVersion}" - - testCompile project(':accurest-messaging-root:accurest-messaging-camel') - testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } -} \ No newline at end of file diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleted.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleted.groovy deleted file mode 100644 index f20d028575..0000000000 --- a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleted.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookReturned.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookReturned.groovy deleted file mode 100644 index 19ca5837d9..0000000000 --- a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookReturned.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplication.groovy b/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplication.groovy deleted file mode 100644 index 26819753e5..0000000000 --- a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplication.groovy +++ /dev/null @@ -1,12 +0,0 @@ -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) - } -} diff --git a/samples/messaging-integration/build.gradle b/samples/messaging-integration/build.gradle deleted file mode 100644 index 94be6d9087..0000000000 --- a/samples/messaging-integration/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -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:${springBootVersion}" - compile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" - - testCompile project(':accurest-messaging-root:accurest-messaging-integration') - testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } -} \ No newline at end of file diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy deleted file mode 100644 index abe8ce0959..0000000000 --- a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy deleted file mode 100644 index cca077e266..0000000000 --- a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplication.groovy b/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplication.groovy deleted file mode 100644 index e1ec8da114..0000000000 --- a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplication.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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) - } -} diff --git a/samples/messaging-spring/build.gradle b/samples/messaging-spring/build.gradle deleted file mode 100644 index c38355e1cf..0000000000 --- a/samples/messaging-spring/build.gradle +++ /dev/null @@ -1,25 +0,0 @@ -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:${springBootVersion}" - compile "org.springframework:spring-jms:${springVersion}" - - 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:${springBootVersion}" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } -} \ No newline at end of file diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookDeleted.groovy b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookDeleted.groovy deleted file mode 100644 index 470329b7a8..0000000000 --- a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookDeleted.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookReturned.groovy b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookReturned.groovy deleted file mode 100644 index bd13a4ff6b..0000000000 --- a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookReturned.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/SpringMessagingApplication.groovy b/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/SpringMessagingApplication.groovy deleted file mode 100644 index 287a1e2240..0000000000 --- a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/SpringMessagingApplication.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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) - } -} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessageBuilder.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessageBuilder.groovy deleted file mode 100644 index cf3294b4e1..0000000000 --- a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessageBuilder.groovy +++ /dev/null @@ -1,35 +0,0 @@ -package io.codearte.accurest.samples.spring.config - -import io.codearte.accurest.messaging.AccurestMessage -import io.codearte.accurest.messaging.AccurestMessageBuilder -import org.springframework.jms.core.MessageCreator - -import javax.jms.JMSException -import javax.jms.Message -import javax.jms.Session -/** - * @author Marcin Grzejszczak - */ -public class AccurestSpringMessageBuilder implements AccurestMessageBuilder { - - @Override - public AccurestMessage create(final T payload, final Map headers) { - MessageCreator messageCreator = new MessageCreator() { - @Override - public Message createMessage(Session session) throws JMSException { - Message message = session.createObjectMessage(payload); - headers.entrySet().each { Map.Entry entry -> - message.setObjectProperty(entry.key, entry.value) - } - return message - } - }; - - return new SpringMessage<>(messageCreator) - } - - @Override - public AccurestMessage create(Message message) { - return new SpringMessage<>(message); - } -} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy deleted file mode 100644 index 7599cbbb7f..0000000000 --- a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/AccurestSpringMessaging.groovy +++ /dev/null @@ -1,77 +0,0 @@ -package io.codearte.accurest.samples.spring.config - -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.jms.core.JmsTemplate -import org.springframework.stereotype.Component - -import javax.jms.Message -import java.util.concurrent.TimeUnit -/** - * @author Marcin Grzejszczak - */ -@Component -public class AccurestSpringMessaging implements AccurestMessaging { - - private static final Logger log = LoggerFactory.getLogger(AccurestSpringMessaging.class); - - private final JmsTemplate jmsTemplate; - private final AccurestMessageBuilder builder; - - @Autowired - @SuppressWarnings("unchecked") - public AccurestSpringMessaging(AccurestMessageBuilder builder, JmsTemplate jmsTemplate) { - this.builder = builder - this.jmsTemplate = jmsTemplate - } - - @Override - @SuppressWarnings("unchecked") - public void send(T payload, Map headers, String destination) { - send(builder.create(payload, headers), destination); - } - - @Override - public void send(AccurestMessage message, String destination) { - try { - jmsTemplate.send(destination, ((SpringMessage) message).messageCreator) - } 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 receiveMessage(String destination, long timeout, TimeUnit timeUnit) { - try { - return builder.create(jmsTemplate.receive(destination)); - } 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 receiveMessage(String destination) { - return receiveMessage(destination, 5, TimeUnit.SECONDS); - } - - @Override - @SuppressWarnings("unchecked") - public AccurestMessage create(T t, Map headers) { - return builder.create(t, headers); - } - - @Override - @SuppressWarnings("unchecked") - public AccurestMessage create(Message message) { - return builder.create(message); - } -} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/ManualAccurestConfiguration.groovy b/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/ManualAccurestConfiguration.groovy deleted file mode 100644 index 1cd05f86f0..0000000000 --- a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/ManualAccurestConfiguration.groovy +++ /dev/null @@ -1,18 +0,0 @@ -package io.codearte.accurest.samples.spring.config - -import io.codearte.accurest.messaging.AccurestMessaging -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.jms.core.JmsTemplate -/** - * @author Marcin Grzejszczak - */ -@Configuration -class ManualAccurestConfiguration { - - @Bean - AccurestMessaging accurestMessaging(JmsTemplate jmsTemplate) { - return new AccurestSpringMessaging(new AccurestSpringMessageBuilder(), jmsTemplate); - } - -} diff --git a/samples/messaging-stream/build.gradle b/samples/messaging-stream/build.gradle deleted file mode 100644 index 54779d6866..0000000000 --- a/samples/messaging-stream/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -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:${springBootVersion}" - compile "org.springframework.cloud:spring-cloud-stream-binder-rabbit:${springStreamVersion}" - - testCompile project(':accurest-messaging-root:accurest-messaging-stream') - testCompile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } -} \ No newline at end of file diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy deleted file mode 100644 index abe8ce0959..0000000000 --- a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookDeleted.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy deleted file mode 100644 index cca077e266..0000000000 --- a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookReturned.groovy +++ /dev/null @@ -1,14 +0,0 @@ -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 - } -} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/DeleteSink.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/DeleteSink.groovy deleted file mode 100644 index 6986da9ca8..0000000000 --- a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/DeleteSink.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package io.codearte.accurest.samples.messaging - -import org.springframework.cloud.stream.annotation.Input -import org.springframework.cloud.stream.messaging.Sink -import org.springframework.messaging.SubscribableChannel - -/** - * @author Marcin Grzejszczak - */ -interface DeleteSink extends Sink { - - String INPUT = "delete"; - - @Input(DeleteSink.INPUT) - SubscribableChannel delete(); -} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplication.groovy b/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplication.groovy deleted file mode 100644 index c6285ea622..0000000000 --- a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplication.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package io.codearte.accurest.samples.messaging; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.cloud.stream.annotation.EnableBinding -import org.springframework.cloud.stream.messaging.Sink; -import org.springframework.cloud.stream.messaging.Source; - -@SpringBootApplication -@EnableBinding([Source, Sink]) -class StreamMessagingApplication { - - static void main(String[] args) { - SpringApplication.run(StreamMessagingApplication.class, args) - } -} diff --git a/samples/samples-messaging-camel/build.gradle b/samples/samples-messaging-camel/build.gradle new file mode 100644 index 0000000000..067b6cdeb2 --- /dev/null +++ b/samples/samples-messaging-camel/build.gradle @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String verifier = "spring-cloud-contract-verifier" + +dependencies { + compile project(":$verifier-root:$verifier-core") + compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" + compile "org.apache.camel:camel-spring-boot-starter:${camelVersion}" + compile "org.apache.camel:camel-jms:${camelVersion}" + compile 'org.apache.activemq:activemq-camel:5.12.1' + compile 'org.apache.activemq:activemq-pool:5.12.1' + compile "org.apache.camel:camel-jackson:${camelVersion}" + + testCompile project(":$verifier-root:$verifier-messaging-root:$verifier-camel") + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy new file mode 100644 index 0000000000..52af5fd871 --- /dev/null +++ b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleter.groovy b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleter.groovy similarity index 56% rename from samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleter.groovy rename to samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleter.groovy index 9184450edc..c1ad517de9 100644 --- a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookDeleter.groovy +++ b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleter.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.camel +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.camel import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy new file mode 100644 index 0000000000..373743a094 --- /dev/null +++ b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookRouteConfiguration.groovy b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookRouteConfiguration.groovy similarity index 64% rename from samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookRouteConfiguration.groovy rename to samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookRouteConfiguration.groovy index 66f5a46535..06ed844919 100644 --- a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookRouteConfiguration.groovy +++ b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookRouteConfiguration.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.camel +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.camel import org.apache.activemq.camel.component.ActiveMQComponent import org.apache.camel.RoutesBuilder diff --git a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookService.groovy b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookService.groovy similarity index 52% rename from samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookService.groovy rename to samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookService.groovy index edda66c9c7..f60ec6fbe9 100644 --- a/samples/messaging-camel/src/main/groovy/io/codearte/accurest/samples/camel/BookService.groovy +++ b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookService.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.camel +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.camel import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy new file mode 100644 index 0000000000..da6bddcb83 --- /dev/null +++ b/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy @@ -0,0 +1,28 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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) + } +} diff --git a/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy b/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy similarity index 58% rename from samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy rename to samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy index 0dfecf7e2e..38337f6b76 100644 --- a/samples/messaging-camel/src/test/groovy/io/codearte/accurest/samples/camel/CamelMessagingApplicationSpec.groovy +++ b/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy @@ -1,15 +1,31 @@ -package io.codearte.accurest.samples.camel +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.camel 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 io.codearte.accurest.messaging.AccurestObjectMapper +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.apache.camel.model.ModelCamelContext import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper import org.springframework.test.context.ContextConfiguration import spock.lang.Specification import spock.util.concurrent.PollingConditions @@ -23,12 +39,12 @@ import javax.inject.Inject public class CamelMessagingApplicationSpec extends Specification { // ALL CASES - @Inject AccurestMessaging accurestMessaging - AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper() + @Inject ContractVerifierMessaging contractVerifierMessaging + ContractVerifierObjectMapper contractVerifierObjectMapper = new ContractVerifierObjectMapper() def "should work for triggered based messaging"() { given: - def dsl = GroovyDsl.make { + def dsl = Contract.make { label 'some_label' input { triggeredBy('bookReturnedTriggered()') @@ -45,16 +61,16 @@ public class CamelMessagingApplicationSpec extends Specification { when: bookReturnedTriggered() then: - def response = accurestMessaging.receiveMessage('activemq:output') + def response = contractVerifierMessaging.receiveMessage('activemq:output') response.headers.get('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload)) JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo') } def "should generate tests triggered by a message"() { given: - def dsl = GroovyDsl.make { + def dsl = Contract.make { label 'some_label' input { messageFrom('jms:input') @@ -80,23 +96,23 @@ public class CamelMessagingApplicationSpec extends Specification { // generated test should look like this: //given: - AccurestMessage inputMessage = accurestMessaging.create( - accurestObjectMapper.writeValueAsString([bookName: 'foo']), + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']), [sample: 'header'] ) when: - accurestMessaging.send(inputMessage, 'jms:input') + contractVerifierMessaging.send(inputMessage, 'jms:input') then: - def response = accurestMessaging.receiveMessage('jms:output') + def response = contractVerifierMessaging.receiveMessage('jms:output') response.headers.get('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.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 { + def dsl = Contract.make { label 'some_label' input { messageFrom('jms:delete') @@ -113,12 +129,12 @@ public class CamelMessagingApplicationSpec extends Specification { // generated test should look like this: //given: - AccurestMessage inputMessage = accurestMessaging.create( - accurestObjectMapper.writeValueAsString([bookName: 'foo']), + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']), [sample: 'header'] ) when: - accurestMessaging.send(inputMessage, 'jms:delete') + contractVerifierMessaging.send(inputMessage, 'jms:delete') then: noExceptionThrown() bookWasDeleted() diff --git a/samples/samples-messaging-integration/build.gradle b/samples/samples-messaging-integration/build.gradle new file mode 100644 index 0000000000..990aa349b2 --- /dev/null +++ b/samples/samples-messaging-integration/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String verifier = "spring-cloud-contract-verifier" + +dependencies { + compile project(":$verifier-root:$verifier-core") + compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" + compile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" + + testCompile project(":$verifier-root:$verifier-messaging-root:$verifier-integration") + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy new file mode 100644 index 0000000000..e43c21c9d2 --- /dev/null +++ b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy similarity index 66% rename from samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy rename to samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy index 1ef7d26f79..e0041a8dcb 100644 --- a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy +++ b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.messaging +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.messaging import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy new file mode 100644 index 0000000000..130c19d468 --- /dev/null +++ b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy similarity index 61% rename from samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy rename to samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy index f5acc1c1e8..888df79bce 100644 --- a/samples/messaging-integration/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy +++ b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.messaging +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.messaging import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy new file mode 100644 index 0000000000..811fcbdfc3 --- /dev/null +++ b/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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) + } +} diff --git a/samples/messaging-integration/src/main/resources/integration-context.xml b/samples/samples-messaging-integration/src/main/resources/integration-context.xml similarity index 50% rename from samples/messaging-integration/src/main/resources/integration-context.xml rename to samples/samples-messaging-integration/src/main/resources/integration-context.xml index aa5a5cc3a5..3dd916e22f 100644 --- a/samples/messaging-integration/src/main/resources/integration-context.xml +++ b/samples/samples-messaging-integration/src/main/resources/integration-context.xml @@ -1,4 +1,20 @@ + + - - - + diff --git a/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy b/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy similarity index 61% rename from samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy rename to samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy index 75b453940d..7307d4ea71 100644 --- a/samples/messaging-integration/src/test/groovy/io/codearte/accurest/samples/messaging/IntegrationMessagingApplicationSpec.groovy +++ b/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy @@ -1,14 +1,30 @@ -package io.codearte.accurest.samples.messaging +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.messaging 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 io.codearte.accurest.messaging.AccurestObjectMapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper import org.springframework.test.context.ContextConfiguration import spock.lang.Specification @@ -18,13 +34,13 @@ import javax.inject.Inject public class IntegrationMessagingApplicationSpec extends Specification { // ALL CASES - @Inject AccurestMessaging accurestMessaging - AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper() + @Inject ContractVerifierMessaging contractVerifierMessaging + ContractVerifierObjectMapper contractVerifierObjectMapper = new ContractVerifierObjectMapper() def "should work for triggered based messaging"() { given: // tag::method_trigger[] - def dsl = GroovyDsl.make { + def dsl = Contract.make { // Human readable description description 'Some description' // Label by means of which the output message can be triggered @@ -51,17 +67,17 @@ public class IntegrationMessagingApplicationSpec extends Specification { when: bookReturnedTriggered() then: - def response = accurestMessaging.receiveMessage('output') + def response = contractVerifierMessaging.receiveMessage('output') response.headers.get('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload)) JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo') } def "should generate tests triggered by a message"() { given: // tag::message_trigger[] - def dsl = GroovyDsl.make { + def dsl = Contract.make { description 'Some Description' label 'some_label' // input is a message @@ -92,23 +108,23 @@ public class IntegrationMessagingApplicationSpec extends Specification { // generated test should look like this: //given: - AccurestMessage inputMessage = accurestMessaging.create( - accurestObjectMapper.writeValueAsString([bookName: 'foo']), + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']), [sample: 'header'] ) when: - accurestMessaging.send(inputMessage, 'input') + contractVerifierMessaging.send(inputMessage, 'input') then: - def response = accurestMessaging.receiveMessage('output') + def response = contractVerifierMessaging.receiveMessage('output') response.headers.get('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.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 { + def dsl = Contract.make { label 'some_label' input { messageFrom('delete') @@ -125,12 +141,12 @@ public class IntegrationMessagingApplicationSpec extends Specification { // generated test should look like this: //given: - AccurestMessage inputMessage = accurestMessaging.create( - accurestObjectMapper.writeValueAsString([bookName: 'foo']), + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']), [sample: 'header'] ) when: - accurestMessaging.send(inputMessage, 'delete') + contractVerifierMessaging.send(inputMessage, 'delete') then: noExceptionThrown() bookWasDeleted() diff --git a/samples/samples-messaging-spring/build.gradle b/samples/samples-messaging-spring/build.gradle new file mode 100644 index 0000000000..dcc70f5e6e --- /dev/null +++ b/samples/samples-messaging-spring/build.gradle @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String verifier = "spring-cloud-contract-verifier" + +dependencies { + compile project(":$verifier-root:$verifier-core") + compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" + compile "org.springframework:spring-jms:${springVersion}" + + compile 'org.apache.activemq:activemq-broker:5.12.1' + compile 'org.apache.activemq:activemq-pool:5.12.1' + + testCompile project(":$verifier-root:$verifier-messaging-root:$verifier-messaging-core") + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy new file mode 100644 index 0000000000..3ee03c12ec --- /dev/null +++ b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookListener.groovy b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookListener.groovy similarity index 75% rename from samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookListener.groovy rename to samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookListener.groovy index 6d56d0f594..117bf6a9b6 100644 --- a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookListener.groovy +++ b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookListener.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.spring +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.spring import com.fasterxml.jackson.databind.ObjectMapper import groovy.transform.CompileStatic diff --git a/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy new file mode 100644 index 0000000000..a875572a76 --- /dev/null +++ b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookService.groovy b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookService.groovy similarity index 63% rename from samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookService.groovy rename to samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookService.groovy index 5ba455d8c1..b6413c21c4 100644 --- a/samples/messaging-spring/src/main/groovy/io/codearte/accurest/samples/spring/BookService.groovy +++ b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookService.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.spring +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.spring import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy new file mode 100644 index 0000000000..c4a6676fb8 --- /dev/null +++ b/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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) + } +} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy similarity index 56% rename from samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy rename to samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy index 0c79f467c2..7737cd4270 100644 --- a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/SpringApplicationSpec.groovy +++ b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy @@ -1,14 +1,30 @@ -package io.codearte.accurest.samples.spring +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.spring 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 io.codearte.accurest.messaging.AccurestObjectMapper import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper import org.springframework.test.context.ContextConfiguration import spock.lang.Specification import spock.util.concurrent.PollingConditions @@ -22,12 +38,12 @@ import javax.inject.Inject public class SpringApplicationSpec extends Specification { // ALL CASES - @Inject AccurestMessaging accurestMessaging - AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper() + @Inject ContractVerifierMessaging contractVerifierMessaging + ContractVerifierObjectMapper contractVerifierObjectMapper = new ContractVerifierObjectMapper() def "should work for triggered based messaging"() { given: - def dsl = GroovyDsl.make { + def dsl = Contract.make { label 'some_label' input { triggeredBy('bookReturnedTriggered()') @@ -44,16 +60,16 @@ public class SpringApplicationSpec extends Specification { when: bookReturnedTriggered() then: - def response = accurestMessaging.receiveMessage('output') + def response = contractVerifierMessaging.receiveMessage('output') response.headers.get('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload)) JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo') } def "should generate tests triggered by a message"() { given: - def dsl = GroovyDsl.make { + def dsl = Contract.make { label 'some_label' input { messageFrom('input') @@ -78,23 +94,23 @@ public class SpringApplicationSpec extends Specification { // generated test should look like this: //given: - AccurestMessage inputMessage = accurestMessaging.create( - accurestObjectMapper.writeValueAsString([bookName: 'foo']), + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']), [sample: 'header'] ) when: - accurestMessaging.send(inputMessage, 'input') + contractVerifierMessaging.send(inputMessage, 'input') then: - def response = accurestMessaging.receiveMessage('output') + def response = contractVerifierMessaging.receiveMessage('output') response.headers.get('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.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 { + def dsl = Contract.make { label 'some_label' input { messageFrom('delete') @@ -111,12 +127,12 @@ public class SpringApplicationSpec extends Specification { // generated test should look like this: //given: - AccurestMessage inputMessage = accurestMessaging.create( - accurestObjectMapper.writeValueAsString([bookName: 'foo']), + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']), [sample: 'header'] ) when: - accurestMessaging.send(inputMessage, 'delete') + contractVerifierMessaging.send(inputMessage, 'delete') then: noExceptionThrown() bookWasDeleted() diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy new file mode 100644 index 0000000000..fdd0094caf --- /dev/null +++ b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.spring.config + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder +import org.springframework.jms.core.MessageCreator + +import javax.jms.JMSException +import javax.jms.Message +import javax.jms.Session +/** + * @author Marcin Grzejszczak + */ +public class ContractVerifierSpringMessageBuilder implements ContractVerifierMessageBuilder { + + @Override + public ContractVerifierMessage create(final T payload, final Map headers) { + MessageCreator messageCreator = new MessageCreator() { + @Override + public Message createMessage(Session session) throws JMSException { + Message message = session.createObjectMessage(payload); + headers.entrySet().each { Map.Entry entry -> + message.setObjectProperty(entry.key, entry.value) + } + return message + } + }; + + return new SpringMessage<>(messageCreator) + } + + @Override + public ContractVerifierMessage create(Message message) { + return new SpringMessage<>(message); + } +} diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy new file mode 100644 index 0000000000..bd7e93503b --- /dev/null +++ b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy @@ -0,0 +1,93 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.spring.config + +import org.slf4j.Logger +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.jms.core.JmsTemplate +import org.springframework.stereotype.Component + +import javax.jms.Message +import java.util.concurrent.TimeUnit +/** + * @author Marcin Grzejszczak + */ +@Component +public class ContractVerifierSpringMessaging implements ContractVerifierMessaging { + + private static final Logger log = LoggerFactory.getLogger(ContractVerifierSpringMessaging.class); + + private final JmsTemplate jmsTemplate; + private final ContractVerifierMessageBuilder builder; + + @Autowired + @SuppressWarnings("unchecked") + public ContractVerifierSpringMessaging(ContractVerifierMessageBuilder builder, JmsTemplate jmsTemplate) { + this.builder = builder + this.jmsTemplate = jmsTemplate + } + + @Override + @SuppressWarnings("unchecked") + public void send(T payload, Map headers, String destination) { + send(builder.create(payload, headers), destination); + } + + @Override + public void send(ContractVerifierMessage message, String destination) { + try { + jmsTemplate.send(destination, ((SpringMessage) message).messageCreator) + } 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 ContractVerifierMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit) { + try { + return builder.create(jmsTemplate.receive(destination)); + } 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 ContractVerifierMessage receiveMessage(String destination) { + return receiveMessage(destination, 5, TimeUnit.SECONDS); + } + + @Override + @SuppressWarnings("unchecked") + public ContractVerifierMessage create(T t, Map headers) { + return builder.create(t, headers); + } + + @Override + @SuppressWarnings("unchecked") + public ContractVerifierMessage create(Message message) { + return builder.create(message); + } +} diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy new file mode 100644 index 0000000000..eb9966e3b3 --- /dev/null +++ b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.spring.config + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.jms.core.JmsTemplate + +/** + * @author Marcin Grzejszczak + */ +@Configuration +class ManualContractVerifierConfiguration { + + @Bean + ContractVerifierMessaging contractVerifierMessaging(JmsTemplate jmsTemplate) { + return new ContractVerifierSpringMessaging(new ContractVerifierSpringMessageBuilder(), jmsTemplate); + } + +} diff --git a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/SpringMessage.groovy b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/SpringMessage.groovy similarity index 55% rename from samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/SpringMessage.groovy rename to samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/SpringMessage.groovy index 1f8f7cc8b6..28239443a1 100644 --- a/samples/messaging-spring/src/test/groovy/io/codearte/accurest/samples/spring/config/SpringMessage.groovy +++ b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/SpringMessage.groovy @@ -1,6 +1,22 @@ -package io.codearte.accurest.samples.spring.config +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.messaging.AccurestMessage +package org.springframework.cloud.contract.verifier.samples.spring.config + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.springframework.jms.core.MessageCreator import javax.jms.Message @@ -8,7 +24,7 @@ import javax.jms.ObjectMessage /** * @author Marcin Grzejszczak */ -public class SpringMessage implements AccurestMessage { +public class SpringMessage implements ContractVerifierMessage { private final ObjectMessage messageDelegate; final MessageCreator messageCreator; diff --git a/samples/samples-messaging-stream/build.gradle b/samples/samples-messaging-stream/build.gradle new file mode 100644 index 0000000000..296798e705 --- /dev/null +++ b/samples/samples-messaging-stream/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String verifier = "spring-cloud-contract-verifier" + +dependencies { + compile project(":$verifier-root:$verifier-core") + compile "org.springframework.boot:spring-boot-starter-actuator:${springBootVersion}" + compile "org.springframework.cloud:spring-cloud-stream-binder-rabbit:${springStreamVersion}" + + testCompile project(":$verifier-root:$verifier-messaging-root:$verifier-stream") + testCompile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy new file mode 100644 index 0000000000..e43c21c9d2 --- /dev/null +++ b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy similarity index 72% rename from samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy rename to samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy index fe201e4636..6e70889df4 100644 --- a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookListener.groovy +++ b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.messaging +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.messaging import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy new file mode 100644 index 0000000000..130c19d468 --- /dev/null +++ b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy similarity index 60% rename from samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy rename to samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy index ae310cb836..4e8a8adefa 100644 --- a/samples/messaging-stream/src/main/groovy/io/codearte/accurest/samples/messaging/BookService.groovy +++ b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.messaging +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.messaging import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy new file mode 100644 index 0000000000..aa6e72e4e4 --- /dev/null +++ b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.messaging + +import org.springframework.cloud.stream.annotation.Input +import org.springframework.cloud.stream.messaging.Sink +import org.springframework.messaging.SubscribableChannel + +/** + * @author Marcin Grzejszczak + */ +interface DeleteSink extends Sink { + + String INPUT = "delete"; + + @Input(DeleteSink.INPUT) + SubscribableChannel delete(); +} diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy new file mode 100644 index 0000000000..9fa8eb8f86 --- /dev/null +++ b/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.messaging; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cloud.stream.annotation.EnableBinding +import org.springframework.cloud.stream.messaging.Sink; +import org.springframework.cloud.stream.messaging.Source; + +@SpringBootApplication +@EnableBinding([Source, Sink]) +class StreamMessagingApplication { + + static void main(String[] args) { + SpringApplication.run(StreamMessagingApplication.class, args) + } +} diff --git a/samples/messaging-stream/src/main/resources/application.yml b/samples/samples-messaging-stream/src/main/resources/application.yml similarity index 100% rename from samples/messaging-stream/src/main/resources/application.yml rename to samples/samples-messaging-stream/src/main/resources/application.yml diff --git a/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy b/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy similarity index 55% rename from samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy rename to samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy index 597f693709..2aa6c241a9 100644 --- a/samples/messaging-stream/src/test/groovy/io/codearte/accurest/samples/messaging/StreamMessagingApplicationSpec.groovy +++ b/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy @@ -1,14 +1,30 @@ -package io.codearte.accurest.samples.messaging +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.samples.messaging 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 io.codearte.accurest.messaging.AccurestObjectMapper +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper import org.springframework.test.context.ContextConfiguration import spock.lang.Specification @@ -21,12 +37,12 @@ import javax.inject.Inject public class StreamMessagingApplicationSpec extends Specification { // ALL CASES - @Inject AccurestMessaging accurestMessaging - AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper() + @Inject ContractVerifierMessaging contractVerifierMessaging + ContractVerifierObjectMapper contractVerifierObjectMapper = new ContractVerifierObjectMapper() def "should work for triggered based messaging"() { given: - def dsl = GroovyDsl.make { + def dsl = Contract.make { label 'some_label' input { triggeredBy('bookReturnedTriggered()') @@ -43,16 +59,16 @@ public class StreamMessagingApplicationSpec extends Specification { when: bookReturnedTriggered() then: - def response = accurestMessaging.receiveMessage('output') + def response = contractVerifierMessaging.receiveMessage('output') response.headers.get('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload)) JsonAssertion.assertThat(parsedJson).field('bookName').isEqualTo('foo') } def "should generate tests triggered by a message"() { given: - def dsl = GroovyDsl.make { + def dsl = Contract.make { label 'some_label' input { messageFrom('input') @@ -77,23 +93,23 @@ public class StreamMessagingApplicationSpec extends Specification { // generated test should look like this: //given: - AccurestMessage inputMessage = accurestMessaging.create( - accurestObjectMapper.writeValueAsString([bookName: 'foo']), + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']), [sample: 'header'] ) when: - accurestMessaging.send(inputMessage, 'input') + contractVerifierMessaging.send(inputMessage, 'input') then: - def response = accurestMessaging.receiveMessage('output') + def response = contractVerifierMessaging.receiveMessage('output') response.headers.get('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.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 { + def dsl = Contract.make { label 'some_label' input { messageFrom('delete') @@ -110,12 +126,12 @@ public class StreamMessagingApplicationSpec extends Specification { // generated test should look like this: //given: - AccurestMessage inputMessage = accurestMessaging.create( - accurestObjectMapper.writeValueAsString([bookName: 'foo']), + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( + contractVerifierObjectMapper.writeValueAsString([bookName: 'foo']), [sample: 'header'] ) when: - accurestMessaging.send(inputMessage, 'delete') + contractVerifierMessaging.send(inputMessage, 'delete') then: noExceptionThrown() bookWasDeleted() diff --git a/scripts/runTests.sh b/scripts/runTests.sh index 4658a122d2..ccb87af81b 100755 --- a/scripts/runTests.sh +++ b/scripts/runTests.sh @@ -3,17 +3,19 @@ set -o errexit mkdir -p build -GRADLE_OUTPUT=`./gradlew cV --quiet` -ACCUREST_VERSION=`echo ${GRADLE_OUTPUT##*:}` -export ACCUREST_VERSION=${ACCUREST_VERSION} +CONTRACT_VERIFIER_VERSION=1.0.0.BUILD-SNAPSHOT +export CONTRACT_VERIFIER_VERSION=${CONTRACT_VERIFIER_VERSION} -echo "Current accurest version is ${ACCUREST_VERSION}" +echo "Current Spring Cloud Contract Verifier version is ${CONTRACT_VERIFIER_VERSION}" cd build echo "Cloning samples" git clone https://github.com/Codearte/accurest-samples cd accurest-samples +echo "Using the rebranding branch" +git checkout rebranding + echo "Running Gradle tests" . ./runTests.sh diff --git a/settings.gradle b/settings.gradle index 7c598a3401..c86dce469d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,29 +1,37 @@ -include 'docs' -include "accurest-core", "accurest-gradle-plugin", 'accurest-converters', 'accurest-testing-utils' +String verifier = "spring-cloud-contract-verifier" +String stubRunner = "spring-cloud-contract-stub-runner" -include ':accurest-messaging:accurest-messaging-core' -include ':accurest-messaging:accurest-messaging-integration' -include ':accurest-messaging:accurest-messaging-stream' -include ':accurest-messaging:accurest-messaging-camel' +rootProject.name = "$verifier-parent" -include ':stub-runner:stub-runner' -include ':stub-runner:stub-runner-spring' -include ':stub-runner:stub-runner-boot' -include ':stub-runner:stub-runner-spring-cloud' -include ':stub-runner:stub-runner-junit' +include "docs" -include ':stub-runner:stub-runner-messaging:stub-runner-messaging-integration' -include ':stub-runner:stub-runner-messaging:stub-runner-messaging-stream' -include ':stub-runner:stub-runner-messaging:stub-runner-messaging-camel' +include ":$verifier:$verifier-core", + ":$verifier:$verifier-gradle-plugin", + ":$verifier:$verifier-converters", + ":$verifier:$verifier-testing-utils" -include ':samples:messaging-stream' -include ':samples:messaging-integration' -include ':samples:messaging-camel' -include ':samples:messaging-spring' +include ":$verifier:$verifier-messaging:$verifier-messaging-core", + ":$verifier:$verifier-messaging:$verifier-integration", + ":$verifier:$verifier-messaging:$verifier-stream", + ":$verifier:$verifier-messaging:$verifier-camel" -rootProject.name = "accurest" +include ":$stubRunner:$stubRunner", + ":$stubRunner:$stubRunner-spring", + ":$stubRunner:$stubRunner-boot", + ":$stubRunner:$stubRunner-spring-cloud", + ":$stubRunner:$stubRunner-junit" + +include ":$stubRunner:$stubRunner-messaging:$stubRunner-integration", + ":$stubRunner:$stubRunner-messaging:$stubRunner-stream", + ":$stubRunner:$stubRunner-messaging:$stubRunner-camel" + +include ":samples:samples-messaging-stream", + ":samples:samples-messaging-integration", + ":samples:samples-messaging-camel", + ":samples:samples-messaging-spring" //to prevent StackOverflow in Sonar -project(":stub-runner").name = "stub-runner-root" -project(":accurest-messaging").name = "accurest-messaging-root" -project(":stub-runner:stub-runner-messaging").name = "stub-runner-messaging-root" +project(":$verifier").name = "$verifier-root" +project(":$stubRunner").name = "$stubRunner-root" +project(":$verifier:$verifier-messaging").name = "$verifier-messaging-root" +project(":$stubRunner:$stubRunner-messaging").name = "$stubRunner-messaging-root" diff --git a/stub-runner/stub-runner-boot/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc similarity index 66% rename from stub-runner/stub-runner-boot/README.adoc rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc index 78cb519824..24f7712612 100644 --- a/stub-runner/stub-runner-boot/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc @@ -1,8 +1,6 @@ === Stub Runner Boot -WARNING: Feature available since {messaging_version} - -Accurest Stub Runner Boot is a Spring Boot application that exposes REST endpoints to +Spring Cloud Contract Verifier Stub Runner Boot is a Spring Boot application that exposes REST endpoints to trigger the messaging labels and to access started WireMock servers. One of the usecases is to run some smoke (end to end) tests on a deployed application. You can read @@ -14,7 +12,7 @@ Just add the [source,groovy,indent=0] ---- -compile "io.codearte.accurest:stub-runner-boot:${accurestVersion}" +compile "org.springframework.cloud.contract:stub-runner-boot:${verifierVersion}" ---- and a messaging implementation: @@ -22,11 +20,11 @@ and a messaging implementation: [source,groovy,indent=0] ---- // for Apache Camel -compile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}" +compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-messaging-camel:${verifierVersion}" // for Spring Integration -compile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}" +compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-messaging-integration:${verifierVersion}" // for Spring Cloud Stream -compile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}" +compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-messaging-stream:${verifierVersion}" ---- Build a fat-jar and you're ready to go! @@ -52,5 +50,5 @@ For Messaging [source,groovy,indent=0] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy[tags=boot_usage] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy[tags=boot_usage] ---- \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/build.gradle new file mode 100644 index 0000000000..a86573fc3a --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/build.gradle @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String stubRunner = "spring-cloud-contract-stub-runner" + +dependencies { + compile project(":$stubRunner-root:$stubRunner-spring") + compile "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" + + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile project(":$stubRunner-root:$stubRunner-messaging-root:$stubRunner-stream") + testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/HttpStubsController.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/HttpStubsController.groovy similarity index 55% rename from stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/HttpStubsController.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/HttpStubsController.groovy index 9a4806edc9..35730cd6ff 100644 --- a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/HttpStubsController.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/HttpStubsController.groovy @@ -1,7 +1,23 @@ -package io.codearte.accurest.stubrunner.boot +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.boot -import io.codearte.accurest.stubrunner.StubRunning import org.springframework.beans.factory.annotation.Autowired +import org.springframework.cloud.contract.stubrunner.StubRunning import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.PathVariable diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy new file mode 100644 index 0000000000..daedaba6d6 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy @@ -0,0 +1,52 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.boot + +import org.springframework.boot.SpringApplication +import org.springframework.boot.autoconfigure.AutoConfigureAfter +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerConfiguration +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessageBuilder +import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging +import org.springframework.context.annotation.Bean + +/** + * @author Marcin Grzejszczak + */ +@SpringBootApplication +@AutoConfigureAfter(StubRunnerConfiguration.class) +class StubRunnerBoot { + + static void main(String[] args) { + SpringApplication.run(StubRunnerBoot.class, args); + } + + @Bean + @ConditionalOnMissingBean + ContractVerifierMessaging noOpContractVerifierMessaging() { + return new NoOpContractVerifierMessaging() + } + + @Bean + @ConditionalOnMissingBean + ContractVerifierMessageBuilder noOpContractVerifierMessageBuilder() { + return new NoOpContractVerifierMessageBuilder() + } +} diff --git a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/TriggerController.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/TriggerController.groovy similarity index 69% rename from stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/TriggerController.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/TriggerController.groovy index 7bb1a002f7..d06760166a 100644 --- a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/TriggerController.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/TriggerController.groovy @@ -1,8 +1,24 @@ -package io.codearte.accurest.stubrunner.boot +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.boot import groovy.util.logging.Slf4j -import io.codearte.accurest.stubrunner.StubFinder import org.springframework.beans.factory.annotation.Autowired +import org.springframework.cloud.contract.stubrunner.StubFinder import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.PathVariable diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/resources/META-INF/spring.factories similarity index 60% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/resources/META-INF/spring.factories index bb95d2a818..31aea03047 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/resources/META-INF/spring.factories @@ -1,3 +1,3 @@ # Auto Configuration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.stubrunner.messaging.camel.StubRunnerCamelConfiguration +org.springframework.cloud.contract.stubrunner.spring.StubRunnerConfiguration diff --git a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy similarity index 62% rename from stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy index 5a02291f2b..40a2e22f41 100644 --- a/stub-runner/stub-runner-boot/src/test/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBootSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy @@ -1,10 +1,26 @@ -package io.codearte.accurest.stubrunner.boot +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.boot import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc import groovy.json.JsonSlurper -import io.codearte.accurest.stubrunner.StubRunning import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.stubrunner.StubRunning import org.springframework.cloud.stream.annotation.EnableBinding import org.springframework.context.annotation.Configuration import org.springframework.test.context.ContextConfiguration @@ -31,7 +47,7 @@ class StubRunnerBootSpec extends Specification { String response = RestAssuredMockMvc.get('/stubs').body.asString() then: def root = new JsonSlurper().parseText(response) - root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs' instanceof Integer + root.'org.springframework.cloud.contract.verifier.stubs:streamService:0.0.1-SNAPSHOT:stubs' instanceof Integer } def 'should return a port on which a [#stubId] stub is running'() { @@ -41,10 +57,10 @@ class StubRunnerBootSpec extends Specification { response.statusCode == 200 response.body.as(Integer) > 0 where: - stubId << ['io.codearte.accurest.stubs:streamService:+:stubs', - 'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs', - 'io.codearte.accurest.stubs:streamService:+', - 'io.codearte.accurest.stubs:streamService', + stubId << ['org.springframework.cloud.contract.verifier.stubs:streamService:+:stubs', + 'org.springframework.cloud.contract.verifier.stubs:streamService:0.0.1-SNAPSHOT:stubs', + 'org.springframework.cloud.contract.verifier.stubs:streamService:+', + 'org.springframework.cloud.contract.verifier.stubs:streamService', 'streamService'] } @@ -60,7 +76,7 @@ class StubRunnerBootSpec extends Specification { String response = RestAssuredMockMvc.get('/triggers').body.asString() then: def root = new JsonSlurper().parseText(response) - root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"]) + root.'org.springframework.cloud.contract.verifier.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"]) } def 'should trigger a messaging label'() { @@ -86,7 +102,7 @@ class StubRunnerBootSpec extends Specification { and: 1 * stubRunning.trigger(stubId, 'delete_book') where: - stubId << ['io.codearte.accurest.stubs:streamService:stubs', 'io.codearte.accurest.stubs:streamService', 'streamService'] + stubId << ['org.springframework.cloud.contract.verifier.stubs:streamService:stubs', 'org.springframework.cloud.contract.verifier.stubs:streamService', 'streamService'] } def 'should return when trigger is missing'() { @@ -95,7 +111,7 @@ class StubRunnerBootSpec extends Specification { then: response.statusCode == 404 def root = new JsonSlurper().parseText(response.body.asString()) - root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"]) + root.'org.springframework.cloud.contract.verifier.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"]) } } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml new file mode 100644 index 0000000000..9b34d9d617 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo/repository/ +stubrunner.stubs.ids: org.springframework.cloud.contract.verifier.stubs:streamService \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..4f874c72510c8870ffaf12cd6305e57ac2535711 GIT binary patch literal 1788 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJs?>QhSbCh9{vwhqxS=O?2HTy8VoX6^(5uz zX9uO0losWsrWop_7v<-dRfdLeGBDd!Cxu%AacKoN10&0Kpb;z}lTG^$b{#Sha5(=m zyd`c~6WgA5zT*CinkuGmnVIH%yT>QUb;kl`*?r<%REo*% zbk>>k(?!od&Qgohiapank5|-^*7)|4wXD z)p|O`VcNd{=_dx}cFwG~FK6zz%Hy++@bdVT<5&6l3mYghApw*K44}5hA%{-`JrzJ? z02v_%kQp#=v@ipxwa>pB7(hqQzg+$zS1W_B`pY)Gt_>@u@9p%s<(Hi~Npo_E>yh{S ze7oxT4jqblcDDMx`H`(9vgX^?MM&BRZ{Kv`%JfYNuOmg{{wbM zvpCikUC}i7HSevVdRD*ugpOlnd-=-~FIa{??mC$wkUGQWDeKhfIreXyTHciXNSx>7 zYEsg1xVx}-l}p*ipgE5wH3l!c%yC)7P1WrFB!erz8MjIvHhg;Fm;9-OJucb*^#6Y0 z+kNBhzVzGY&l*i={@u9uFC!wbGJ%1`{k<`CBQUUj0wbIn(3N63hZ((I=ZnvI)f98%& zmkRHOsX8C9E==b3-@BQ0>%@f}-`ZlPn{Fz7^!C?lwhV(>wNuW0c31gq-S#|j>Gcb_ zTUI+~o7Mu3kR7R9&x9}CJRd)?ddB4yQ)l^of6RS4WV(y8%iRA>)-3Hh#=)`aiCY|A z*t~LGb^n}?+%ZPMClx!KOsXEqIhqx3H@+z%HR&NMqA1WpD>KltWNu-EyAPLuoR0^S+08$Mr;y{HB1PCzv zbu0rik;)T%8bSVq0FcIoKqit#ctHd*L5>-c&oB!j39tdcEXUB$col~U*o!4rNU?-g zBq7^|nX8d)`v$ZWn|qOML*#LwZJ<1k$2QDtfoz*HGj7|^GYQZxP$t1*7cA{yOL5?U h1g4$8jwUQ9cEQtMfHx}}NEHVV)&XNb1E`LH0RWpuDM + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + streamService + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml new file mode 100644 index 0000000000..001cf26899 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + streamService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-junit/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/README.adoc similarity index 59% rename from stub-runner/stub-runner-junit/README.adoc rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/README.adoc index d55abedcef..6fa5144dd0 100644 --- a/stub-runner/stub-runner-junit/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/README.adoc @@ -4,7 +4,7 @@ Stub Runner comes with a JUnit rule thanks to which you can very easily download [source,java,indent=0] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java[tags=classrule] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java[tags=classrule] ---- After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to: @@ -18,25 +18,25 @@ After that rule gets executed Stub Runner connects to your Maven repository and Stub Runner uses https://wiki.eclipse.org/Aether[Eclipse Aether] mechanism to download the Maven dependencies. Check their https://wiki.eclipse.org/Aether[docs] for more information. -Since the `AccurestRule` implements the `StubFinder` it allows you to find the started stubs: +Since the `StubRunnerRule` implements the `StubFinder` it allows you to find the started stubs: [source,groovy,indent=0] ---- -include::../stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy[] +include::../spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy[] ---- Example of usage in Spock tests: [source,groovy,indent=0] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy[tags=classrule] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy[tags=classrule] ---- Example of usage in JUnit tests: [source,java,indent=0] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java[tags=test] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java[tags=test] ---- Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner. @@ -48,18 +48,18 @@ JUnit rule. ==== Fluent API -When using the `AccurestRule` you can add a stub to download and then pass the port for the last downloaded stub. +When using the `StubRunnerRule` you can add a stub to download and then pass the port for the last downloaded stub. [source,java,indent=0] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java[tags=classrule_with_port] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java[tags=classrule_with_port] ---- You can see that for this example the following test is valid: [source,java,indent=0] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java[tags=test_with_port] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java[tags=test_with_port] ---- diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/build.gradle new file mode 100644 index 0000000000..3349027ab9 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/build.gradle @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +description = 'JUnit rule for stub-runner' + +String stubRunner = "spring-cloud-contract-stub-runner" + +dependencies { + compile project(":$stubRunner-root:$stubRunner") + + compile localGroovy() + compile 'junit:junit:4.12' + + testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + testCompile 'ch.qos.logback:logback-classic:1.1.3' + testCompile 'org.assertj:assertj-core:2.3.0' + testCompile 'org.apache.commons:commons-io:1.3.2' +} diff --git a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java similarity index 65% rename from stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java index fdc76d786a..30f888c6be 100644 --- a/stub-runner/stub-runner-junit/src/main/groovy/io/codearte/accurest/stubrunner/junit/AccurestRule.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java @@ -1,16 +1,20 @@ -package io.codearte.accurest.stubrunner.junit; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.dsl.GroovyDsl; -import io.codearte.accurest.stubrunner.BatchStubRunner; -import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; -import io.codearte.accurest.stubrunner.RunningStubs; -import io.codearte.accurest.stubrunner.StubConfiguration; -import io.codearte.accurest.stubrunner.StubFinder; -import io.codearte.accurest.stubrunner.StubRunnerOptions; -import io.codearte.accurest.stubrunner.StubRunnerOptionsBuilder; -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; +package org.springframework.cloud.contract.stubrunner.junit; import java.net.URL; import java.util.Arrays; @@ -18,12 +22,24 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; +import org.springframework.cloud.contract.stubrunner.BatchStubRunner; +import org.springframework.cloud.contract.stubrunner.BatchStubRunnerFactory; +import org.springframework.cloud.contract.stubrunner.RunningStubs; +import org.springframework.cloud.contract.stubrunner.StubConfiguration; +import org.springframework.cloud.contract.stubrunner.StubFinder; +import org.springframework.cloud.contract.stubrunner.StubRunnerOptions; +import org.springframework.cloud.contract.stubrunner.StubRunnerOptionsBuilder; +import org.springframework.cloud.contract.verifier.dsl.Contract; + /** * JUnit class rule that allows you to download the provided stubs. * * @author Marcin Grzejszczak */ -public class AccurestRule implements TestRule, StubFinder { +public class StubRunnerRule implements TestRule, StubFinder { private static final String DELIMITER = ":"; private static final String LATEST_VERSION = "+"; @@ -63,7 +79,7 @@ public class AccurestRule implements TestRule, StubFinder { * * @see StubRunnerOptions */ - public AccurestRule options(StubRunnerOptions stubRunnerOptions) { + public StubRunnerRule options(StubRunnerOptions stubRunnerOptions) { stubRunnerOptionsBuilder.withOptions(stubRunnerOptions); return this; } @@ -71,7 +87,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Min value of port for WireMock server */ - public AccurestRule minPort(int minPort) { + public StubRunnerRule minPort(int minPort) { stubRunnerOptionsBuilder.withMinPort(minPort); return this; } @@ -79,7 +95,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Max value of port for WireMock server */ - public AccurestRule maxPort(int maxPort) { + public StubRunnerRule maxPort(int maxPort) { stubRunnerOptionsBuilder.withMaxPort(maxPort); return this; } @@ -87,7 +103,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * String URI of repository containing stubs */ - public AccurestRule repoRoot(String repoRoot) { + public StubRunnerRule repoRoot(String repoRoot) { stubRunnerOptionsBuilder.withStubRepositoryRoot(repoRoot); return this; } @@ -95,7 +111,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Should download stubs or use only the local repository */ - public AccurestRule workOffline(boolean workOffline) { + public StubRunnerRule workOffline(boolean workOffline) { stubRunnerOptionsBuilder.withWorkOffline(workOffline); return this; } @@ -103,7 +119,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Group Id, artifact Id, version and classifier of a single stub to download */ - public AccurestRule downloadStub(String groupId, String artifactId, String version, String classifier) { + public StubRunnerRule downloadStub(String groupId, String artifactId, String version, String classifier) { stubRunnerOptionsBuilder.withStubs(groupId + DELIMITER + artifactId + DELIMITER + version + DELIMITER + classifier); return this; } @@ -111,7 +127,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Group Id, artifact Id and classifier of a single stub to download in the latest version */ - public AccurestRule downloadLatestStub(String groupId, String artifactId, String classifier) { + public StubRunnerRule downloadLatestStub(String groupId, String artifactId, String classifier) { stubRunnerOptionsBuilder.withStubs(groupId + DELIMITER + artifactId + DELIMITER + LATEST_VERSION + DELIMITER + classifier); return this; } @@ -119,7 +135,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Group Id, artifact Id and version of a single stub to download */ - public AccurestRule downloadStub(String groupId, String artifactId, String version) { + public StubRunnerRule downloadStub(String groupId, String artifactId, String version) { stubRunnerOptionsBuilder.withStubs(groupId + DELIMITER + artifactId + DELIMITER + version); return this; } @@ -127,7 +143,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Group Id, artifact Id of a single stub to download. Default classifier will be picked. */ - public AccurestRule downloadStub(String groupId, String artifactId) { + public StubRunnerRule downloadStub(String groupId, String artifactId) { stubRunnerOptionsBuilder.withStubs(groupId + DELIMITER + artifactId); return this; } @@ -135,7 +151,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Ivy notation of a single stub to download. */ - public AccurestRule downloadStub(String ivyNotation) { + public StubRunnerRule downloadStub(String ivyNotation) { stubRunnerOptionsBuilder.withStubs(ivyNotation); return this; } @@ -143,7 +159,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Stubs to download in Ivy notations */ - public AccurestRule downloadStubs(String... ivyNotations) { + public StubRunnerRule downloadStubs(String... ivyNotations) { stubRunnerOptionsBuilder.withStubs(Arrays.asList(ivyNotations)); return this; } @@ -151,7 +167,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Stubs to download in Ivy notations */ - public AccurestRule downloadStubs(List ivyNotations) { + public StubRunnerRule downloadStubs(List ivyNotations) { stubRunnerOptionsBuilder.withStubs(ivyNotations); return this; } @@ -159,7 +175,7 @@ public class AccurestRule implements TestRule, StubFinder { /** * Appends port to last added stub */ - public AccurestRule withPort(Integer port) { + public StubRunnerRule withPort(Integer port) { stubRunnerOptionsBuilder.withPort(port); return this; } @@ -180,8 +196,8 @@ public class AccurestRule implements TestRule, StubFinder { } @Override - public Map> getAccurestContracts() { - return stubFinder.getAccurestContracts(); + public Map> getContracts() { + return stubFinder.getContracts(); } @Override diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java new file mode 100644 index 0000000000..06519312b3 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java @@ -0,0 +1,85 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.junit; + +import java.io.InputStream; +import java.net.URI; + +import org.apache.commons.io.IOUtils; +import org.assertj.core.api.BDDAssertions; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public class StubRunnerRuleCustomPortJUnitTest { + + @BeforeClass + @AfterClass + public static void setupProps() { + System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); + System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); + } + + // tag::classrule_with_port[] + @ClassRule public static StubRunnerRule rule = new StubRunnerRule() + .repoRoot(repoRoot()) + .downloadStub("org.springframework.cloud.contract.verifier.stubs", "loanIssuance") + .withPort(12345) + .downloadStub("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer:12346"); + // end::classrule_with_port[] + + @Test + public void should_start_wiremock_servers() throws Exception { + // expect: 'WireMocks are running' + then(rule.findStubUrl("org.springframework.cloud.contract.verifier.stubs", "loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("org.springframework.cloud.contract.verifier.stubs", "loanIssuance")); + then(rule.findStubUrl("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer")).isNotNull(); + // and: + BDDAssertions.then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); + BDDAssertions.then(rule.findAllRunningStubs().isPresent("org.springframework.cloud.contract.verifier.stubs", "fraudDetectionServer")).isTrue(); + BDDAssertions.then(rule.findAllRunningStubs().isPresent("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer")).isTrue(); + // and: 'Stubs were registered' + then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); + then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); + // and: 'The port is fixed' + // tag::test_with_port[] + then(rule.findStubUrl("loanIssuance")).isEqualTo(URI.create("http://localhost:12345").toURL()); + then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL()); + // end::test_with_port[] + } + + private static String repoRoot() { + try { + return StubRunnerRuleCustomPortJUnitTest.class.getResource("/m2repo/repository/").toURI().toString(); + } catch (Exception e) { + return ""; + } + } + + private String httpGet(String url) throws Exception { + try(InputStream stream = URI.create(url).toURL().openStream()) { + return IOUtils.toString(stream); + } + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java new file mode 100644 index 0000000000..e5ae1d1c15 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java @@ -0,0 +1,81 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.junit; + +import java.io.InputStream; +import java.net.URI; + +import org.apache.commons.io.IOUtils; +import org.assertj.core.api.BDDAssertions; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.ClassRule; +import org.junit.Test; + +import static org.assertj.core.api.BDDAssertions.then; + +/** + * @author Marcin Grzejszczak + */ +public class StubRunnerRuleJUnitTest { + + @BeforeClass + @AfterClass + public static void setupProps() { + System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); + System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); + } + + // tag::classrule[] + @ClassRule public static StubRunnerRule rule = new StubRunnerRule() + .repoRoot(repoRoot()) + .downloadStub("org.springframework.cloud.contract.verifier.stubs", "loanIssuance") + .downloadStub("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer"); + // end::classrule[] + + // tag::test[] + @Test + public void should_start_wiremock_servers() throws Exception { + // expect: 'WireMocks are running' + then(rule.findStubUrl("org.springframework.cloud.contract.verifier.stubs", "loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isNotNull(); + then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("org.springframework.cloud.contract.verifier.stubs", "loanIssuance")); + then(rule.findStubUrl("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer")).isNotNull(); + // and: + BDDAssertions.then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); + BDDAssertions.then(rule.findAllRunningStubs().isPresent("org.springframework.cloud.contract.verifier.stubs", "fraudDetectionServer")).isTrue(); + BDDAssertions.then(rule.findAllRunningStubs().isPresent("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer")).isTrue(); + // and: 'Stubs were registered' + then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); + then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); + } + // end::test[] + + private static String repoRoot() { + try { + return StubRunnerRuleJUnitTest.class.getResource("/m2repo/repository/").toURI().toString(); + } catch (Exception e) { + return ""; + } + } + + private String httpGet(String url) throws Exception { + try(InputStream stream = URI.create(url).toURL().openStream()) { + return IOUtils.toString(stream); + } + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy new file mode 100644 index 0000000000..3399d25ea0 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy @@ -0,0 +1,58 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.junit + +import org.junit.AfterClass +import org.junit.BeforeClass +import org.junit.ClassRule +import spock.lang.Shared +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +class StubRunnerRuleSpec extends Specification { + + @BeforeClass + @AfterClass + void setupProps() { + System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); + System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); + } + + // tag::classrule[] + @ClassRule @Shared StubRunnerRule rule = new StubRunnerRule() + .repoRoot(StubRunnerRuleSpec.getResource("/m2repo/repository").toURI().toString()) + .downloadStub("org.springframework.cloud.contract.verifier.stubs", "loanIssuance") + .downloadStub("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer") + + def 'should start WireMock servers'() { + expect: 'WireMocks are running' + rule.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance') != null + rule.findStubUrl('loanIssuance') != null + rule.findStubUrl('loanIssuance') == rule.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance') + rule.findStubUrl('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer') != null + and: + rule.findAllRunningStubs().isPresent('loanIssuance') + rule.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs', 'fraudDetectionServer') + rule.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer') + and: 'Stubs were registered' + "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + } + // end::classrule[] +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml new file mode 100644 index 0000000000..7eecabf2f2 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml @@ -0,0 +1,30 @@ + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..40610c8cdb --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml new file mode 100644 index 0000000000..281b9b3b80 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..59db343686 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + loanIssuance + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml new file mode 100644 index 0000000000..615428dae6 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + loanIssuance + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062111 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc similarity index 61% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc index d931a61a10..84eb4ac140 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc @@ -3,7 +3,7 @@ === Stub Runner Messaging Camel -Accurest Stub Runner's messaging module gives you an easy way to integrate with Apache Camel. +Spring Cloud Contract Verifier Stub Runner's messaging module gives you an easy way to integrate with Apache Camel. For the provided artifacts it will automatically download the stubs and register the required routes. @@ -13,7 +13,7 @@ To use it you have to add the following dependency to your project (example for [source,groovy,indent=0] ---- -testCompile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}" +testCompile "org.springframework.cloud.contract:stub-runner-messaging-camel:${verifierVersion}" ---- ==== Examples @@ -57,14 +57,14 @@ Let's consider the following contracts (let' number it with *1*): [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=sample_dsl,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=sample_dsl,indent=0] ---- and number *2* [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] ---- ===== Scenario 1 (no input message) @@ -73,21 +73,21 @@ So as to trigger a message via the `return_book_1` label we'll use the `StubTigg [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger,indent=0] ---- Next we'll want to listen to the output of the message sent to `{output_name}` [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] ---- And the received message would pass the following assertions [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] ---- ===== Scenario 2 (output triggered by input) @@ -96,21 +96,21 @@ Since the route is set for you it's enough to just send a message to the `{outpu [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_send,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_send,indent=0] ---- Next we'll want to listen to the output of the message sent to `{output_name}` [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_receive,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_receive,indent=0] ---- And the received message would pass the following assertions [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_receive_message,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=client_receive_message,indent=0] ---- ===== Scenario 3 (input with no output) @@ -119,5 +119,5 @@ Since the route is set for you it's enough to just send a message to the `{outpu [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] ---- diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle new file mode 100644 index 0000000000..bd4200c30f --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String verifier = "spring-cloud-contract-verifier" +String stubRunner = "spring-cloud-contract-stub-runner" + +dependencies { + compile project(":$stubRunner-root:$stubRunner-spring") + compile project(":$verifier-root:$verifier-messaging-root:$verifier-camel") + compile "org.apache.camel:camel-spring-boot-starter:${camelVersion}" + compile "org.apache.camel:camel-jackson:${camelVersion}" + + testCompile "org.springframework:spring-beans:${springVersion}" + testCompile "org.apache.camel:camel-jms:${camelVersion}" + testCompile 'org.apache.activemq:activemq-camel:5.12.1' + testCompile 'org.apache.activemq:activemq-pool:5.12.1' + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy new file mode 100644 index 0000000000..a97f21f07c --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.camel + +import org.apache.camel.RoutesBuilder +import org.apache.camel.spring.SpringRouteBuilder +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.stubrunner.BatchStubRunner +import org.springframework.cloud.contract.stubrunner.StubConfiguration +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration + +/** + * Camel configuration that iterates over the downloaded Groovy DSLs + * and registers a route for each DSL. + * + * @author Marcin Grzejszczak + */ +@Configuration +class StubRunnerCamelConfiguration { + + @Bean + RoutesBuilder myRouter(BatchStubRunner batchStubRunner) { + return new SpringRouteBuilder() { + @Override + public void configure() throws Exception { + Map> contracts = batchStubRunner.contracts + (contracts.values().flatten() as Collection).findAll { it?.input?.messageFrom?.clientValue && it?.outputMessage?.sentTo }.each { + from(it.input.messageFrom.clientValue) + .filter(new StubRunnerCamelPredicate(it)) + .process(new StubRunnerCamelProcessor(it)) + .to(it.outputMessage.sentTo.clientValue) + } + } + }; + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy similarity index 57% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy index b38b82fabe..c8fc231223 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy @@ -1,16 +1,32 @@ -package io.codearte.accurest.stubrunner.messaging.camel +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.camel import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import com.toomuchcoding.jsonassert.JsonVerifiable import groovy.transform.PackageScope -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.messaging.AccurestObjectMapper -import io.codearte.accurest.util.JsonPaths -import io.codearte.accurest.util.JsonToJsonPathsConverter +import org.springframework.cloud.contract.verifier.dsl.Contract import org.apache.camel.Exchange import org.apache.camel.Predicate +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper +import org.springframework.cloud.contract.verifier.util.JsonPaths +import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter import java.util.regex.Pattern @@ -22,10 +38,10 @@ import java.util.regex.Pattern @PackageScope class StubRunnerCamelPredicate implements Predicate { - private final GroovyDsl groovyDsl - private final AccurestObjectMapper objectMapper = new AccurestObjectMapper() + private final Contract groovyDsl + private final ContractVerifierObjectMapper objectMapper = new ContractVerifierObjectMapper() - StubRunnerCamelPredicate(GroovyDsl groovyDsl) { + StubRunnerCamelPredicate(Contract groovyDsl) { this.groovyDsl = groovyDsl } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy new file mode 100644 index 0000000000..7bf6113f9b --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy @@ -0,0 +1,52 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.camel + +import groovy.transform.PackageScope +import org.springframework.cloud.contract.verifier.util.BodyAsStringUtil +import org.apache.camel.Exchange +import org.apache.camel.Message +import org.apache.camel.Processor +import org.springframework.cloud.contract.verifier.dsl.Contract + +/** + * Sends forward a message defined in the DSL. Also removes headers from the + * input message and provides the headers from the DSL. + * + * @author Marcin Grzejszczak + */ +@PackageScope +class StubRunnerCamelProcessor implements Processor { + + private final Contract groovyDsl + + StubRunnerCamelProcessor(Contract groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + void process(Exchange exchange) throws Exception { + Message input = exchange.in + input.body = BodyAsStringUtil.extractClientValueFrom(groovyDsl.outputMessage.body) + groovyDsl.input.messageHeaders.entries.each { + input.removeHeader(it.name) + } + groovyDsl.outputMessage.headers.entries.each { + input.setHeader(it.name, it.clientValue) + } + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..26adb8c16c --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.contract.stubrunner.messaging.camel.StubRunnerCamelConfiguration diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy new file mode 100644 index 0000000000..72a689a659 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.camel + +import com.fasterxml.jackson.annotation.JsonCreator +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode + +@CompileStatic +@EqualsAndHashCode +class BookReturned implements Serializable { + final String bookName + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + BookReturned(String bookName) { + this.bookName = bookName + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy similarity index 84% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy index 28e8053387..1fc0b9bc95 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy @@ -1,9 +1,23 @@ -package io.codearte.accurest.stubrunner.messaging.camel +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.camel import groovy.json.JsonOutput import groovy.json.JsonSlurper -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.stubrunner.StubFinder import org.apache.activemq.camel.component.ActiveMQComponent import org.apache.camel.CamelContext import org.apache.camel.Exchange @@ -11,6 +25,8 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.stubrunner.StubFinder import org.springframework.context.annotation.Bean import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration @@ -70,7 +86,7 @@ class CamelStubRunnerSpec extends Specification { def 'should trigger a label for the existing groupId:artifactId'() { when: // tag::trigger_group_artifact[] - stubFinder.trigger('io.codearte.accurest.stubs:camelService', 'return_book_1') + stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:camelService', 'return_book_1') // end::trigger_group_artifact[] then: Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000) @@ -150,9 +166,9 @@ class CamelStubRunnerSpec extends Specification { return new ActiveMQComponent(brokerURL: url) } - GroovyDsl dsl = + Contract dsl = // tag::sample_dsl[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'return_book_1' input { triggeredBy('bookReturnedTriggered()') @@ -167,9 +183,9 @@ class CamelStubRunnerSpec extends Specification { } // end::sample_dsl[] - GroovyDsl dsl2 = + Contract dsl2 = // tag::sample_dsl_2[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'return_book_2' input { messageFrom('jms:input') @@ -192,9 +208,9 @@ class CamelStubRunnerSpec extends Specification { } // end::sample_dsl_2[] - GroovyDsl dsl3 = + Contract dsl3 = // tag::sample_dsl_3[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'delete_book' input { messageFrom('jms:delete') diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml new file mode 100644 index 0000000000..db021bb201 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo/repository/ +stubrunner.stubs.ids: org.springframework.cloud.contract.verifier.stubs:camelService \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..4196403cea227573936b3feaa20a98fe03584166 GIT binary patch literal 1797 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJs?>QhP81QJoJq9jvWT_xEUE3G#F&C>PgDa z&kjm0DJ{xNO)=C!fw$8V{rutw;>`j$p63UjiE$~rrnLCx zUF{QpwyelFmmjb;A+%$sfXUG>tB(n6iG8HBpg(=p1FN>T-D#mFDM36B6i>(4EIIAH zb84!4$SKQ4oxcmrP9(nk!!P=#@A&(#4>#XC+}^T8|Jj`F=lwwu3JIhYz(AVzr~Jxk zpvNMJ3?w7uK;i}l(9bfAKx*|ny$TpevCHEx#%g7V>D^ta(X>LkTzuk|xpp~|G$((F z(|ff4_L3hF9EWnw%~221%<3(XT`+9X*v*ivQiSi?f#}BYo z{wj6+y0WU!B1irA&%CF%_x_5k-OY>$tPQ}x5~yvuv<(-4-E^*6t->5aU8{%3D8r*1LZ%-8!L zbzYeK;+W}n--v*oUfD3IqZSZyiB2yZ{RDM%9L10D%;Pz>-EyAPLuoR2-q3 z08$Mr>p-Or1PCzvbu0rikqQ=k8bSVq0FcIoKqit#c!>luL5>-c*)U5a39tdce8;f$2QEofoz*PGj7|^a|+Nd tP)@;O7cA{yOL5?U1g4$8j + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + camelService + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..8ac2715bc8 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + camelService + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml new file mode 100644 index 0000000000..237fd747a9 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + camelService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml new file mode 100644 index 0000000000..237fd747a9 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + camelService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc similarity index 61% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc index 89c30d9dcf..2d2664bba1 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc @@ -3,7 +3,7 @@ === Stub Runner Messaging Integration -Accurest Stub Runner's messaging module gives you an easy way to integrate with Spring Integration. +Spring Cloud Contract Verifier Stub Runner's messaging module gives you an easy way to integrate with Spring Integration. For the provided artifacts it will automatically download the stubs and register the required routes. @@ -13,7 +13,7 @@ To use it you have to add the following dependency to your project (example for [source,groovy,indent=0] ---- -testCompile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}" +testCompile "org.springframework.cloud.contract:stub-runner-messaging-integration:${verifierVersion}" ---- ==== Examples @@ -57,14 +57,14 @@ Let's consider the following contracts (let' number it with *1*): [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=sample_dsl,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=sample_dsl,indent=0] ---- and number *2* [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] ---- and the following Spring Integration Route: @@ -81,21 +81,21 @@ So as to trigger a message via the `return_book_1` label we'll use the `StubTigg [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger,indent=0] ---- Next we'll want to listen to the output of the message sent to `{output_name}` [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] ---- And the received message would pass the following assertions [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] ---- ===== Scenario 2 (output triggered by input) @@ -104,21 +104,21 @@ Since the route is set for you it's enough to just send a message to the `{outpu [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_send,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_send,indent=0] ---- Next we'll want to listen to the output of the message sent to `{output_name}` [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_receive,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_receive,indent=0] ---- And the received message would pass the following assertions [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_receive_message,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=client_receive_message,indent=0] ---- ===== Scenario 3 (input with no output) @@ -127,5 +127,5 @@ Since the route is set for you it's enough to just send a message to the `{input [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] ---- diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle new file mode 100644 index 0000000000..338123d564 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} +String verifier = "spring-cloud-contract-verifier" +String stubRunner = "spring-cloud-contract-stub-runner" + +dependencies { + compile project(":$stubRunner-root:$stubRunner-spring") + compile project(":$verifier-root:$verifier-messaging-root:$verifier-integration") + compile "org.springframework.integration:spring-integration-java-dsl:${springIntegrationDslVersion}" + compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0' + + testCompile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy similarity index 64% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy index f4ba7902a0..2d777d252e 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -1,11 +1,27 @@ -package io.codearte.accurest.stubrunner.messaging.integration +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.integration import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.stubrunner.BatchStubRunner -import io.codearte.accurest.stubrunner.StubConfiguration -import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.stubrunner.StubConfiguration import org.springframework.beans.factory.config.AutowireCapableBeanFactory +import org.springframework.cloud.contract.stubrunner.BatchStubRunner +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerConfiguration import org.springframework.context.Lifecycle import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -29,10 +45,10 @@ class StubRunnerIntegrationConfiguration { @Bean FlowRegistrar flowRegistrar(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner) { - Map> accurestContracts = batchStubRunner.accurestContracts - accurestContracts.each { StubConfiguration key, Collection value -> + Map> contracts = batchStubRunner.contracts + contracts.each { StubConfiguration key, Collection value -> String name = "${key.groupId}_${key.artifactId}" - value.findAll { it?.input?.messageFrom?.clientValue }.each { GroovyDsl dsl -> + value.findAll { it?.input?.messageFrom?.clientValue }.each { Contract dsl -> String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" IntegrationFlowBuilder builder = IntegrationFlows.from(dsl.input.messageFrom.clientValue) .filter(new StubRunnerIntegrationMessageSelector(dsl), { FilterEndpointSpec e -> e.id("${flowName}.filter") } ) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy similarity index 57% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy index 1bdf1398f2..e3a7a87e69 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy @@ -1,14 +1,30 @@ -package io.codearte.accurest.stubrunner.messaging.integration +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.integration import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import com.toomuchcoding.jsonassert.JsonVerifiable import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.messaging.AccurestObjectMapper -import io.codearte.accurest.util.JsonPaths -import io.codearte.accurest.util.JsonToJsonPathsConverter +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper +import org.springframework.cloud.contract.verifier.util.JsonPaths +import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter import org.springframework.integration.core.MessageSelector import org.springframework.messaging.Message @@ -21,10 +37,10 @@ import java.util.regex.Pattern @CompileStatic class StubRunnerIntegrationMessageSelector implements MessageSelector { - private final GroovyDsl groovyDsl - private final AccurestObjectMapper objectMapper = new AccurestObjectMapper() + private final Contract groovyDsl + private final ContractVerifierObjectMapper objectMapper = new ContractVerifierObjectMapper() - StubRunnerIntegrationMessageSelector(GroovyDsl groovyDsl) { + StubRunnerIntegrationMessageSelector(Contract groovyDsl) { this.groovyDsl = groovyDsl } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy new file mode 100644 index 0000000000..d45dafcc81 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy @@ -0,0 +1,48 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.integration + +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.util.BodyAsStringUtil +import org.springframework.integration.transformer.GenericTransformer +import org.springframework.messaging.Message +import org.springframework.messaging.MessageHeaders +import org.springframework.messaging.support.MessageBuilder + +/** + * Sends forward a message defined in the DSL. + * + * @author Marcin Grzejszczak + */ +class StubRunnerIntegrationTransformer implements GenericTransformer, Message> { + + private final Contract groovyDsl + + StubRunnerIntegrationTransformer(Contract groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + Message transform(Message source) { + if (!groovyDsl.outputMessage) { + return source + } + String payload = BodyAsStringUtil.extractClientValueFrom(groovyDsl.outputMessage.body) + Map headers = groovyDsl.outputMessage.headers.asStubSideMap() + return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..a69b005443 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.contract.stubrunner.messaging.integration.StubRunnerIntegrationConfiguration diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy new file mode 100644 index 0000000000..bbb47bbb60 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.integration + +import com.fasterxml.jackson.annotation.JsonCreator +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode + +@CompileStatic +@EqualsAndHashCode +class BookReturned implements Serializable { + final String bookName + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + BookReturned(String bookName) { + this.bookName = bookName + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy similarity index 72% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy index 02b875af6f..3f7a37f357 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy @@ -1,14 +1,30 @@ -package io.codearte.accurest.stubrunner.messaging.integration +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.integration import groovy.json.JsonOutput import groovy.json.JsonSlurper -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.messaging.AccurestMessage -import io.codearte.accurest.messaging.AccurestMessaging -import io.codearte.accurest.stubrunner.StubFinder +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.stubrunner.StubFinder +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.ImportResource @@ -27,7 +43,7 @@ import java.util.concurrent.TimeUnit class IntegrationStubRunnerSpec extends Specification { @Autowired StubFinder stubFinder - @Autowired AccurestMessaging messaging + @Autowired ContractVerifierMessaging messaging def setup() { // ensure that message were taken from the queue @@ -41,7 +57,7 @@ class IntegrationStubRunnerSpec extends Specification { // end::client_send[] then: // tag::client_receive[] - AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('outputTest') // end::client_receive[] and: // tag::client_receive_message[] @@ -58,7 +74,7 @@ class IntegrationStubRunnerSpec extends Specification { // end::client_trigger[] then: // tag::client_trigger_receive[] - AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('outputTest') // end::client_trigger_receive[] and: // tag::client_trigger_message[] @@ -71,10 +87,10 @@ class IntegrationStubRunnerSpec extends Specification { def 'should trigger a label for the existing groupId:artifactId'() { when: // tag::trigger_group_artifact[] - stubFinder.trigger('io.codearte.accurest.stubs:integrationService', 'return_book_1') + stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:integrationService', 'return_book_1') // end::trigger_group_artifact[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('outputTest') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -87,7 +103,7 @@ class IntegrationStubRunnerSpec extends Specification { stubFinder.trigger('integrationService', 'return_book_1') // end::trigger_artifact[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('outputTest') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -114,7 +130,7 @@ class IntegrationStubRunnerSpec extends Specification { stubFinder.trigger() // end::trigger_all[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('outputTest') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('outputTest') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -134,7 +150,7 @@ class IntegrationStubRunnerSpec extends Specification { when: messaging.send(new BookReturned('not_matching'), [wrong: 'header_value'], 'input') then: - AccurestMessage receivedMessage = messaging.receiveMessage('outputTest', 100, TimeUnit.MILLISECONDS) + ContractVerifierMessage receivedMessage = messaging.receiveMessage('outputTest', 100, TimeUnit.MILLISECONDS) and: receivedMessage == null } @@ -146,9 +162,9 @@ class IntegrationStubRunnerSpec extends Specification { return json.bookName == 'foo' } - GroovyDsl dsl = + Contract dsl = // tag::sample_dsl[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'return_book_1' input { triggeredBy('bookReturnedTriggered()') @@ -163,9 +179,9 @@ class IntegrationStubRunnerSpec extends Specification { } // end::sample_dsl[] - GroovyDsl dsl2 = + Contract dsl2 = // tag::sample_dsl_2[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'return_book_2' input { messageFrom('input') @@ -188,9 +204,9 @@ class IntegrationStubRunnerSpec extends Specification { } // end::sample_dsl_2[] - GroovyDsl dsl3 = + Contract dsl3 = // tag::sample_dsl_3[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'delete_book' input { messageFrom('delete') diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml new file mode 100644 index 0000000000..911b24bbaa --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo/repository/ +stubrunner.stubs.ids: org.springframework.cloud.contract.verifier.stubs:integrationService:0.0.1-SNAPSHOT \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/integration-context.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml similarity index 50% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/integration-context.xml rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml index c342dc9e94..1fdb1bb847 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/integration-context.xml +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml @@ -1,4 +1,20 @@ + + W7$;qWfsl_EwJs?>QhGTITJp3Q1M(+pm*cllZG#F&C>PgDa z&kjm0DJ{xNO)=C^fv1;BfwB zcuU-}Cbm8Ae8v42HC0UCGBeHjc8^bx>yrO@m##j3vUiVU(&|IKbGPfhW|TiNH>*mj zH|vD^HQ$i(l8vy7r;DC_%DswJhs#j3>DY`qSp$~b=Q}uFJZ{zcp&lu0I#YzH;-t~_zL&3p{+-yQ zs`Ye=!?b?^(oYP`?VMR}U(VcbmB(it;pOow$FK797dB92LIUU%Fo4<~ha5f)^i%+m z0c3<6Kt900amNgx);|AkU;rIG|8n_@T&)bg>Mz^$x;CtszPHokmS1+}B+bbsu1DVQ z^X;nVJ9H@K+1cv%=0~=c$eM3k7a?gQynWM!E7LbAyp9x&`=?|c+N|Tf{OR>r(^W^m z%;H#EbVbwP*Sxoe>RJ8r6FQES?d2~|ykHsnxa(w!Ks+_=h(k-YI#%kBXORS zt4T@6;qJoTRW4;4gXTP%)EK<%GRI{RH&wIylMJr>X51=y*zoCvU-G9C_PAvK)BpR0 zZ}*M2`_gZpKWj9h`FG>qzl?~$It&af?(dDE8-aoK6NuIDq$ZctoYa!k6y%_?1qPED zW>ER|ZR9&-z~l1#i}o(nsR4Ekf&xiNPDu_NJA0#7sgR^KOx5{-bzw5M|K824TPH5;_|_IP-E>pwqqo0avt=06s-1G~v%AV?>$c~KORrzZ z-Ll#_+q4#NgzQM=dM147=K1)E)iW-ym^#bv`(y6YA=6!yUFQC8vSw-5F%FJRPu$}0 z!seChs{7}BbO&}0pcx)DatEXs1eP>v0!g?wq*4go1dwW25eF)4AV7fO zuVWdIiBz88(+Kh>1b{Ry1Tv8{!V4mh33AMke1=&NNq`LiW;uq2#;Z6?z+Nn|LW(7{ zA_>_x%v_CZ+c%)4*xZY38zPSbZ3E?TJhowG3uN1rnQ_~Oo=JdqfiejeyI^StTZ#h* hBrxs#bu?i?u?wF50=!w-K&m)^unrje89;Rm3;^?$E1CcR literal 0 HcmV?d00001 diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..0581ac022d --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + integrationService + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..e6c62c5897 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + integrationService + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml new file mode 100644 index 0000000000..f619bafb54 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + integrationService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml new file mode 100644 index 0000000000..f619bafb54 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + integrationService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc similarity index 64% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc index aa9af8950d..670ea5201a 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc @@ -1,6 +1,6 @@ === Stub Runner Messaging Stream -Accurest Stub Runner's messaging module gives you an easy way to integrate with Spring Stream. +Spring Cloud Contract Verifier Stub Runner's messaging module gives you an easy way to integrate with Spring Stream. For the provided artifacts it will automatically download the stubs and register the required routes. @@ -14,7 +14,7 @@ To use it you have to add the following dependency to your project (example for [source,groovy,indent=0] ---- -testCompile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}" +testCompile "org.springframework.cloud.contract:stub-runner-messaging-stream:${verifierVersion}" ---- ==== Examples @@ -58,14 +58,14 @@ Let's consider the following contracts (let' number it with *1*): [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=sample_dsl,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=sample_dsl,indent=0] ---- and number *2* [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=sample_dsl_2,indent=0] ---- and the following Spring configuration: @@ -82,21 +82,21 @@ So as to trigger a message via the `return_book_1` label we'll use the `StubTrig [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger,indent=0] ---- Next we'll want to listen to the output of the message sent to a channel whose `destination` is `returnBook` [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger_receive,indent=0] ---- And the received message would pass the following assertions [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_trigger_message,indent=0] ---- ===== Scenario 2 (output triggered by input) @@ -105,21 +105,21 @@ Since the route is set for you it's enough to just send a message to the `bookSt [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_send,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_send,indent=0] ---- Next we'll want to listen to the output of the message sent to `returnBook` [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_receive,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_receive,indent=0] ---- And the received message would pass the following assertions [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_receive_message,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=client_receive_message,indent=0] ---- ===== Scenario 3 (input with no output) @@ -128,5 +128,5 @@ Since the route is set for you it's enough to just send a message to the `{outpu [source,groovy] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy[tags=trigger_no_output,indent=0] ---- diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle new file mode 100644 index 0000000000..30791e97ed --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String verifier = "spring-cloud-contract-verifier" +String stubRunner = "spring-cloud-contract-stub-runner" + +dependencies { + compile project(":$stubRunner-root:$stubRunner-spring") + compile project(":$verifier-root:$verifier-messaging-root:$verifier-stream") + compile "org.springframework.integration:spring-integration-java-dsl:${springIntegrationDslVersion}" + + testCompile "org.springframework:spring-context:${springVersion}" + testCompile "org.springframework:spring-beans:${springVersion}" + testCompile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } +} \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy similarity index 73% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy index 41813d1789..7a9c769dbc 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy @@ -1,13 +1,29 @@ -package io.codearte.accurest.stubrunner.messaging.stream +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.stream import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.stubrunner.BatchStubRunner -import io.codearte.accurest.stubrunner.StubConfiguration -import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration import org.slf4j.Logger import org.slf4j.LoggerFactory import org.springframework.beans.factory.config.AutowireCapableBeanFactory +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.stubrunner.BatchStubRunner +import org.springframework.cloud.contract.stubrunner.StubConfiguration +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerConfiguration import org.springframework.cloud.stream.config.BindingProperties import org.springframework.cloud.stream.config.ChannelBindingServiceProperties import org.springframework.context.Lifecycle @@ -34,10 +50,10 @@ class StubRunnerStreamConfiguration { @Bean FlowRegistrar flowRegistrar(AutowireCapableBeanFactory beanFactory, BatchStubRunner batchStubRunner) { - Map> accurestContracts = batchStubRunner.accurestContracts - accurestContracts.each { StubConfiguration key, Collection value -> + Map> contracts = batchStubRunner.contracts + contracts.each { StubConfiguration key, Collection value -> String name = "${key.groupId}_${key.artifactId}" - value.findAll { it?.input?.messageFrom?.clientValue }.each { GroovyDsl dsl -> + value.findAll { it?.input?.messageFrom?.clientValue }.each { Contract dsl -> String flowName = "${name}_${dsl.label}_${dsl.hashCode()}" String from = resolvedDestination(beanFactory, dsl.input.messageFrom.clientValue) IntegrationFlowBuilder builder = IntegrationFlows.from(from) diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy similarity index 58% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy index d32339b504..ca55e84d73 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy @@ -1,14 +1,30 @@ -package io.codearte.accurest.stubrunner.messaging.stream +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.stream import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import com.toomuchcoding.jsonassert.JsonVerifiable import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.messaging.AccurestObjectMapper -import io.codearte.accurest.util.JsonPaths -import io.codearte.accurest.util.JsonToJsonPathsConverter +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper +import org.springframework.cloud.contract.verifier.util.JsonPaths +import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter import org.springframework.integration.core.MessageSelector import org.springframework.messaging.Message @@ -22,10 +38,10 @@ import java.util.regex.Pattern @CompileStatic class StubRunnerStreamMessageSelector implements MessageSelector { - private final GroovyDsl groovyDsl - private final AccurestObjectMapper objectMapper = new AccurestObjectMapper() + private final Contract groovyDsl + private final ContractVerifierObjectMapper objectMapper = new ContractVerifierObjectMapper() - StubRunnerStreamMessageSelector(GroovyDsl groovyDsl) { + StubRunnerStreamMessageSelector(Contract groovyDsl) { this.groovyDsl = groovyDsl } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy new file mode 100644 index 0000000000..949304099c --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy @@ -0,0 +1,48 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.stream + +import org.springframework.cloud.contract.verifier.util.BodyAsStringUtil +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.integration.transformer.GenericTransformer +import org.springframework.messaging.Message +import org.springframework.messaging.MessageHeaders +import org.springframework.messaging.support.MessageBuilder + +/** + * Sends forward a message defined in the DSL. + * + * @author Marcin Grzejszczak + */ +class StubRunnerStreamTransformer implements GenericTransformer, Message> { + + private final Contract groovyDsl + + StubRunnerStreamTransformer(Contract groovyDsl) { + this.groovyDsl = groovyDsl + } + + @Override + Message transform(Message source) { + if (!groovyDsl.outputMessage) { + return source + } + String payload = BodyAsStringUtil.extractClientValueFrom(groovyDsl.outputMessage.body) + Map headers = groovyDsl.outputMessage.headers.asStubSideMap() + return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..35f2e3fddc --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.contract.stubrunner.messaging.stream.StubRunnerStreamConfiguration diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy new file mode 100644 index 0000000000..49dea202eb --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.stream + +import com.fasterxml.jackson.annotation.JsonCreator +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode + +@CompileStatic +@EqualsAndHashCode +class BookReturned implements Serializable { + final String bookName + + @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) + BookReturned(String bookName) { + this.bookName = bookName + } +} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy similarity index 72% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy index 0233009851..00e9c495b1 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy @@ -1,14 +1,30 @@ -package io.codearte.accurest.stubrunner.messaging.stream +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.messaging.stream import groovy.json.JsonOutput import groovy.json.JsonSlurper -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.messaging.AccurestMessage -import io.codearte.accurest.messaging.AccurestMessaging -import io.codearte.accurest.stubrunner.StubFinder +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage +import org.springframework.cloud.contract.stubrunner.StubFinder import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import org.springframework.cloud.stream.annotation.EnableBinding import org.springframework.cloud.stream.messaging.Sink import org.springframework.cloud.stream.messaging.Source @@ -29,7 +45,7 @@ import java.util.concurrent.TimeUnit class StreamStubRunnerSpec extends Specification { @Autowired StubFinder stubFinder - @Autowired AccurestMessaging messaging + @Autowired ContractVerifierMessaging messaging def setup() { // ensure that message were taken from the queue @@ -43,7 +59,7 @@ class StreamStubRunnerSpec extends Specification { // end::client_send[] then: // tag::client_receive[] - AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('returnBook') // end::client_receive[] and: // tag::client_receive_message[] @@ -60,7 +76,7 @@ class StreamStubRunnerSpec extends Specification { // end::client_trigger[] then: // tag::client_trigger_receive[] - AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('returnBook') // end::client_trigger_receive[] and: // tag::client_trigger_message[] @@ -73,10 +89,10 @@ class StreamStubRunnerSpec extends Specification { def 'should trigger a label for the existing groupId:artifactId'() { when: // tag::trigger_group_artifact[] - stubFinder.trigger('io.codearte.accurest.stubs:streamService', 'return_book_1') + stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:streamService', 'return_book_1') // end::trigger_group_artifact[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('returnBook') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -89,7 +105,7 @@ class StreamStubRunnerSpec extends Specification { stubFinder.trigger('streamService', 'return_book_1') // end::trigger_artifact[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('returnBook') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -116,7 +132,7 @@ class StreamStubRunnerSpec extends Specification { stubFinder.trigger() // end::trigger_all[] then: - AccurestMessage receivedMessage = messaging.receiveMessage('returnBook') + ContractVerifierMessage receivedMessage = messaging.receiveMessage('returnBook') and: receivedMessage != null assertJsons(receivedMessage.payload) @@ -136,7 +152,7 @@ class StreamStubRunnerSpec extends Specification { when: messaging.send(new BookReturned('not_matching'), [wrong: 'header_value'], 'bookStorage') then: - AccurestMessage receivedMessage = messaging.receiveMessage('returnBook', 100, TimeUnit.MILLISECONDS) + ContractVerifierMessage receivedMessage = messaging.receiveMessage('returnBook', 100, TimeUnit.MILLISECONDS) and: receivedMessage == null } @@ -148,9 +164,9 @@ class StreamStubRunnerSpec extends Specification { return json.bookName == 'foo' } - GroovyDsl dsl = + Contract dsl = // tag::sample_dsl[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'return_book_1' input { triggeredBy('bookReturnedTriggered()') @@ -165,9 +181,9 @@ class StreamStubRunnerSpec extends Specification { } // end::sample_dsl[] - GroovyDsl dsl2 = + Contract dsl2 = // tag::sample_dsl_2[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'return_book_2' input { messageFrom('bookStorage') @@ -190,9 +206,9 @@ class StreamStubRunnerSpec extends Specification { } // end::sample_dsl_2[] - GroovyDsl dsl3 = + Contract dsl3 = // tag::sample_dsl_3[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { label 'delete_book' input { messageFrom('delete') diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml similarity index 66% rename from stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml index 0bcac69997..f7c3f12f4a 100644 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/application.yml +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml @@ -1,5 +1,5 @@ stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs +stubrunner.stubs.ids: org.springframework.cloud.contract.verifier.stubs:streamService:0.0.1-SNAPSHOT:stubs spring: cloud: diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml new file mode 100644 index 0000000000..f14e885df3 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + streamService + 0.0.1-SNAPSHOT + + + true + + 20160409062112 + + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar new file mode 100644 index 0000000000000000000000000000000000000000..2fee7265b6d3ae717130c9a257d42c6610bbb129 GIT binary patch literal 1809 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJs?>QhRC=J9xpEKop}t%<6&fA&|r|kswXKw zKRYP3q_ik6HN{Xby(mAwtTHr&lYzOaEGfJgh)XND85mi<1C3w-nQYp3aMd9L0oUs< z!&~x}HL=~A!?N7qGCcgd3 z>>agvQn1s9{oz4gx1ASmXumu2=1j*|EpsyrV!eY7vtQE4YAsgIGU-csdxSM3gI(cb zglZh;$D-Pgv!^L9+1{cV+3022IQ!%j(MJ*MDi5(4pVj-|)4X+4v+lxk6%YLRPBQ;_ z*nVc?&b0i0X*wEw`%VR)igtN_sQLCCiK%WOnm6u-TYd?efP$}1n!*!up>eQrmqF);L#v{CxchTd`l%%FM45 z>LQ-*Qt}cg{mK1KP-fE^pVHZ_7nv4*Uom~>KMUhZA6BIkA1j(Oz8tY_%z1YEoX)Zf zGkWt8<%1SlK>|u)Ncl83v7jI`FTEI?PZ^m+m~j_BK#f2k!0^@)M8gZC0B=-n=!FqT zF$gSa)C7`nZAe8Ex(OiFuyPMn0zrTP!(YcTAQQ>)_%wq22>~FD3xP}|jquV5WP%(s zB-de + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + streamService + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml new file mode 100644 index 0000000000..001cf26899 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + streamService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml new file mode 100644 index 0000000000..001cf26899 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + streamService + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring-cloud/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/README.adoc similarity index 94% rename from stub-runner/stub-runner-spring-cloud/README.adoc rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/README.adoc index 25e0ca4341..7ea59a2a37 100644 --- a/stub-runner/stub-runner-spring-cloud/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/README.adoc @@ -4,7 +4,7 @@ Registers the stubs in the provided Service Discovery. It's enough to add the ja [source,groovy,indent=0] ---- -io.codearte.accurest:stub-runner-spring-cloud +org.springframework.cloud.contract:stub-runner-spring-cloud ---- and the Stub Runner autoconfiguration should be picked up. diff --git a/stub-runner/stub-runner-spring-cloud/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle similarity index 55% rename from stub-runner/stub-runner-spring-cloud/build.gradle rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle index 7e3bc4a9a2..b015f00ef4 100644 --- a/stub-runner/stub-runner-spring-cloud/build.gradle +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle @@ -1,5 +1,23 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +String stubRunner = "spring-cloud-contract-stub-runner" + dependencies { - compile project(':stub-runner-root:stub-runner-spring') + compile project(":$stubRunner-root:$stubRunner-spring") compile localGroovy() // TODO: should be compile only diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java similarity index 66% rename from stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java index c69ca674dc..79d405b9b0 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubMapperProperties.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner.spring.cloud; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring.cloud; import java.util.HashMap; import java.util.Map; @@ -17,6 +33,8 @@ import org.springframework.boot.context.properties.ConfigurationProperties; * fraudDetectionServer: someNameThatShouldMapFraudDetectionServer * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ @ConfigurationProperties("stubrunner.stubs") public class StubMapperProperties { diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java similarity index 71% rename from stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java index a6615fd5b0..e4905c7814 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner.spring.cloud; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring.cloud; import java.net.URI; import java.net.URL; @@ -10,15 +26,17 @@ import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClient; -import io.codearte.accurest.stubrunner.RunningStubs; -import io.codearte.accurest.stubrunner.StubFinder; -import io.codearte.accurest.stubrunner.util.StringUtils; +import org.springframework.cloud.contract.stubrunner.RunningStubs; +import org.springframework.cloud.contract.stubrunner.StubFinder; +import org.springframework.cloud.contract.stubrunner.util.StringUtils; /** * Custom version of {@link DiscoveryClient} that tries to find an instance * in one of the started WireMock servers * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ public class StubRunnerDiscoveryClient implements DiscoveryClient { diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerServiceInstance.java similarity index 57% rename from stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerServiceInstance.java index ba5ee8249f..d34340f98e 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerServiceInstance.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerServiceInstance.java @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner.spring.cloud; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring.cloud; import java.net.URI; import java.util.HashMap; @@ -10,6 +26,8 @@ import org.springframework.cloud.client.ServiceInstance; * {@link ServiceInstance} with a helpful constructor * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ public class StubRunnerServiceInstance implements ServiceInstance { diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java similarity index 64% rename from stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java index b5d78bfe78..6a5ec3f72d 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java @@ -1,22 +1,40 @@ -package io.codearte.accurest.stubrunner.spring.cloud; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring.cloud; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.cloud.contract.stubrunner.spring.StubRunnerConfiguration; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Primary; -import io.codearte.accurest.stubrunner.StubFinder; -import io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration; +import org.springframework.cloud.contract.stubrunner.StubFinder; /** * Wraps {@link DiscoveryClient} in a Stub Runner implementation that tries to find * a corresponding WireMock server for a searched dependency + * + * @since 1.0.0 */ @Configuration @EnableConfigurationProperties diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java similarity index 53% rename from stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java index 9bffb4c1ea..7e886e6eac 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java @@ -1,7 +1,23 @@ -package io.codearte.accurest.stubrunner.spring.cloud.ribbon; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring.cloud.ribbon; import com.netflix.loadbalancer.ServerList; -import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; +import org.springframework.cloud.contract.stubrunner.spring.cloud.StubMapperProperties; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java similarity index 67% rename from stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java index fc4e801e0a..9ba1002603 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java @@ -1,9 +1,25 @@ -package io.codearte.accurest.stubrunner.spring.cloud.ribbon; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring.cloud.ribbon; import com.netflix.client.config.IClientConfig; import com.netflix.loadbalancer.ServerList; -import io.codearte.accurest.stubrunner.StubFinder; -import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; +import org.springframework.cloud.contract.stubrunner.StubFinder; +import org.springframework.cloud.contract.stubrunner.spring.cloud.StubMapperProperties; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -13,6 +29,8 @@ import org.springframework.beans.factory.config.BeanPostProcessor; * be picked from the list of available WireMock instance if one is available. * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ class StubRunnerRibbonBeanPostProcessor implements BeanPostProcessor { diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java similarity index 56% rename from stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java index 68aedc86ea..b03d729a5f 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner.spring.cloud.ribbon; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring.cloud.ribbon; import com.netflix.loadbalancer.Server; import com.netflix.loadbalancer.ServerList; diff --git a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java similarity index 70% rename from stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java index 2feca19e9b..e0efe4bc8d 100644 --- a/stub-runner/stub-runner-spring-cloud/src/main/groovy/io/codearte/accurest/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java @@ -1,23 +1,42 @@ -package io.codearte.accurest.stubrunner.spring.cloud.ribbon; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import com.netflix.client.config.IClientConfig; -import com.netflix.loadbalancer.Server; -import com.netflix.loadbalancer.ServerList; -import io.codearte.accurest.stubrunner.RunningStubs; -import io.codearte.accurest.stubrunner.StubConfiguration; -import io.codearte.accurest.stubrunner.StubFinder; -import io.codearte.accurest.stubrunner.spring.cloud.StubMapperProperties; -import io.codearte.accurest.stubrunner.util.StringUtils; +package org.springframework.cloud.contract.stubrunner.spring.cloud.ribbon; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; +import com.netflix.client.config.IClientConfig; +import com.netflix.loadbalancer.Server; +import com.netflix.loadbalancer.ServerList; + +import org.springframework.cloud.contract.stubrunner.RunningStubs; +import org.springframework.cloud.contract.stubrunner.StubConfiguration; +import org.springframework.cloud.contract.stubrunner.StubFinder; +import org.springframework.cloud.contract.stubrunner.spring.cloud.StubMapperProperties; +import org.springframework.cloud.contract.stubrunner.util.StringUtils; + /** * Stub Runner representation of a server list * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ class StubRunnerRibbonServerList implements ServerList { diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..fd191f3591 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories @@ -0,0 +1,4 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.contract.stubrunner.spring.cloud.StubRunnerSpringCloudAutoConfiguration,\ +org.springframework.cloud.contract.stubrunner.spring.cloud.ribbon.StubRunnerRibbonAutoConfiguration diff --git a/stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy similarity index 74% rename from stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy index 741d7ccbe0..8a3c6f886e 100644 --- a/stub-runner/stub-runner-spring-cloud/src/test/groovy/io/codearte/accurest/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy @@ -1,11 +1,27 @@ -package io.codearte.accurest.stubrunner.spring.cloud +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring.cloud -import io.codearte.accurest.stubrunner.StubFinder import org.apache.curator.test.TestingServer import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.test.SpringApplicationContextLoader import org.springframework.boot.test.WebIntegrationTest +import org.springframework.cloud.contract.stubrunner.StubFinder import org.springframework.cloud.client.discovery.EnableDiscoveryClient import org.springframework.cloud.client.loadbalancer.LoadBalanced import org.springframework.cloud.zookeeper.discovery.ZookeeperServiceDiscovery diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/application.yml similarity index 56% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/application.yml index 051a8a328e..629b688f80 100644 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/application.yml +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/application.yml @@ -1,5 +1,5 @@ stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer +stubrunner.stubs.ids: org.springframework.cloud.contract.verifier.stubs:loanIssuance,org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer stubrunner.stubs.idsToServiceIds: ivyNotation: someValueInsideYourCode diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml new file mode 100644 index 0000000000..7eecabf2f2 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml @@ -0,0 +1,30 @@ + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..40610c8cdb --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml new file mode 100644 index 0000000000..281b9b3b80 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..59db343686 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + loanIssuance + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml new file mode 100644 index 0000000000..615428dae6 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + loanIssuance + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062111 + + diff --git a/stub-runner/stub-runner-spring/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/README.adoc similarity index 80% rename from stub-runner/stub-runner-spring/README.adoc rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/README.adoc index 51342e9c14..38169894bf 100644 --- a/stub-runner/stub-runner-spring/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/README.adoc @@ -10,7 +10,7 @@ its methods as presented below: [source,groovy,indent=0] ---- -include::src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=test] +include::src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=test] ---- for the following configuration file: diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/build.gradle new file mode 100644 index 0000000000..32586d07e3 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/build.gradle @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +description = 'Spring configuration for stub-runner' + +String stubRunner = "spring-cloud-contract-stub-runner" + +dependencies { + compile project(":$stubRunner-root:$stubRunner") + + compile localGroovy() + compile "org.springframework:spring-context:${springVersion}" + + testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + testCompile "org.springframework.boot:spring-boot-starter:${springBootVersion}" + testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" + testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { + exclude(group: 'org.codehaus.groovy') + } + testCompile 'ch.qos.logback:logback-classic:1.1.3' +} diff --git a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java similarity index 60% rename from stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java index 5ba1a3cc66..bea711f6f1 100644 --- a/stub-runner/stub-runner-spring/src/main/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfiguration.java +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java @@ -1,30 +1,46 @@ -package io.codearte.accurest.stubrunner.spring; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring; + +import java.io.IOException; -import io.codearte.accurest.messaging.AccurestMessaging; -import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging; -import io.codearte.accurest.stubrunner.AetherStubDownloader; -import io.codearte.accurest.stubrunner.BatchStubRunner; -import io.codearte.accurest.stubrunner.BatchStubRunnerFactory; -import io.codearte.accurest.stubrunner.StubDownloader; -import io.codearte.accurest.stubrunner.StubRunner; -import io.codearte.accurest.stubrunner.StubRunnerOptions; -import io.codearte.accurest.stubrunner.StubRunnerOptionsBuilder; -import io.codearte.accurest.stubrunner.StubRunning; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.contract.stubrunner.AetherStubDownloader; +import org.springframework.cloud.contract.stubrunner.BatchStubRunner; +import org.springframework.cloud.contract.stubrunner.BatchStubRunnerFactory; +import org.springframework.cloud.contract.stubrunner.StubDownloader; +import org.springframework.cloud.contract.stubrunner.StubRunner; +import org.springframework.cloud.contract.stubrunner.StubRunnerOptions; +import org.springframework.cloud.contract.stubrunner.StubRunnerOptionsBuilder; +import org.springframework.cloud.contract.stubrunner.StubRunning; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging; +import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; -import java.io.IOException; - /** * Configuration that initializes a {@link BatchStubRunner} that runs {@link StubRunner} instance for each stub */ @Configuration public class StubRunnerConfiguration { - @Autowired(required = false) AccurestMessaging accurestMessaging; + @Autowired(required = false) ContractVerifierMessaging contractVerifierMessaging; @Autowired(required = false) StubDownloader stubDownloader; /** @@ -56,7 +72,7 @@ public class StubRunnerConfiguration { .build(); BatchStubRunner batchStubRunner = new BatchStubRunnerFactory(stubRunnerOptions, stubDownloader != null ? stubDownloader : new AetherStubDownloader(stubRunnerOptions), - accurestMessaging != null ? accurestMessaging : new NoOpAccurestMessaging()).buildBatchStubRunner(); + contractVerifierMessaging != null ? contractVerifierMessaging : new NoOpContractVerifierMessaging()).buildBatchStubRunner(); // TODO: Consider running it in a separate thread batchStubRunner.runStubs(); return batchStubRunner; diff --git a/accurest-messaging/accurest-messaging-camel/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/resources/META-INF/spring.factories similarity index 53% rename from accurest-messaging/accurest-messaging-camel/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/resources/META-INF/spring.factories index 318eec3472..d39588e8dc 100644 --- a/accurest-messaging/accurest-messaging-camel/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/resources/META-INF/spring.factories @@ -1,3 +1,3 @@ # Auto Configuration org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.messaging.camel.AccurestCamelConfiguration +org.springframework.cloud.contract.stubrunner.spring.StubRunnerConfiguration \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy new file mode 100644 index 0000000000..4d9b01856d --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy @@ -0,0 +1,57 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.spring + +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.boot.autoconfigure.EnableAutoConfiguration +import org.springframework.boot.test.SpringApplicationContextLoader +import org.springframework.cloud.contract.stubrunner.StubFinder +import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Import +import org.springframework.test.context.ContextConfiguration +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +// tag::test[] +@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) +class StubRunnerConfigurationSpec extends Specification { + + @Autowired StubFinder stubFinder + + def 'should start WireMock servers'() { + expect: 'WireMocks are running' + stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance') != null + stubFinder.findStubUrl('loanIssuance') != null + stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs', 'loanIssuance') + stubFinder.findStubUrl('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer') != null + and: + stubFinder.findAllRunningStubs().isPresent('loanIssuance') + stubFinder.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs', 'fraudDetectionServer') + stubFinder.findAllRunningStubs().isPresent('org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer') + and: 'Stubs were registered' + "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' + "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' + } + + @Configuration + @Import(StubRunnerConfiguration) + @EnableAutoConfiguration + static class Config {} +} +// end::test[] \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml new file mode 100644 index 0000000000..4f618057e1 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml @@ -0,0 +1,2 @@ +stubrunner.stubs.repository.root: classpath:m2repo/repository/ +stubrunner.stubs.ids: org.springframework.cloud.contract.verifier.stubs:loanIssuance,org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml new file mode 100644 index 0000000000..7eecabf2f2 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml @@ -0,0 +1,30 @@ + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..40610c8cdb --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml new file mode 100644 index 0000000000..281b9b3b80 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + fraudDetectionServer + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062112 + + diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom new file mode 100644 index 0000000000..59db343686 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom @@ -0,0 +1,25 @@ + + + + + 4.0.0 + org.springframework.cloud.contract.verifier.stubs + loanIssuance + 0.0.1-SNAPSHOT + pom + diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml new file mode 100644 index 0000000000..615428dae6 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml @@ -0,0 +1,28 @@ + + + + + org.springframework.cloud.contract.verifier.stubs + loanIssuance + 0.0.1-SNAPSHOT + + + 0.0.1-SNAPSHOT + + 20160409062111 + + diff --git a/stub-runner/stub-runner/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/README.adoc similarity index 84% rename from stub-runner/stub-runner/README.adoc rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/README.adoc index 075d1c7a6a..fd0ace56e4 100644 --- a/stub-runner/stub-runner/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/README.adoc @@ -41,14 +41,14 @@ Just call the following command: [source,groovy,indent=0] ---- -./gradlew stub-runner-root:stub-runner:shadowJar -PfatJar +./gradlew spring-cloud-contract-stub-runner-root:spring-cloud-contract-stub-runner:shadowJar -PfatJar ---- and inside the `build/lib` there will be a Fat Jar with classifier `fatJar` waiting for you to execute. E.g. [source,groovy,indent=0] ---- -java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h:i +java -jar spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/build/libs/spring-cloud-contract-stub-runner-1.0.0-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h:i ---- ==== Stub runner configuration @@ -57,14 +57,14 @@ You can configure the stub runner by either passing the full arguments list with [source,groovy,indent=0] ---- -./gradlew stub-runner-root:stub-runner:run -Pargs="-c pl -minp 10000 -maxp 10005 -s a:b:c,d:e,f:g:h" +./gradlew spring-cloud-contract-stub-runner-root:spring-cloud-contract-stub-runner:run -Pargs="-c pl -minp 10000 -maxp 10005 -s a:b:c,d:e,f:g:h" ---- or each parameter separately with a `-P` prefix and without the hyphen `-` in the name of the param [source,groovy,indent=0] ---- -./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h +./gradlew spring-cloud-contract-stub-runner-root:spring-cloud-contract-stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h ---- ===== HTTP Stubs diff --git a/stub-runner/stub-runner/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/build.gradle similarity index 75% rename from stub-runner/stub-runner/build.gradle rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/build.gradle index c633e222aa..dc362bdbdb 100644 --- a/stub-runner/stub-runner/build.gradle +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/build.gradle @@ -1,11 +1,29 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + description = 'Runs stubs for service collaborators' apply plugin: 'application' -mainClassName = 'io.codearte.accurest.stubrunner.StubRunnerMain' +mainClassName = 'org.springframework.cloud.stubrunner.StubRunnerMain' + +String verifier = "spring-cloud-contract-verifier" dependencies { - compile project(':accurest-core') - compile project(':accurest-messaging-root:accurest-messaging-core') + compile project(":$verifier-root:$verifier-core") + compile project(":$verifier-root:$verifier-messaging-root:$verifier-messaging-core") compile 'org.codehaus.groovy:groovy-all:2.4.4' compile "com.github.tomakehurst:wiremock:$wiremockVersion" compile 'javax.servlet:javax.servlet-api:3.1.0' @@ -46,7 +64,7 @@ Object getPropertyByEither(String paramName1, String paramName2, Object defaultV } run { - main = 'io.codearte.accurest.stubrunner.StubRunnerMain' + main = 'org.springframework.cloud.stubrunner.StubRunnerMain' List argumentList if (arguments) { argumentList = (arguments.split(' ') as List).findAll { it != null } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherFactories.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherFactories.groovy similarity index 76% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherFactories.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherFactories.groovy index 4999d49b93..df67a84c25 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherFactories.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherFactories.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import org.apache.maven.repository.internal.MavenRepositorySystemUtils import org.eclipse.aether.DefaultRepositorySystemSession diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.groovy similarity index 81% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.groovy index 271d98cceb..588e26c0b4 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AetherStubDownloader.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j @@ -14,10 +30,10 @@ import org.eclipse.aether.resolution.VersionRangeResult import org.eclipse.aether.resolution.VersionRequest import org.eclipse.aether.resolution.VersionResult -import static io.codearte.accurest.stubrunner.AetherFactories.newRepositories -import static io.codearte.accurest.stubrunner.AetherFactories.newRepositorySystem -import static io.codearte.accurest.stubrunner.AetherFactories.newSession -import static io.codearte.accurest.stubrunner.util.ZipCategory.unzipTo +import static AetherFactories.newRepositories +import static AetherFactories.newRepositorySystem +import static AetherFactories.newSession +import static org.springframework.cloud.contract.stubrunner.util.ZipCategory.unzipTo import static java.nio.file.Files.createTempDirectory /** @@ -27,7 +43,7 @@ import static java.nio.file.Files.createTempDirectory @Slf4j class AetherStubDownloader implements StubDownloader { - private static final String ACCUREST_TEMP_DIR_PREFIX = 'accurest' + private static final String TEMP_DIR_PREFIX = 'contracts' private static final String ARTIFACT_EXTENSION = 'jar' private static final String LATEST_ARTIFACT_VERSION = '(,]' private static final String LATEST_VERSION_IN_IVY = '+' @@ -46,7 +62,7 @@ class AetherStubDownloader implements StubDownloader { } /** - * Used by Accurest Maven Plugin + * Used by the Maven Plugin * * @param repositorySystem * @param remoteRepositories - remote artifact repositories @@ -80,7 +96,9 @@ class AetherStubDownloader implements StubDownloader { try { ArtifactResult result = repositorySystem.resolveArtifact(session, request) log.info("Resolved artifact $artifact to ${result.artifact.file}") - return unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) + File temporaryFile = unpackStubJarToATemporaryFolder(result.artifact.file.toURI()) + log.info("Unpacked file to [$temporaryFile]") + return temporaryFile } catch (Exception e) { log.warn("Exception occured while trying to download a stub for group [$stubsGroup] module [$stubsModule] and classifier [$classifier] in $remoteRepos", e) return null @@ -127,7 +145,7 @@ class AetherStubDownloader implements StubDownloader { } private static File unpackStubJarToATemporaryFolder(URI stubJarUri) { - File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(ACCUREST_TEMP_DIR_PREFIX).toFile() + File tmpDirWhereStubsWillBeUnzipped = createTempDirectory(TEMP_DIR_PREFIX).toFile() tmpDirWhereStubsWillBeUnzipped.deleteOnExit() log.info("Unpacking stub from JAR [URI: ${stubJarUri}]") unzipTo(new File(stubJarUri), tmpDirWhereStubsWillBeUnzipped) diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy new file mode 100644 index 0000000000..254bc0634b --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import groovy.transform.ToString + +/** + * Arguments passed to the {@link StubRunner} application + * + * @see StubRunner + */ +@CompileStatic +@ToString(includeNames = true) +@PackageScope +class Arguments { + final StubRunnerOptions stubRunnerOptions + final String context + final String repositoryPath + final StubConfiguration stub + + Arguments(StubRunnerOptions stubRunnerOptions, String repositoryPath = "", StubConfiguration stub = null) { + this.stubRunnerOptions = stubRunnerOptions + this.context = context + this.repositoryPath = repositoryPath + this.stub = stub + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScanner.groovy similarity index 76% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScanner.groovy index 36251d4524..d493199106 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/AvailablePortScanner.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScanner.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy similarity index 76% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy index c2c20567dd..978ca3e109 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunner.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy @@ -1,7 +1,23 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic -import io.codearte.accurest.dsl.GroovyDsl +import org.springframework.cloud.contract.verifier.dsl.Contract /** * Manages lifecycle of multiple {@link StubRunner} instances. * @@ -49,11 +65,11 @@ class BatchStubRunner implements StubRunning { } @Override - Map> getAccurestContracts() { - return stubRunners.inject([:]) { Map> map, StubRunner stubRunner -> - map.putAll(stubRunner.accurestContracts ?: [:]) + Map> getContracts() { + return stubRunners.inject([:]) { Map> map, StubRunner stubRunner -> + map.putAll(stubRunner.contracts ?: [:]) return map - } as Map> + } as Map> } @Override diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy new file mode 100644 index 0000000000..6261afe289 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy @@ -0,0 +1,59 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import groovy.transform.CompileStatic +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging + +/** + * Manages lifecycle of multiple {@link StubRunner} instances. + * + * @see StubRunner + * @see BatchStubRunner + */ +@CompileStatic +class BatchStubRunnerFactory { + + private final StubRunnerOptions stubRunnerOptions + private final StubDownloader stubDownloader + private final ContractVerifierMessaging contractVerifierMessaging + + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions) { + this(stubRunnerOptions, new AetherStubDownloader(stubRunnerOptions), new NoOpContractVerifierMessaging()) + } + + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, ContractVerifierMessaging contractVerifierMessaging) { + this(stubRunnerOptions, new AetherStubDownloader(stubRunnerOptions), contractVerifierMessaging) + } + + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader) { + this(stubRunnerOptions, stubDownloader, new NoOpContractVerifierMessaging()) + } + + BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader, ContractVerifierMessaging contractVerifierMessaging) { + this.stubRunnerOptions = stubRunnerOptions + this.stubDownloader = stubDownloader + this.contractVerifierMessaging = contractVerifierMessaging + } + + BatchStubRunner buildBatchStubRunner() { + StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, stubDownloader, contractVerifierMessaging) + return new BatchStubRunner(stubRunnerFactory.createStubsFromServiceConfiguration()) + } + +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy new file mode 100644 index 0000000000..252a60510c --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import org.springframework.cloud.contract.verifier.dsl.Contract + +/** + * @author Marcin Grzejszczak + */ +@PackageScope +@CompileStatic +class GroovyDslWrapper { + + @Delegate final Contract groovyDsl + + GroovyDslWrapper(Contract groovyDsl) { + this.groovyDsl = groovyDsl + } + + boolean hasHttpPart() { + return groovyDsl.request + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy new file mode 100644 index 0000000000..d99d288ee0 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy @@ -0,0 +1,28 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import groovy.transform.InheritConstructors + +/** + * Exception thrown when message is not matched + * + * @author Marcin Grzejszczak + */ +@InheritConstructors +class MessageNotMatchingException extends RuntimeException { +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/RunningStubs.groovy similarity index 71% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/RunningStubs.groovy index 90520ca15d..d0d0b3f657 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/RunningStubs.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/RunningStubs.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubConfiguration.groovy similarity index 84% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubConfiguration.groovy index 5d04e09850..82daa2d0cc 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubConfiguration.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubConfiguration.groovy @@ -1,9 +1,26 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileDynamic import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode -import io.codearte.accurest.stubrunner.util.StringUtils +import org.springframework.cloud.contract.stubrunner.util.StringUtils + /** * Represents a configuration of a single stub. The stub can be described * by groupId:artifactId:classifier notation diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy new file mode 100644 index 0000000000..c203c5659d --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy @@ -0,0 +1,31 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import org.springframework.cloud.contract.verifier.dsl.Contract + +/** + * @author Marcin Grzejszczak + */ +@CompileStatic +@EqualsAndHashCode +class StubData { + final Integer port + final List contracts +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy new file mode 100644 index 0000000000..fba3a207a1 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy @@ -0,0 +1,28 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +interface StubDownloader { + + /** + * Returns a mapping of updated StubConfiguration (it will contain the resolved version) and the location of the downloaded JAR. + * If there was no artifact this method will return {@code null}. + */ + Map.Entry downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration) + + +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy new file mode 100644 index 0000000000..368494fb04 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import org.springframework.cloud.contract.verifier.dsl.Contract + +interface StubFinder extends StubTrigger { + /** + * For the given groupId and artifactId tries to find the matching + * URL of the running stub. + * + * @param groupId - might be null. In that case a search only via artifactId takes place + * @return URL of a running stub or null if not found + */ + URL findStubUrl(String groupId, String artifactId) + + /** + * For the given Ivy notation {@code groupId:artifactId} tries to find the matching + * URL of the running stub. You can also pass only {@code artifactId}. + * + * @param ivyNotation - Ivy representation of the Maven artifact + * @return URL of a running stub or null if not found + */ + URL findStubUrl(String ivyNotation) + + /** + * Returns all running stubs + */ + RunningStubs findAllRunningStubs() + + /** + * Returns the list of Contracts + */ + Map> getContracts() +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy similarity index 55% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy index 78527dbd6c..b82b1c1694 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRepository.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy @@ -1,10 +1,27 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.util.AccurestDslConverter +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter + /** * Wraps the folder with WireMock mappings. */ @@ -15,7 +32,7 @@ class StubRepository { private final File path final List projectDescriptors - final Collection accurestContracts + final Collection contracts StubRepository(File repository) { if (!repository.isDirectory()) { @@ -23,15 +40,15 @@ class StubRepository { } this.path = repository this.projectDescriptors = projectDescriptors() - this.accurestContracts = accurestContracts() + this.contracts = contracts() } /** - * Returns a list of {@link GroovyDsl} + * Returns a list of {@link Contract} */ - private Collection accurestContracts() { - List contracts = [] - contracts.addAll(accurestDescriptors()) + private Collection contracts() { + List contracts = [] + contracts.addAll(contractDescriptors()) return contracts } @@ -58,16 +75,16 @@ class StubRepository { return mappingDescriptors } - private Collection accurestDescriptors() { - return path.exists() ? collectAccurestDescriptors(path) : [] + private Collection contractDescriptors() { + return path.exists() ? collectContractDescriptors(path) : [] } - private Collection collectAccurestDescriptors(File descriptorsDirectory) { - List mappingDescriptors = [] + private Collection collectContractDescriptors(File descriptorsDirectory) { + List mappingDescriptors = [] descriptorsDirectory.eachFileRecurse { File file -> - if (isAccurestDescriptor(file)) { + if (isContractDescriptor(file)) { try { - mappingDescriptors << AccurestDslConverter.convert(file) + mappingDescriptors << ContractVerifierDslConverter.convert(file) } catch (Exception e) { log.warn("Exception occurred while trying to parse file [$file]", e) } @@ -80,7 +97,7 @@ class StubRepository { return file.isFile() && file.name.endsWith('.json') } - private static boolean isAccurestDescriptor(File file) { + private static boolean isContractDescriptor(File file) { //TODO: Consider script injections implications... return file.isFile() && file.name.endsWith('.groovy') } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy similarity index 66% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy index c525646c5e..388eafcbce 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunner.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy @@ -1,10 +1,26 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.messaging.AccurestMessaging -import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging /** * Represents a single instance of ready-to-run stubs. @@ -21,7 +37,7 @@ class StubRunner implements StubRunning { private final StubConfiguration stubsConfiguration private final StubRunnerOptions stubRunnerOptions private final StubRunnerExecutor localStubRunner - private final AccurestMessaging accurestMessaging + private final ContractVerifierMessaging contractVerifierMessaging @Deprecated StubRunner(Arguments arguments) { @@ -29,18 +45,18 @@ class StubRunner implements StubRunning { } StubRunner(StubRunnerOptions stubRunnerOptions, String repositoryPath, StubConfiguration stubsConfiguration) { - this(stubRunnerOptions, repositoryPath, stubsConfiguration, new NoOpAccurestMessaging()) + this(stubRunnerOptions, repositoryPath, stubsConfiguration, new NoOpContractVerifierMessaging()) } StubRunner(StubRunnerOptions stubRunnerOptions, String repositoryPath, StubConfiguration stubsConfiguration, - AccurestMessaging accurestMessaging) { + ContractVerifierMessaging contractVerifierMessaging) { this.stubsConfiguration = stubsConfiguration this.stubRunnerOptions = stubRunnerOptions this.stubRepository = new StubRepository(new File(repositoryPath)) AvailablePortScanner portScanner = new AvailablePortScanner(stubRunnerOptions.minPortValue, stubRunnerOptions.maxPortValue) - this.accurestMessaging = accurestMessaging - this.localStubRunner = new StubRunnerExecutor(portScanner, accurestMessaging) + this.contractVerifierMessaging = contractVerifierMessaging + this.localStubRunner = new StubRunnerExecutor(portScanner, contractVerifierMessaging) } @Override @@ -70,8 +86,8 @@ class StubRunner implements StubRunning { } @Override - Map> getAccurestContracts() { - return localStubRunner.getAccurestContracts() + Map> getContracts() { + return localStubRunner.getContracts() } @Override diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy similarity index 58% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy index 2852327f13..3f688e177d 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutor.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy @@ -1,11 +1,27 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.messaging.AccurestMessage -import io.codearte.accurest.messaging.AccurestMessaging -import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging +import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging /** * Runs stubs for a particular {@link StubServer} @@ -15,17 +31,17 @@ import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging class StubRunnerExecutor implements StubFinder { private final AvailablePortScanner portScanner - private final AccurestMessaging accurestMessaging + private final ContractVerifierMessaging contractVerifierMessaging private StubServer stubServer - StubRunnerExecutor(AvailablePortScanner portScanner, AccurestMessaging accurestMessaging) { + StubRunnerExecutor(AvailablePortScanner portScanner, ContractVerifierMessaging contractVerifierMessaging) { this.portScanner = portScanner - this.accurestMessaging = accurestMessaging + this.contractVerifierMessaging = contractVerifierMessaging } StubRunnerExecutor(AvailablePortScanner portScanner) { this.portScanner = portScanner - this.accurestMessaging = new NoOpAccurestMessaging() + this.contractVerifierMessaging = new NoOpContractVerifierMessaging() } RunningStubs runStubs(StubRunnerOptions stubRunnerOptions, StubRepository repository, StubConfiguration stubConfiguration) { @@ -64,25 +80,25 @@ class StubRunnerExecutor implements StubFinder { } @Override - Map> getAccurestContracts() { + Map> getContracts() { return [(stubServer.stubConfiguration): stubServer.contracts] } @Override boolean trigger(String ivyNotationAsString, String labelName) { - Collection matchingContracts = getAccurestContracts().findAll { + Collection matchingContracts = getContracts().findAll { it.key.groupIdAndArtifactMatches(ivyNotationAsString) - }.values().flatten() as Collection + }.values().flatten() as Collection return triggerForDsls(matchingContracts, labelName) } @Override boolean trigger(String labelName) { - return triggerForDsls(getAccurestContracts().values().flatten() as Collection, labelName) + return triggerForDsls(getContracts().values().flatten() as Collection, labelName) } - private boolean triggerForDsls(Collection dsls, String labelName) { - Collection matchingDsls = dsls.findAll { it.label == labelName } + private boolean triggerForDsls(Collection dsls, String labelName) { + Collection matchingDsls = dsls.findAll { it.label == labelName } if (matchingDsls.empty) { return false } @@ -94,7 +110,7 @@ class StubRunnerExecutor implements StubFinder { @Override boolean trigger() { - (getAccurestContracts().values().flatten() as Collection).each { GroovyDsl groovyDsl -> + (getContracts().values().flatten() as Collection).each { Contract groovyDsl -> sendMessageIfApplicable(groovyDsl) } return true @@ -102,18 +118,18 @@ class StubRunnerExecutor implements StubFinder { @Override Map> labels() { - return getAccurestContracts().collectEntries { + return getContracts().collectEntries { [(it.key.toColonSeparatedDependencyNotation()) : it.value.collect { it.label }] } as Map> } - private void sendMessageIfApplicable(GroovyDsl groovyDsl) { + private void sendMessageIfApplicable(Contract groovyDsl) { if (!groovyDsl.outputMessage) { return } - AccurestMessage message = accurestMessaging.create(groovyDsl.outputMessage?.body?.clientValue, + ContractVerifierMessage message = contractVerifierMessaging.create(groovyDsl.outputMessage?.body?.clientValue, groovyDsl.outputMessage?.headers?.asStubSideMap()) - accurestMessaging.send(message, groovyDsl.outputMessage.sentTo.clientValue) + contractVerifierMessaging.send(message, groovyDsl.outputMessage.sentTo.clientValue) } private URL returnStubUrlIfMatches(boolean condition) { @@ -122,7 +138,7 @@ class StubRunnerExecutor implements StubFinder { private void startStubServers(StubRunnerOptions stubRunnerOptions, StubConfiguration stubConfiguration, StubRepository repository) { List mappings = repository.getProjectDescriptors() - Collection contracts = repository.accurestContracts + Collection contracts = repository.contracts Integer port = stubRunnerOptions.port(stubConfiguration) if (port) { stubServer = new StubServer(port, stubConfiguration, mappings, contracts).start() diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.groovy similarity index 57% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.groovy index 42f5cf65af..6429e56252 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerFactory.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.groovy @@ -1,8 +1,24 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.messaging.AccurestMessaging +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging /** * Factory of StubRunners. Basing on the options and passed collaborators @@ -14,12 +30,12 @@ class StubRunnerFactory { private final StubRunnerOptions stubRunnerOptions private final StubDownloader stubDownloader - private final AccurestMessaging accurestMessaging + private final ContractVerifierMessaging contractVerifierMessaging - StubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader, AccurestMessaging accurestMessaging) { + StubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader, ContractVerifierMessaging contractVerifierMessaging) { this.stubRunnerOptions = stubRunnerOptions this.stubDownloader = stubDownloader - this.accurestMessaging = accurestMessaging + this.contractVerifierMessaging = contractVerifierMessaging } Collection createStubsFromServiceConfiguration() { @@ -41,7 +57,7 @@ class StubRunnerFactory { private StubRunner createStubRunner(File unzippedStubsDir, StubConfiguration stubsConfiguration, StubRunnerOptions stubRunnerOptions) { - return new StubRunner(stubRunnerOptions, unzippedStubsDir.path, stubsConfiguration, accurestMessaging) + return new StubRunner(stubRunnerOptions, unzippedStubsDir.path, stubsConfiguration, contractVerifierMessaging) } } diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMain.groovy similarity index 81% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMain.groovy index aaa620a63a..3fc959780a 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMain.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMain.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy new file mode 100644 index 0000000000..594dd1c1ce --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import groovy.transform.PackageScope +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging + +/** + * @author Marcin Grzejszczak + */ +@PackageScope +class StubRunnerMessagingTrigger { + + private final ContractVerifierMessaging contractVerifierMessaging + + StubRunnerMessagingTrigger(ContractVerifierMessaging contractVerifierMessaging) { + this.contractVerifierMessaging = contractVerifierMessaging + } + + void trigger +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.groovy similarity index 71% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.groovy index aa4a9a890f..d93f8ea034 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptions.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.groovy similarity index 80% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.groovy index 903b21c789..78b98c9186 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilder.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.groovy @@ -1,7 +1,23 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic -import io.codearte.accurest.stubrunner.util.StubsParser +import org.springframework.cloud.contract.stubrunner.util.StubsParser @CompileStatic class StubRunnerOptionsBuilder { diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy new file mode 100644 index 0000000000..08758b541e --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy @@ -0,0 +1,25 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +interface StubRunning extends Closeable, StubFinder { + /** + * Runs the stubs and returns the {@link RunningStubs} + */ + RunningStubs runStubs() + +} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy similarity index 72% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy index 62e5cc5952..5889584035 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubServer.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import com.github.tomakehurst.wiremock.WireMockServer import com.github.tomakehurst.wiremock.client.WireMock @@ -6,7 +22,7 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j -import io.codearte.accurest.dsl.GroovyDsl +import org.springframework.cloud.contract.verifier.dsl.Contract @CompileStatic @Slf4j @@ -15,10 +31,10 @@ class StubServer { private WireMockServer wireMockServer final StubConfiguration stubConfiguration final Collection mappings - final Collection contracts + final Collection contracts StubServer(int port, StubConfiguration stubConfiguration, Collection mappings, - Collection contracts) { + Collection contracts) { this.stubConfiguration = stubConfiguration this.mappings = mappings this.wireMockServer = new WireMockServer(WireMockConfiguration.wireMockConfig().port(port)) diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy similarity index 54% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy index bd5ec1e30e..c9ef71bafa 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubTrigger.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner interface StubTrigger { diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy new file mode 100644 index 0000000000..e3bdba3f9b --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import com.github.tomakehurst.wiremock.stubbing.StubMapping +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.PackageScope +import groovy.transform.ToString + +/** + * Represents a single JSON file that was found in the folder with + * potential WireMock stubs + */ +@CompileStatic +@EqualsAndHashCode +@ToString(includePackage = false) +@PackageScope +class WiremockMappingDescriptor { + final File descriptor + + WiremockMappingDescriptor(File mappingDescriptor) { + this.descriptor = mappingDescriptor + } + + StubMapping getMapping() { + return StubMapping.buildFrom(descriptor.getText('UTF-8')) + } +} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StringUtils.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StringUtils.groovy similarity index 85% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StringUtils.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StringUtils.groovy index 16b8f35db1..5382f8ae57 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StringUtils.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StringUtils.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner.util +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.util /** * Utils ported from Apache Commons diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StubsParser.groovy similarity index 69% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StubsParser.groovy index ae06a9bfe2..bb45d160fe 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/StubsParser.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StubsParser.groovy @@ -1,7 +1,23 @@ -package io.codearte.accurest.stubrunner.util +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.util import groovy.transform.CompileStatic -import io.codearte.accurest.stubrunner.StubConfiguration +import org.springframework.cloud.contract.stubrunner.StubConfiguration /** * Utility to parse string into a list of configuration of stubs diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/ZipCategory.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategory.groovy similarity index 72% rename from stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/ZipCategory.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategory.groovy index 1877da70d4..105298b558 100644 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/util/ZipCategory.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategory.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner.util +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.util import groovy.transform.CompileStatic diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml new file mode 100644 index 0000000000..cbbd28cea5 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScannerSpec.groovy similarity index 71% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScannerSpec.groovy index 609e746e66..6a7703ee84 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/AvailablePortScannerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScannerSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import spock.lang.Specification diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerSpec.groovy similarity index 67% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerSpec.groovy index 0013801aa8..83c46a48d5 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import spock.lang.Specification diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy new file mode 100644 index 0000000000..2fddae9d96 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import com.github.tomakehurst.wiremock.http.RequestMethod +import spock.lang.Specification + +class MappingDescriptorSpec extends Specification { + public static + final File MAPPING_DESCRIPTOR = new File('src/test/resources/repository/mappings/spring/cloud/ping/ping.json') + + def 'should describe stub mapping'() { + given: + WiremockMappingDescriptor mappingDescriptor = new WiremockMappingDescriptor(MAPPING_DESCRIPTOR) + + expect: + with(mappingDescriptor.mapping) { + request.method == RequestMethod.GET + request.url == '/ping' + response.status == 200 + response.body == 'pong' + response.headers.contentTypeHeader.mimeTypePart() == 'text/plain' + } + } +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/RunningStubsSpec.groovy similarity index 72% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/RunningStubsSpec.groovy index 11acce3339..57eac143b8 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/RunningStubsSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/RunningStubsSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import spock.lang.Specification diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy new file mode 100644 index 0000000000..0e5d631d8d --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner + +import spock.lang.Specification + +/** + * @author Marcin Grzejszczak + */ +class StubConfigurationSpec extends Specification { + + def 'should parse ivy notation'() { + given: + String ivy = 'group:artifact:version:classifier' + when: + StubConfiguration stubConfiguration = new StubConfiguration(ivy) + then: + stubConfiguration.artifactId == 'artifact' + stubConfiguration.groupId == 'group' + stubConfiguration.classifier == 'classifier' + stubConfiguration.version == 'version' + } +} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRepositorySpec.groovy similarity index 58% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRepositorySpec.groovy index 8e50f75267..bc5614e5a1 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRepositorySpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRepositorySpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import spock.lang.Specification diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy similarity index 72% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy index a90447dce9..ad59d1374b 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerExecutorSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy @@ -1,6 +1,22 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.stubrunner.util.StubsParser +package org.springframework.cloud.contract.stubrunner + +import org.springframework.cloud.contract.stubrunner.util.StubsParser import spock.lang.Specification class StubRunnerExecutorSpec extends Specification { diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy similarity index 59% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy index 71d5e90f3b..ced2a5f713 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerFactorySpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy @@ -1,8 +1,24 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner -import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging import org.junit.Rule import org.junit.rules.TemporaryFolder +import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging import spock.lang.Specification class StubRunnerFactorySpec extends Specification { @@ -19,7 +35,7 @@ class StubRunnerFactorySpec extends Specification { stubRunnerOptions = new StubRunnerOptionsBuilder() .withStubRepositoryRoot(folder.root.absolutePath) // FIXME: not used .withStubs(stubs).build() - factory = new StubRunnerFactory(stubRunnerOptions, downloader, new NoOpAccurestMessaging()) + factory = new StubRunnerFactory(stubRunnerOptions, downloader, new NoOpContractVerifierMessaging()) } def "Should download stub definitions many times"() { diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilderSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy similarity index 65% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilderSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy index 07de7cb30b..c0d4aba44c 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerOptionsBuilderSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import spock.lang.Specification diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerSpec.groovy similarity index 63% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerSpec.groovy index f67ad211fa..18fb646e97 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubRunnerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import spock.lang.Specification diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy similarity index 62% rename from stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy index fad9fd82eb..7be6fbaefc 100644 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubServerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.stubrunner +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner import spock.lang.Specification @@ -6,7 +22,7 @@ class StubServerSpec extends Specification { static final int STUB_SERVER_PORT = 12180 static final URL EXPECTED_URL = new URL("http://localhost:$STUB_SERVER_PORT") - File repository = new File('src/test/resources/repository/mappings/com/ofg/bye') + File repository = new File('src/test/resources/repository/mappings/spring/cloud/bye') StubConfiguration stubConfiguration = new StubConfiguration("a:b") def 'should register stub mappings upon server start'() { diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy new file mode 100644 index 0000000000..c3b0834b02 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy @@ -0,0 +1,40 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.stubrunner.util + +import groovy.util.logging.Slf4j +import spock.lang.Specification + +@Slf4j +class ZipCategorySpec extends Specification { + + def 'should unzip a file to the specified location'() { + given: + File zipFile = new File(ZipCategorySpec.classLoader.getResource('file.zip').toURI()) + File tempDir = File.createTempDir() + tempDir.deleteOnExit() + when: + use(ZipCategory) { + zipFile.unzipTo(tempDir) + } + then: + tempDir.listFiles().find { + it.name == 'file.txt' + }?.text?.trim() == 'test' + } + +} diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/bar/bar.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/bar/bar.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/bar/bar.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/bar/bar.json diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/bar/foobar.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/bar/foobar.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/bar/foobar.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/bar/foobar.json diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/foo.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/foo.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/anotherRepository/mappings/com/ofg/foo/foo.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/foo.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json new file mode 100644 index 0000000000..fae6436ad8 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json @@ -0,0 +1,5 @@ +{ + "pl": [ + "spring/cloud/bar" + ] +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json new file mode 100644 index 0000000000..b3a72bfbcf --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json @@ -0,0 +1,5 @@ +{ + "pl": [ + "spring/cloud/foo/bar" + ] +} \ No newline at end of file diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json new file mode 100644 index 0000000000..a2384b0930 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json @@ -0,0 +1,5 @@ +{ + "pl": [ + "spring/cloud/foo" + ] +} \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/emptyrepo/.gitkeep similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/emptyrepo/.gitkeep diff --git a/stub-runner/stub-runner/src/test/resources/file.zip b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/file.zip similarity index 100% rename from stub-runner/stub-runner/src/test/resources/file.zip rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/file.zip diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/logback.xml b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/logback.xml new file mode 100644 index 0000000000..7eecabf2f2 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/logback.xml @@ -0,0 +1,30 @@ + + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/lv/com/ofg/bye/lv_bye.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/lv/spring/cloud/bye/lv_bye.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/lv/com/ofg/bye/lv_bye.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/lv/spring/cloud/bye/lv_bye.json diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_bye.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_bye.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_bye.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_bye.json diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_overridden_bye.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_overridden_bye.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/pl/com/ofg/bye/pl_overridden_bye.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_overridden_bye.json diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/admin/admin.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/admin/admin.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/admin/admin.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/admin/admin.json diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/bye.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/bye.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/bye/bye.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/bye.json diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/README.md b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/README.md similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/README.md rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/README.md diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/admin/admin.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/admin/admin.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/admin/admin.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/admin/admin.json diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/hello.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/hello.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/hello/hello.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/hello.json diff --git a/stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/ping/ping.json b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/ping/ping.json similarity index 100% rename from stub-runner/stub-runner/src/test/resources/repository/mappings/com/ofg/ping/ping.json rename to spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/ping/ping.json diff --git a/spring-cloud-contract-verifier/build.gradle b/spring-cloud-contract-verifier/build.gradle new file mode 100644 index 0000000000..178c42a48e --- /dev/null +++ b/spring-cloud-contract-verifier/build.gradle @@ -0,0 +1,118 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +String verifier = "spring-cloud-contract-verifier" + +project(":$verifier-root:$verifier-core") { + + dependencies { + compile 'org.slf4j:slf4j-api:1.6.0' + compile 'commons-io:commons-io:2.0' + compile 'org.apache.commons:commons-lang3:3.3' + compile "com.github.tomakehurst:wiremock:$wiremockVersion" + compile "com.toomuchcoding.jsonassert:jsonassert:$jsonassertVersion" + compile 'org.codehaus.groovy:groovy-all:2.4.4' + testCompile 'cglib:cglib-nodep:2.2' + testCompile 'org.objenesis:objenesis:2.1' + testCompile project(":$verifier-root:$verifier-testing-utils") + } + +} + +project(":$verifier-root:$verifier-testing-utils") { + + dependencies { + compile 'org.skyscreamer:jsonassert:1.2.3' + } + +} + +project(":$verifier-root:$verifier-converters") { + dependencies { + compile project(":$verifier-root:$verifier-core") + compile 'org.apache.commons:commons-lang3:3.0' + compile 'commons-io:commons-io:2.0' + compile 'dk.brics.automaton:automaton:1.11-8' // needed for Xeger + testCompile "com.github.tomakehurst:wiremock:$wiremockVersion" + testCompile 'org.hamcrest:hamcrest-all:1.3' + } +} + +project(":$verifier-root:$verifier-gradle-plugin") { + + ext.messagingLibsDir ="$buildDir/messaging-libs" + ext.contractVerifierGradlePluginLibsDir ="$buildDir/contractVerifier-gradle-plugin-libs" + + ext.testSystemProperties = [ + 'contract-verifier-gradle-plugin-libs-dir': contractVerifierGradlePluginLibsDir, + 'messaging-libs-dir': messagingLibsDir + ] + + dependencies { + compile project(":$verifier-root:$verifier-core") + compile project(":$verifier-root:$verifier-converters") + compile gradleApi() + + testCompile gradleTestKit() + testCompile project(":$verifier-root:$verifier-testing-utils") + } + + configurations { + messagingLibs + contractVerifierGradlePluginLibs + } + + dependencies { + + messagingLibs project(":$verifier-root:$verifier-messaging-root:$verifier-integration") + messagingLibs project(":$verifier-root:$verifier-messaging-root:$verifier-messaging-core") + messagingLibs project(":$verifier-root:$verifier-testing-utils") + messagingLibs 'org.codehaus.groovy:groovy-all:2.4.5' + + contractVerifierGradlePluginLibs project(":$verifier-root:$verifier-gradle-plugin") + } + + test { + exclude '**/*FunctionalSpec.*' + systemProperties = testSystemProperties + } + task funcTest(type: Test) { + include '**/*FunctionalSpec.*' + systemProperties = testSystemProperties + reports.html { + destination = file("${reporting.baseDir}/funcTests") + } + } + + task archiveMessagingLibsDependencies(type: Sync) { + from configurations.messagingLibs.resolvedConfiguration.resolvedArtifacts.collect { it.file } + into messagingLibsDir + } + + task archiveContractVerifierGradlePluginLibsDependencies(type: Sync) { + from configurations.contractVerifierGradlePluginLibs.resolvedConfiguration.resolvedArtifacts.collect { it.file } + into contractVerifierGradlePluginLibsDir + } + + // archive task needs to have jars ready + archiveMessagingLibsDependencies.dependsOn project(":$verifier-root:$verifier-messaging-root:$verifier-integration").tasks.jar + archiveContractVerifierGradlePluginLibsDependencies.dependsOn project(":$verifier-root:$verifier-gradle-plugin").tasks.jar + + test.dependsOn archiveMessagingLibsDependencies, archiveContractVerifierGradlePluginLibsDependencies + funcTest.dependsOn archiveMessagingLibsDependencies, archiveContractVerifierGradlePluginLibsDependencies + + uploadArchives.dependsOn { funcTest } +} diff --git a/accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java similarity index 100% rename from accurest-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy new file mode 100644 index 0000000000..ad860b19ea --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.converter + +import groovy.transform.CompileStatic +import org.springframework.cloud.contract.verifier.file.ContractMetadata + +/** + * Converts contracts into their stub representation + * + * @since 1.0.0 + */ +@CompileStatic +interface SingleFileConverter { + + /** + * Returns {@code true} if the converter can handle the file + */ + boolean canHandleFileName(String fileName) + + /** + * Returns the content of the converted file + */ + String convertContent(String rootName, ContractMetadata content) + + /** + * Returns the name of the converted file + */ + String generateOutputFileNameForInput(String inputFileName) +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy new file mode 100644 index 0000000000..205dd170e4 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy @@ -0,0 +1,33 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.wiremock + +import groovy.transform.CompileStatic +import org.springframework.cloud.contract.verifier.ContractVerifierException + +/** + * Thrown when a a DSL can't be properly converted + * + * @since 1.0.0 + */ +@CompileStatic +class ConversionContractVerifierException extends ContractVerifierException { + + ConversionContractVerifierException(String message, Throwable cause) { + super(message, cause) + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy new file mode 100644 index 0000000000..3fe90afb25 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.wiremock + +import groovy.transform.CompileStatic +import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy +import org.springframework.cloud.contract.verifier.file.ContractMetadata + +import java.nio.charset.StandardCharsets + +/** + * Converts DSLs to WireMock stubs + * + * @since 1.0.0 + */ +@CompileStatic +class DslToWireMockClientConverter extends DslToWireMockConverter { + + @Override + String convertContent(String rootName, ContractMetadata contract) { + String dslContent = contract.path.getText(StandardCharsets.UTF_8.toString()) + return new WireMockStubStrategy(rootName, contract, createGroovyDSLFromStringContent(dslContent)).toWireMockClientStub() + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy new file mode 100644 index 0000000000..289b1d6ed0 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.wiremock + +import groovy.transform.CompileStatic +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.converter.SingleFileConverter +import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter + +/** + * WireMock implementation of the {@link SingleFileConverter} + * + * @since 1.0.0 + */ +@CompileStatic +abstract class DslToWireMockConverter implements SingleFileConverter { + + @Override + boolean canHandleFileName(String fileName) { + return fileName.endsWith('.groovy') + } + + @Override + String generateOutputFileNameForInput(String inputFileName) { + return inputFileName.replaceAll('.groovy', '.json') + } + + protected Contract createGroovyDSLFromStringContent(String groovyDslAsString) { + return ContractVerifierDslConverter.convert(groovyDslAsString) + } +} diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy similarity index 57% rename from accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy index 867aab8a34..57a56c9c77 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy @@ -1,34 +1,56 @@ -package io.codearte.accurest.wiremock +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.wiremock import com.google.common.collect.ListMultimap import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.file.Contract -import io.codearte.accurest.file.ContractFileScanner +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.converter.SingleFileConverter +import org.springframework.cloud.contract.verifier.file.ContractMetadata +import org.springframework.cloud.contract.verifier.file.ContractFileScanner import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths +/** + * Recursively converts contracts into their stub representations + * + * @since 1.0.0 + */ @Slf4j @CompileStatic class RecursiveFilesConverter { private final SingleFileConverter singleFileConverter - private final AccurestConfigProperties properties + private final ContractVerifierConfigProperties properties - RecursiveFilesConverter(SingleFileConverter singleFileConverter, AccurestConfigProperties properties) { + RecursiveFilesConverter(SingleFileConverter singleFileConverter, ContractVerifierConfigProperties properties) { this.properties = properties this.singleFileConverter = singleFileConverter } void processFiles() { ContractFileScanner scanner = new ContractFileScanner(properties.contractsDslDir, properties.excludedFiles as Set, [] as Set) - ListMultimap contracts = scanner.findContracts() + ListMultimap contracts = scanner.findContracts() contracts.asMap().entrySet().each { entry -> - entry.value.each { Contract contract -> + entry.value.each { ContractMetadata contract -> File sourceFile = contract.path.toFile() try { if (!singleFileConverter.canHandleFileName(sourceFile.name)) { @@ -42,7 +64,7 @@ class RecursiveFilesConverter { File newGroovyFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) newGroovyFile.setText(convertedContent, StandardCharsets.UTF_8.toString()) } catch (Exception e) { - throw new ConversionAccurestException("Unable to make conversion of ${sourceFile.name}", e) + throw new ConversionContractVerifierException("Unable to make conversion of ${sourceFile.name}", e) } } } diff --git a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy similarity index 83% rename from accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy index 0a7bfc8bb8..7844605653 100644 --- a/accurest-converters/src/main/groovy/io/codearte/accurest/wiremock/WireMockToDslConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy @@ -1,18 +1,47 @@ -package io.codearte.accurest.wiremock +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.wiremock import groovy.io.FileType import groovy.json.JsonOutput import groovy.json.JsonParserType import groovy.json.JsonSlurper +import groovy.transform.CompileDynamic import groovy.xml.XmlUtil -import io.codearte.accurest.dsl.GroovyDsl +import org.springframework.cloud.contract.verifier.dsl.Contract import nl.flotsam.xeger.Xeger import java.nio.charset.StandardCharsets import static org.apache.commons.lang3.StringEscapeUtils.escapeJava +/** + * Converts WireMock stubs into the DSL format + * + * @since 1.0.0 + */ +@CompileDynamic class WireMockToDslConverter { + + /** + * Returns the string content of the contract + * + * @param wireMockStringStub - string content of the WireMock JSON stub + */ static String fromWireMockStub(String wireMockStringStub) { return new WireMockToDslConverter().convertFromWireMockStub(wireMockStringStub) } @@ -172,7 +201,7 @@ class WireMockToDslConverter { static String wrapWithFactoryMethod(String dslFromWireMockStub) { return """\ -${GroovyDsl.name}.make { +${Contract.name}.make { $dslFromWireMockStub } """ diff --git a/accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java similarity index 100% rename from accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java diff --git a/accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java similarity index 100% rename from accurest-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy similarity index 77% rename from accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy index 0d0eee7c03..9bd88e86c7 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/DslToWireMockClientConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy @@ -1,9 +1,25 @@ -package io.codearte.accurest.wiremock +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.wiremock -import io.codearte.accurest.file.Contract import org.junit.Rule import org.junit.rules.TemporaryFolder import org.skyscreamer.jsonassert.JSONAssert +import org.springframework.cloud.contract.verifier.file.ContractMetadata import spock.lang.Issue import spock.lang.Specification @@ -18,7 +34,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl1.groovy") file.write(""" - io.codearte.accurest.dsl.GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('PUT') url \$(client(~/\\/[0-9]{2}/), server('/12')) @@ -29,7 +45,7 @@ class DslToWireMockClientConverterSpec extends Specification { } """) when: - String json = converter.convertContent("Test", new Contract(file.toPath(), false, 0, null)) + String json = converter.convertContent("Test", new ContractMetadata(file.toPath(), false, 0, null)) then: JSONAssert.assertEquals(''' {"request":{"method":"PUT","urlPattern":"/[0-9]{2}"},"response":{"status":200}} @@ -43,7 +59,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl-delay.groovy") file.write(""" - io.codearte.accurest.dsl.GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { } response { @@ -53,7 +69,7 @@ class DslToWireMockClientConverterSpec extends Specification { } """) when: - String json = converter.convertContent("test", new Contract(file.toPath(), false, 0, null)) + String json = converter.convertContent("test", new ContractMetadata(file.toPath(), false, 0, null)) then: JSONAssert.assertEquals(''' {"request":{},"response":{"status":200,"fixedDelayMilliseconds":1000}} @@ -66,12 +82,12 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl2.groovy") file.write(""" - io.codearte.accurest.dsl.GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'PUT' url '/api/12' headers { - header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json' + header 'Content-Type': 'application/vnd.org.springframework.cloud.contract.verifier.twitter-places-analyzer.v1+json' } body ''' @@ -111,7 +127,7 @@ class DslToWireMockClientConverterSpec extends Specification { } """) when: - String json = converter.convertContent("Test", new Contract(file.toPath(), false, 0, null)) + String json = converter.convertContent("Test", new ContractMetadata(file.toPath(), false, 0, null)) then: JSONAssert.assertEquals(''' { @@ -153,7 +169,7 @@ class DslToWireMockClientConverterSpec extends Specification { } ], "headers" : { "Content-Type" : { - "equalTo" : "application/vnd.com.ofg.twitter-places-analyzer.v1+json" + "equalTo" : "application/vnd.org.springframework.cloud.contract.verifier.twitter-places-analyzer.v1+json" } } }, @@ -172,7 +188,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl-mapinlist.groovy") file.write(""" - io.codearte.accurest.dsl.GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath '/foos' @@ -193,7 +209,7 @@ class DslToWireMockClientConverterSpec extends Specification { } """) when: - String json = converter.convertContent("test", new Contract(file.toPath(), false, 0, null)) + String json = converter.convertContent("test", new ContractMetadata(file.toPath(), false, 0, null)) then: JSONAssert.assertEquals(''' {"request":{"urlPath":"/foos","method":"GET"},"response":{"body":"[{\\"id\\":\\"123\\"},{\\"id\\":\\"567\\"}]"}} @@ -206,7 +222,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl_from_docs.groovy") file.write(''' - io.codearte.accurest.dsl.GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { priority 1 request { method 'POST' @@ -232,7 +248,7 @@ class DslToWireMockClientConverterSpec extends Specification { } ''') when: - String json = converter.convertContent("Test", new Contract(file.toPath(), false, 0, null)) + String json = converter.convertContent("Test", new ContractMetadata(file.toPath(), false, 0, null)) then: JSONAssert.assertEquals( // tag::wiremock[] ''' diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy similarity index 78% rename from accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy index 754445866e..0e3de65413 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/RecursiveFilesConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy @@ -1,10 +1,27 @@ -package io.codearte.accurest.wiremock +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.wiremock -import io.codearte.accurest.config.AccurestConfigProperties import org.apache.commons.io.FileUtils import org.apache.commons.io.filefilter.TrueFileFilter import org.junit.Rule import org.junit.rules.TemporaryFolder +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.converter.SingleFileConverter import spock.lang.Specification import java.nio.file.Path @@ -20,7 +37,7 @@ class RecursiveFilesConverterSpec extends Specification { def "should recursively convert all matching files"() { given: - AccurestConfigProperties properties = new AccurestConfigProperties() + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties() File originalSourceRootDirectory = new File(this.getClass().getResource("/converter/source").toURI()) properties.contractsDslDir = tmpFolder.newFolder("source") properties.stubsOutputDir = tmpFolder.newFolder("target") @@ -44,7 +61,7 @@ class RecursiveFilesConverterSpec extends Specification { def "should recursively convert matching files with exlusions"() { given: - AccurestConfigProperties properties = new AccurestConfigProperties() + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties() File originalSourceRootDirectory = new File(this.getClass().getResource("/converter/source").toURI()) properties.contractsDslDir = tmpFolder.newFolder("source") properties.stubsOutputDir = tmpFolder.newFolder("target") @@ -75,14 +92,14 @@ class RecursiveFilesConverterSpec extends Specification { singleFileConverterStub.canHandleFileName(_) >> { true } singleFileConverterStub.convertContent(_, _) >> { throw new NullPointerException("Test conversion error") } singleFileConverterStub.generateOutputFileNameForInput(_) >> { String inputFileName -> "${inputFileName}2" } - AccurestConfigProperties properties = new AccurestConfigProperties() + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties() properties.contractsDslDir = tmpFolder.root properties.stubsOutputDir = tmpFolder.root RecursiveFilesConverter recursiveFilesConverter = new RecursiveFilesConverter(singleFileConverterStub, properties) when: recursiveFilesConverter.processFiles() then: - def e = thrown(ConversionAccurestException) + def e = thrown(ConversionContractVerifierException) e.message?.contains(sourceFile.name) e.cause?.message == "Test conversion error" } diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy similarity index 78% rename from accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy index 5e71f81605..f564abadb2 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WireMockToDslConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy @@ -1,8 +1,24 @@ -package io.codearte.accurest.wiremock +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.wiremock import com.github.tomakehurst.wiremock.stubbing.StubMapping -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.util.AccurestDslConverter +import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter +import org.springframework.cloud.contract.verifier.dsl.Contract import spock.lang.Specification class WireMockToDslConverterSpec extends Specification { @@ -35,7 +51,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'GET' url '/path' @@ -68,8 +84,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -100,7 +116,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'DELETE' url $(client(~/\/credit-card-verification-data\/[0-9]+/), server('/credit-card-verification-data/1')) @@ -122,8 +138,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -153,7 +169,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'POST' url '/charge/count' @@ -173,8 +189,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -204,7 +220,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'POST' url '/charge/count' @@ -227,8 +243,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -255,7 +271,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'POST' url '/charge/search?pageNumber=0&size=2147483647' @@ -292,8 +308,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -317,7 +333,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'POST' url '/test' @@ -330,8 +346,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") and: @@ -357,7 +373,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'POST' url '/test' @@ -370,8 +386,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") and: @@ -398,7 +414,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'POST' url '/test' @@ -411,8 +427,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") and: @@ -438,7 +454,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'POST' url '/test' @@ -451,8 +467,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") and: @@ -478,7 +494,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { request { method 'POST' url '/test' @@ -491,8 +507,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") and: @@ -516,7 +532,7 @@ class WireMockToDslConverterSpec extends Specification { and: stubMappingIsValidWireMockStub(wireMockStub) and: - GroovyDsl expectedGroovyDsl = GroovyDsl.make { + Contract expectedGroovyDsl = Contract.make { priority 2 request { method 'POST' @@ -529,8 +545,8 @@ class WireMockToDslConverterSpec extends Specification { when: String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: - GroovyDsl evaluatedGroovyDsl = AccurestDslConverter.convert( - """ io.codearte.accurest.dsl.GroovyDsl.make { + Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( + """org.springframework.cloud.contract.verifier.dsl.Contract.make { $groovyDsl }""") and: diff --git a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockScenarioConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WiremockScenarioConverterSpec.groovy similarity index 65% rename from accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockScenarioConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WiremockScenarioConverterSpec.groovy index e7911c1303..64f0cbe13b 100755 --- a/accurest-converters/src/test/groovy/io/codearte/accurest/wiremock/WiremockScenarioConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WiremockScenarioConverterSpec.groovy @@ -1,6 +1,22 @@ -package io.codearte.accurest.wiremock +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.file.Contract +package org.springframework.cloud.contract.verifier.wiremock + +import org.springframework.cloud.contract.verifier.file.ContractMetadata import spock.lang.Specification import java.nio.file.Path @@ -13,7 +29,7 @@ class WiremockScenarioConverterSpec extends Specification { DslToWireMockClientConverter converter = new DslToWireMockClientConverter() Path dsl = Paths.get(this.getClass().getResource("/converter/scenario/main_scenario/01_login.groovy").toURI()) when: - String content = converter.convertContent("Test", new Contract(dsl, false, 3, 0)) + String content = converter.convertContent("Test", new ContractMetadata(dsl, false, 3, 0)) then: content.contains('"requiredScenarioState" : "Started"') content.contains('"newScenarioState" : "Step1"') @@ -25,7 +41,7 @@ class WiremockScenarioConverterSpec extends Specification { DslToWireMockClientConverter converter = new DslToWireMockClientConverter() Path dsl = Paths.get(this.getClass().getResource("/converter/scenario/main_scenario/02_showCart.groovy").toURI()) when: - String content = converter.convertContent("Test", new Contract(dsl, false, 3, 1)) + String content = converter.convertContent("Test", new ContractMetadata(dsl, false, 3, 1)) then: content.contains('"requiredScenarioState" : "Step1"') content.contains('"newScenarioState" : "Step2"') @@ -37,7 +53,7 @@ class WiremockScenarioConverterSpec extends Specification { DslToWireMockClientConverter converter = new DslToWireMockClientConverter() Path dsl = Paths.get(this.getClass().getResource("/converter/scenario/main_scenario/03_logout.groovy").toURI()) when: - String content = converter.convertContent("Test", new Contract(dsl, false, 3, 2)) + String content = converter.convertContent("Test", new ContractMetadata(dsl, false, 3, 2)) then: content.contains('"requiredScenarioState" : "Step2"') !content.contains('"newScenarioState"') diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy new file mode 100644 index 0000000000..c2c151e460 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy @@ -0,0 +1,27 @@ +import org.springframework.cloud.contract.verifier.dsl.Contract + +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Contract.make { + request { + method('POST') + url '/login' + } + response { + status 200 + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy new file mode 100644 index 0000000000..a4284fe016 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy @@ -0,0 +1,27 @@ +import org.springframework.cloud.contract.verifier.dsl.Contract + +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Contract.make { + request { + method('GET') + url '/cart' + } + response { + status 200 + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy new file mode 100644 index 0000000000..d2675b3a90 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy @@ -0,0 +1,27 @@ +import org.springframework.cloud.contract.verifier.dsl.Contract + +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Contract.make { + request { + method('POST') + url '/logout' + } + response { + status 200 + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy new file mode 100644 index 0000000000..b23e11ed01 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy @@ -0,0 +1,30 @@ +import org.springframework.cloud.contract.verifier.dsl.Contract + +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Contract.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + url $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy new file mode 100644 index 0000000000..3a8bed4ecc --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy @@ -0,0 +1,30 @@ +import org.springframework.cloud.contract.verifier.dsl.Contract + +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Contract.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + urlPattern $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy new file mode 100644 index 0000000000..b23e11ed01 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy @@ -0,0 +1,30 @@ +import org.springframework.cloud.contract.verifier.dsl.Contract + +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Contract.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + url $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy new file mode 100644 index 0000000000..b23e11ed01 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy @@ -0,0 +1,30 @@ +import org.springframework.cloud.contract.verifier.dsl.Contract + +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Contract.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + url $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/ContractVerifierException.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/ContractVerifierException.groovy new file mode 100644 index 0000000000..6b1d5a9c79 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/ContractVerifierException.groovy @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier + +import groovy.transform.CompileStatic + +/** + * @author Jakub Kubrynski, codearte.io + */ +@CompileStatic +class ContractVerifierException extends RuntimeException { + + ContractVerifierException(String message) { + super(message) + } + + ContractVerifierException(String message, Throwable cause) { + super(message, cause) + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/FileSaver.groovy similarity index 50% rename from accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/FileSaver.groovy index 2a9c730787..6b350b34e3 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/FileSaver.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/FileSaver.groovy @@ -1,17 +1,33 @@ -package io.codearte.accurest +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import io.codearte.accurest.config.TestFramework +import org.springframework.cloud.contract.verifier.config.TestFramework import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.nio.file.StandardOpenOption -import static io.codearte.accurest.util.NamesUtil.beforeLast -import static io.codearte.accurest.util.NamesUtil.capitalize -import static io.codearte.accurest.util.NamesUtil.packageToDirectory +import static org.springframework.cloud.contract.verifier.util.NamesUtil.beforeLast +import static org.springframework.cloud.contract.verifier.util.NamesUtil.capitalize +import static org.springframework.cloud.contract.verifier.util.NamesUtil.packageToDirectory @CompileStatic @Slf4j diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy similarity index 51% rename from accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy index d0e9f15346..47f3da17b1 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/TestGenerator.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy @@ -1,43 +1,60 @@ -package io.codearte.accurest +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier import com.google.common.collect.ListMultimap import groovy.transform.PackageScope -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.file.Contract -import io.codearte.accurest.file.ContractFileScanner import org.apache.commons.lang3.StringUtils +import org.springframework.cloud.contract.verifier.builder.SingleTestGenerator +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.file.ContractMetadata +import org.springframework.cloud.contract.verifier.file.ContractFileScanner import java.nio.charset.StandardCharsets import java.nio.file.Path import java.util.concurrent.atomic.AtomicInteger -import static io.codearte.accurest.util.NamesUtil.afterLast -import static io.codearte.accurest.util.NamesUtil.beforeLast -import static io.codearte.accurest.util.NamesUtil.convertIllegalPackageChars -import static io.codearte.accurest.util.NamesUtil.directoryToPackage +import static org.springframework.cloud.contract.verifier.util.NamesUtil.afterLast +import static org.springframework.cloud.contract.verifier.util.NamesUtil.beforeLast +import static org.springframework.cloud.contract.verifier.util.NamesUtil.convertIllegalPackageChars +import static org.springframework.cloud.contract.verifier.util.NamesUtil.directoryToPackage /** - * @author Jakub Kubrynski + * @author Jakub Kubrynski, codearte.io */ class TestGenerator { - private final AccurestConfigProperties configProperties - private final String DEFAULT_CLASS_PREFIX = "Accurest" + private final ContractVerifierConfigProperties configProperties + private final String DEFAULT_CLASS_PREFIX = "ContractVerifier" private AtomicInteger counter = new AtomicInteger() private SingleTestGenerator generator private FileSaver saver private ContractFileScanner contractFileScanner - TestGenerator(AccurestConfigProperties accurestConfigProperties) { - this(accurestConfigProperties, new SingleTestGenerator(accurestConfigProperties), - new FileSaver(accurestConfigProperties.generatedTestSourcesDir, accurestConfigProperties.targetFramework)) + TestGenerator(ContractVerifierConfigProperties configProperties) { + this(configProperties, new SingleTestGenerator(configProperties), + new FileSaver(configProperties.generatedTestSourcesDir, configProperties.targetFramework)) } - TestGenerator(AccurestConfigProperties configProperties, SingleTestGenerator generator, FileSaver saver) { + TestGenerator(ContractVerifierConfigProperties configProperties, SingleTestGenerator generator, FileSaver saver) { this.configProperties = configProperties if (configProperties.contractsDslDir == null) { - throw new AccurestException("Stubs directory not found under " + configProperties.contractsDslDir) + throw new ContractVerifierException("Stubs directory not found under " + configProperties.contractsDslDir) } this.generator = generator this.saver = saver @@ -53,9 +70,9 @@ class TestGenerator { @PackageScope void generateTestClasses(final String basePackageName) { - ListMultimap contracts = contractFileScanner.findContracts() + ListMultimap contracts = contractFileScanner.findContracts() contracts.asMap().entrySet().each { - Map.Entry> entry -> processIncludedDirectory(relativizeContractPath(entry), entry.getValue(), basePackageName) + Map.Entry> entry -> processIncludedDirectory(relativizeContractPath(entry), entry.getValue(), basePackageName) } } @@ -68,7 +85,7 @@ class TestGenerator { } private void processIncludedDirectory( - final String includedDirectoryRelativePath, Collection contracts, final String basePackageNameForClass) { + final String includedDirectoryRelativePath, Collection contracts, final String basePackageNameForClass) { if (contracts.size()) { def className = afterLast(includedDirectoryRelativePath.toString(), File.separator) + resolveNameSuffix() def packageName = buildPackage(basePackageNameForClass, includedDirectoryRelativePath) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/BlockBuilder.groovy similarity index 55% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/BlockBuilder.groovy index 3ab11e9359..2f0fb85483 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BlockBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/BlockBuilder.groovy @@ -1,17 +1,43 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.cloud.contract.verifier.builder + +import groovy.transform.CompileDynamic +import groovy.transform.CompileStatic import groovy.transform.PackageScope /** - * @author Jakub Kubrynski + * Builds a block of code. Allows to start, end, indent etc. pieces of code. + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 */ @PackageScope +@CompileStatic class BlockBuilder { private final StringBuilder builder private final String spacer private int indents + /** + * @param spacer - char used for spacing + */ BlockBuilder(String spacer) { this.spacer = spacer builder = new StringBuilder() @@ -48,6 +74,7 @@ class BlockBuilder { return this } + @CompileDynamic private void addIndentation() { indents.times { builder << spacer @@ -72,7 +99,6 @@ class BlockBuilder { return this } - @Override String toString() { return builder.toString() diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ClassBuilder.groovy similarity index 71% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ClassBuilder.groovy index b24c5b57ec..4552ca7f05 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/ClassBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ClassBuilder.groovy @@ -1,11 +1,36 @@ -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 +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + +package org.springframework.cloud.contract.verifier.builder + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import org.springframework.cloud.contract.verifier.config.TestFramework +import org.springframework.cloud.contract.verifier.util.NamesUtil +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties + +/** + * Builds a class. Adds all the imports, static imports etc. + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 + */ +@CompileStatic +@PackageScope class ClassBuilder { private final String className @@ -29,7 +54,10 @@ class ClassBuilder { this.className = className } - static ClassBuilder createClass(String className, String classPackage, AccurestConfigProperties properties) { + /** + * Returns a {@link ClassBuilder} for the given parameters + */ + static ClassBuilder createClass(String className, String classPackage, ContractVerifierConfigProperties properties) { String baseClassForTests if (properties.targetFramework == TestFramework.SPOCK && !properties.baseClassForTests) { baseClassForTests = 'spock.lang.Specification' @@ -49,7 +77,6 @@ class ClassBuilder { return this } - ClassBuilder addStaticImport(String importToAdd) { staticImports << importToAdd return this diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy similarity index 68% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy index fa8551cdb2..bf58dbef87 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy @@ -1,25 +1,49 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.Input +import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty import java.util.regex.Pattern -import static io.codearte.accurest.config.TestFramework.JUNIT +import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT + /** - * @author Jakub Kubrynski + * Builds a JUnit method for messaging + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @author Marcin Grzejszczak + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 */ @PackageScope @TypeChecked class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { - JUnitMessagingMethodBodyBuilder(GroovyDsl stubDefinition) { + JUnitMessagingMethodBodyBuilder(Contract stubDefinition) { super(stubDefinition) } @@ -28,7 +52,7 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { if (request.triggeredBy) { return request.triggeredBy.executionCommand } - return "accurestMessaging.send(inputMessage, \"${request.messageFrom.serverValue}\")" + return "contractVerifierMessaging.send(inputMessage, \"${request.messageFrom.serverValue}\")" } @Override @@ -68,16 +92,16 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { - bb.addLine("""AccurestMessage response = accurestMessaging.receiveMessage("${outputMessage.sentTo.serverValue}");""") + bb.addLine("""ContractVerifierMessage response = contractVerifierMessaging.receiveMessage("${outputMessage.sentTo.serverValue}");""") bb.addLine("""assertThat(response).isNotNull();""") - outputMessage.headers?.collect { Header header ->\ + outputMessage.headers?.executeForEachHeader { Header header ->\ processHeaderElement(bb, header.name, header.serverValue) } } @Override protected String getResponseAsString() { - return 'accurestObjectMapper.writeValueAsString(response.getPayload())' + return 'contractVerifierObjectMapper.writeValueAsString(response.getPayload())' } @Override @@ -113,14 +137,14 @@ class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected String getInputString() { - String request = 'AccurestMessage inputMessage = accurestMessaging.create(' + String request = 'ContractVerifierMessage inputMessage = contractVerifierMessaging.create(' if (inputMessage.messageBody) { request = "${request}\n \"${StringEscapeUtils.escapeJava(bodyAsString)}\"\n " } if (inputMessage.messageHeaders) { request = "${request}, headers()\n" } - inputMessage.messageHeaders?.collect { Header header -> + inputMessage.messageHeaders?.executeForEachHeader { Header header -> request = "${request} ${getHeaderString(header)}" } return "${request})" diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy similarity index 69% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy index 543e8c41cf..8c3fc89258 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy @@ -1,29 +1,51 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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.NamedProperty -import io.codearte.accurest.dsl.internal.Request +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.verifier.dsl.internal.Request +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty import java.util.regex.Pattern import static groovy.json.StringEscapeUtils.escapeJava -import static io.codearte.accurest.config.TestFramework.JUNIT -import static io.codearte.accurest.util.ContentUtils.getJavaMultipartFileParameterContent +import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT +import static org.springframework.cloud.contract.verifier.util.ContentUtils.getJavaMultipartFileParameterContent /** - * @author Jakub Kubrynski - * @author Olga Maciaszek-Sharma + * Root class for JUnit method building + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @author Jakub Kubrynski, codearte.io + * @author Olga Maciaszek-Sharma, codearte.io + * + * @since 1.0.0 */ @TypeChecked @PackageScope abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder { - JUnitMethodBodyBuilder(GroovyDsl stubDefinition) { + JUnitMethodBodyBuilder(Contract stubDefinition) { super(stubDefinition) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy similarity index 66% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy index ab8506d61f..feb23dfd57 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientJUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy @@ -1,22 +1,48 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -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.QueryParameter -import io.codearte.accurest.dsl.internal.QueryParameters +package org.springframework.cloud.contract.verifier.builder + +import groovy.transform.PackageScope +import groovy.transform.TypeChecked +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameters import java.util.regex.Pattern -import static io.codearte.accurest.config.TestFramework.JUNIT +import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT /** - * @author Olga Maciaszek-Sharma - @since 21.02.16 + * JaxRs implementation of the {@link JUnitMethodBodyBuilder}. Knows how to build + * a test method for JaxRs. + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @author Olga Maciaszek-Sharma, codearte.io + * + * @since 1.0.0 */ +@TypeChecked +@PackageScope class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { - JaxRsClientJUnitMethodBodyBuilder(GroovyDsl stubDefinition) { + JaxRsClientJUnitMethodBodyBuilder(Contract stubDefinition) { super(stubDefinition) } @@ -74,7 +100,7 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { } protected appendHeaders(BlockBuilder bb) { - request.headers?.collect { Header header -> + request.headers?.executeForEachHeader { Header header -> if (header.name == 'Content-Type' || header.name == 'Accept') return bb.addLine(".header(\"${header.name}\", \"${header.serverValue}\")") } @@ -96,7 +122,7 @@ class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { - response.headers?.collect { Header header -> + response.headers?.executeForEachHeader { Header header -> processHeaderElement(bb, header.name, header.serverValue) } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy similarity index 69% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy index 86fe435034..b45c7981f2 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy @@ -1,20 +1,45 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.builder 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.QueryParameter -import io.codearte.accurest.dsl.internal.QueryParameters +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter +import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameters +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty import java.util.regex.Pattern +/** + * Knows how to build a Spock test method for JaxRs. + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @author Olga Maciaszek-Sharma, codearte.io + * + * @since 1.0.0 + */ @PackageScope @TypeChecked class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestProcessingBodyBuilder { - JaxRsClientSpockMethodRequestProcessingBodyBuilder(GroovyDsl stubDefinition) { + JaxRsClientSpockMethodRequestProcessingBodyBuilder(Contract stubDefinition) { super(stubDefinition) } @@ -80,7 +105,7 @@ class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequ } protected appendHeaders(BlockBuilder bb) { - request.headers?.collect { Header header -> + request.headers?.executeForEachHeader { Header header -> if (header.name == 'Content-Type' || header.name == 'Accept') return // Particular headers are set via 'request' / 'entity' methods bb.addLine(".header('${header.name}', '${header.serverValue}')") } @@ -97,7 +122,7 @@ class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequ @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { - response.headers?.collect { Header header -> + response.headers?.executeForEachHeader { Header header -> processHeaderElement(bb, header.name, header.serverValue) } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy similarity index 56% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy index 6da92a5bce..33229a001a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy @@ -1,18 +1,40 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Input +import org.springframework.cloud.contract.verifier.dsl.internal.OutputMessage +import org.springframework.cloud.contract.verifier.util.ContentType + +import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromContent +import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromHeader -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader /** - * @author Olga Maciaszek-Sharma - * @since 2016-02-17 + * Root class for messaging method building. + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @author Olga Maciaszek-Sharma, codearte.io + * + * @since 1.0.0 */ @TypeChecked @PackageScope @@ -21,7 +43,7 @@ abstract class MessagingMethodBodyBuilder extends MethodBodyBuilder { protected final Input inputMessage protected final OutputMessage outputMessage - MessagingMethodBodyBuilder(GroovyDsl stubDefinition) { + MessagingMethodBodyBuilder(Contract stubDefinition) { this.inputMessage = stubDefinition.input this.outputMessage = stubDefinition.outputMessage } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy similarity index 52% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy index 044394a1aa..eb7b7fc1ea 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy @@ -1,76 +1,186 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.builder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import io.codearte.accurest.dsl.internal.* -import io.codearte.accurest.util.ContentType -import io.codearte.accurest.util.JsonPaths -import io.codearte.accurest.util.JsonToJsonPathsConverter -import io.codearte.accurest.util.MapConverter +import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.verifier.util.MapConverter +import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy +import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter +import org.springframework.cloud.contract.verifier.util.ContentType +import org.springframework.cloud.contract.verifier.util.JsonPaths +import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.extractValue +import static org.springframework.cloud.contract.verifier.util.ContentUtils.extractValue + /** - * @author Olga Maciaszek-Sharma - * @since 2016-02-17 + * Main class for building method body. + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @author Olga Maciaszek-Sharma, codearte.io + * + * @since 1.0.0 */ @TypeChecked @PackageScope abstract class MethodBodyBuilder { + /** + * Builds the response body validation code block + */ protected abstract void validateResponseCodeBlock(BlockBuilder bb) + /** + * Builds the response headers validation code block + */ protected abstract void validateResponseHeadersBlock(BlockBuilder bb) + /** + * Builds the code that returns response in the string format + */ protected abstract String getResponseAsString() + /** + * Returns the given string with comment sign if required by the given implementation + */ protected abstract String addCommentSignIfRequired(String baseString) + /** + * Adds a colon sign at the end of each line if necessary + */ protected abstract BlockBuilder addColonIfRequired(BlockBuilder blockBuilder) + /** + * Builds the code that for the given {@code property} will compare it to + * the given {@code value} + */ protected abstract String getResponseBodyPropertyComparisonString(String property, String value) + /** + * Appends to the {@link BlockBuilder} the assertion for the given body element + */ protected abstract void processBodyElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) + /** + * Appends to the {@link BlockBuilder} the assertion for the given body element + */ protected abstract void processBodyElement(BlockBuilder blockBuilder, String property, Map.Entry entry) + /** + * Appends to the {@link BlockBuilder} the assertion for the given header element + */ protected abstract void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) + /** + * Appends to the {@link BlockBuilder} the assertion for the given header element + */ protected abstract void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) + /** + * Appends to the {@link BlockBuilder} the assertion for the given header element + */ protected abstract void processHeaderElement(BlockBuilder blockBuilder, String property, String value) + /** + * Appends to the {@link BlockBuilder} the code to retrieve a value for a property + * from the list with the given index + */ protected abstract String getPropertyInListString(String property, Integer index) protected abstract String convertUnicodeEscapesIfRequired(String json) + /** + * NOTE: XML support is experimental + */ protected abstract String getParsedXmlResponseBodyString(String responseString) + /** + * Builds the code that returns String from a body that is plain text + */ protected abstract String getSimpleResponseBodyString(String responseString) + /** + * Builds the code that returns the "message". For messaging it will be an input + * message. For REST it will be an input request. + */ protected abstract String getInputString() + /** + * Builds the code to append a header to the request / message + */ protected abstract String getHeaderString(Header header) + /** + * Builds the code to append body to the request / message + */ protected abstract String getBodyString(String bodyAsString) + /** + * Builds the code to append multipart content to the request. + * Not applicable for messaging. + */ protected abstract String getMultipartFileParameterContent(String propertyName, NamedProperty propertyValue) + /** + * Builds the code to append a form parameter to the request. + * Not applicable for messaging. + */ protected abstract String getParameterString(Map.Entry parameter) + /** + * Appends the code to {@link BlockBuilder} for initial request processing + */ protected abstract void processInput(BlockBuilder bb) + /** + * Appends the code to {@link BlockBuilder} for the {@code //when} block + */ protected abstract void when(BlockBuilder bb) + /** + * Appends the code to {@link BlockBuilder} for the {@code //then} block + */ protected abstract void then(BlockBuilder bb) + /** + * Returns a {@link org.springframework.cloud.contract.verifier.util.ContentType} for the given request + */ protected abstract ContentType getResponseContentType() + /** + * Converts the body into String format + */ protected abstract String getBodyAsString() + /** + * Returns {@code true} if given section should be created + */ protected abstract boolean hasGivenSection() + /** + * Builds the test contents and appends them to {@link BlockBuilder} + */ void appendTo(BlockBuilder blockBuilder) { blockBuilder.startBlock() @@ -83,6 +193,9 @@ abstract class MethodBodyBuilder { blockBuilder.endBlock() } + /** + * Prepares the {@code given} block section together with comments and indents + */ protected void givenBlock(BlockBuilder bb) { bb.addLine(addCommentSignIfRequired('given:')) bb.startBlock() @@ -90,6 +203,9 @@ abstract class MethodBodyBuilder { bb.endBlock().addEmptyLine() } + /** + * Prepares the {@code when} block section together with comments and indents + */ protected void whenBlock(BlockBuilder bb) { bb.addLine(addCommentSignIfRequired('when:')) bb.startBlock() @@ -97,6 +213,9 @@ abstract class MethodBodyBuilder { bb.endBlock().addEmptyLine() } + /** + * Prepares the {@code then} block section together with comments and indents + */ protected void thenBlock(BlockBuilder bb) { bb.addLine(addCommentSignIfRequired('then:')) bb.startBlock() @@ -104,6 +223,9 @@ abstract class MethodBodyBuilder { bb.endBlock() } + /** + * Builds the {@code given} block section together with comments and indents + */ protected void given(BlockBuilder bb) { bb.addLine(getInputString()) bb.indent() @@ -112,6 +234,10 @@ abstract class MethodBodyBuilder { bb.unindent() } + /** + * Builds the response body verification part. The code will differ depending on the + * ContentType, type of response etc. The result will be appended to {@link BlockBuilder} + */ protected void validateResponseBodyBlock(BlockBuilder bb, Object responseBody) { ContentType contentType = getResponseContentType() if (responseBody instanceof GString) { @@ -138,15 +264,24 @@ abstract class MethodBodyBuilder { } } + /** + * Post processing of each JSON path entry + */ protected String postProcessJsonPathCall(String jsonPath) { return jsonPath } + /** + * Appends to {@link BlockBuilder} parsing of the JSON Path document + */ protected void appendJsonPath(BlockBuilder blockBuilder, String json) { blockBuilder.addLine(("DocumentContext parsedJson = JsonPath.parse($json)")) addColonIfRequired(blockBuilder) } + /** + * Appends to {@link BlockBuilder} processing of the given String value. + */ protected void processText(BlockBuilder blockBuilder, String property, String value) { if (value.startsWith('$')) { value = stripFirstChar(value).replaceAll('\\$value', "responseBody$property") @@ -161,16 +296,29 @@ abstract class MethodBodyBuilder { return s.substring(1); } + /** + * Appends to the {@link BlockBuilder} the assertion for the given header element + */ protected void processHeaderElement(BlockBuilder blockBuilder, String property, Object value) { } + /** + * Appends to the {@link BlockBuilder} the assertion for the given body element + */ protected void processBodyElement(BlockBuilder blockBuilder, String property, Object value) { } + /** + * Removes unnecessary quotes + */ protected String trimRepeatedQuotes(String toTrim) { return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim } + /** + * Converts the passed body into ints server side representation. All {@link DslProperty} + * will return their server side values + */ protected Object extractServerValueFromBody(bodyValue) { if (bodyValue instanceof GString) { bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) @@ -180,28 +328,48 @@ abstract class MethodBodyBuilder { return bodyValue } + /** + * Converts the {@link org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter} server side value into its String + * representation + */ protected String resolveParamValue(QueryParameter param) { return resolveParamValue(param.serverValue) } + /** + * Converts the query parameter value into String + */ protected String resolveParamValue(Object value) { return value.toString() } + /** + * Converts the query parameter value into String + */ protected String resolveParamValue(MatchingStrategy matchingStrategy) { return matchingStrategy.serverValue.toString() } + /** + * Depending on the object type extracts the test side values and + * combines them into a String representation + */ protected String getTestSideValue(Object object) { return MapConverter.getTestSideValues(object).toString() } + /** + * Appends to the {@link BlockBuilder} the assertion for the given body element + */ protected void processBodyElement(BlockBuilder blockBuilder, String property, Map map) { map.each { processBodyElement(blockBuilder, property, it) } } + /** + * Appends to the {@link BlockBuilder} the assertion for the given body element + */ protected void processBodyElement(BlockBuilder blockBuilder, String property, List list) { list.eachWithIndex { listElement, listIndex -> String prop = getPropertyInListString(property, listIndex as Integer) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy new file mode 100644 index 0000000000..090f87273e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy @@ -0,0 +1,95 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.builder + +import groovy.transform.CompileStatic +import groovy.transform.PackageScope +import groovy.util.logging.Slf4j +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.config.TestFramework +import org.springframework.cloud.contract.verifier.util.NamesUtil +import org.springframework.cloud.contract.verifier.config.TestMode +import org.springframework.cloud.contract.verifier.file.ContractMetadata + +/** + * Builds a test method. Adds an ignore annotation on a method if necessary. + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 + */ +@Slf4j +@CompileStatic +@PackageScope +class MethodBuilder { + + private final String methodName + private final org.springframework.cloud.contract.verifier.dsl.Contract stubContent + private final ContractVerifierConfigProperties configProperties + private final boolean ignored + + private MethodBuilder(String methodName, org.springframework.cloud.contract.verifier.dsl.Contract stubContent, ContractVerifierConfigProperties configProperties, boolean ignored) { + this.ignored = ignored + this.stubContent = stubContent + this.methodName = methodName + this.configProperties = configProperties + } + + /** + * A factory method that creates a {@link MethodBuilder} for the given arguments + */ + static MethodBuilder createTestMethod(ContractMetadata contract, File stubsFile, org.springframework.cloud.contract.verifier.dsl.Contract stubContent, ContractVerifierConfigProperties 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) + } + + /** + * Appends to the {@link BlockBuilder} the contents of the test + */ + void appendTo(BlockBuilder blockBuilder) { + if (configProperties.targetFramework == TestFramework.JUNIT) { + blockBuilder.addLine('@Test') + } + if (ignored) { + blockBuilder.addLine('@Ignore') + } + blockBuilder.addLine(configProperties.targetFramework.methodModifier + "validate_$methodName() throws Exception {") + getMethodBodyBuilder().appendTo(blockBuilder) + blockBuilder.addLine('}') + } + + private MethodBodyBuilder getMethodBodyBuilder() { + if (stubContent.input || 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) + } + if (configProperties.testMode == TestMode.JAXRSCLIENT) { + if (configProperties.targetFramework == TestFramework.JUNIT){ + return new JaxRsClientJUnitMethodBodyBuilder(stubContent) + } + return new JaxRsClientSpockMethodRequestProcessingBodyBuilder(stubContent) + } + return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent) + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy new file mode 100644 index 0000000000..406ad8a5f2 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy @@ -0,0 +1,69 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.builder + +import groovy.transform.PackageScope +import groovy.transform.TypeChecked +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty + +import java.util.regex.Pattern + +/** + * A {@link JUnitMethodBodyBuilder} implementation that uses MockMvc to send requests. + * + * @author Olga Maciaszek-Sharma, codearte.io + * + * @since 1.0.0 + */ +@TypeChecked +@PackageScope +class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { + + MockMvcJUnitMethodBodyBuilder(Contract stubDefinition) { + super(stubDefinition) + } + + @Override + protected void validateResponseCodeBlock(BlockBuilder bb) { + bb.addLine("assertThat(response.statusCode()).isEqualTo($response.status.serverValue);") + } + + @Override + protected void validateResponseHeadersBlock(BlockBuilder bb) { + response.headers?.executeForEachHeader { Header header ->\ + processHeaderElement(bb, header.name, header.serverValue) + } + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, String value) { + blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(value)}") + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, Pattern pattern) { + blockBuilder.addLine("assertThat(response.header(\"$property\")).${createHeaderComparison(pattern)}") + } + + @Override + protected void processHeaderElement(BlockBuilder blockBuilder, String property, ExecutionProperty exec) { + blockBuilder.addLine("${exec.insertValue("response.header(\"$property\")")};") + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy similarity index 55% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy index 5d983c3e6c..742a49ab41 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy @@ -1,18 +1,39 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.builder 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 org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.dsl.internal.Header import java.util.regex.Pattern +/** + * A {@link SpockMethodRequestProcessingBodyBuilder} implementation that uses MockMvc to send requests. + * + * @since 1.0.0 + */ @PackageScope @TypeChecked class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestProcessingBodyBuilder { - MockMvcSpockMethodRequestProcessingBodyBuilder(GroovyDsl stubDefinition) { + MockMvcSpockMethodRequestProcessingBodyBuilder(Contract stubDefinition) { super(stubDefinition) } @@ -23,7 +44,7 @@ class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestP @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { - response.headers?.collect { Header header -> + response.headers?.executeForEachHeader { Header header -> processHeaderElement(bb, header.name, header.serverValue) } } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/RequestProcessingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy similarity index 57% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/RequestProcessingMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy index c26e09ab08..ce3385a18d 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/RequestProcessingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy @@ -1,26 +1,47 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Request +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy +import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter +import org.springframework.cloud.contract.verifier.dsl.internal.Response +import org.springframework.cloud.contract.verifier.dsl.internal.Url +import org.springframework.cloud.contract.verifier.util.ContentType +import org.springframework.cloud.contract.verifier.util.MapConverter -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader +import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromContent +import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromHeader /** - * @author Olga Maciaszek-Sharma - * @since 2016-02-17 + * An abstraction for creating a test method that includes processing of an HTTP request + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @author Olga Maciaszek-Sharma, codearte.io + * + * @since 1.0.0 */ @TypeChecked @PackageScope @@ -29,11 +50,14 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { protected final Request request protected final Response response - RequestProcessingMethodBodyBuilder(GroovyDsl stubDefinition) { + RequestProcessingMethodBodyBuilder(Contract stubDefinition) { this.request = stubDefinition.request this.response = stubDefinition.response } + /** + * Returns code used to retrieve a response for the given {@link Request} + */ protected abstract String getInputString(Request request) @Override @@ -41,20 +65,30 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { return true } + /** + * Returns {@code true} if the query parameter is allowed + */ protected boolean allowedQueryParameter(QueryParameter param) { return allowedQueryParameter(param.serverValue) } + /** + * Returns {@code true} if the query parameter is allowed + */ protected boolean allowedQueryParameter(MatchingStrategy matchingStrategy) { return matchingStrategy.type != MatchingStrategy.Type.ABSENT } + /** + * Returns {@code true} if the query parameter is allowed + */ protected boolean allowedQueryParameter(Object o) { return true } + @Override protected void processInput(BlockBuilder bb) { - request.headers?.collect { Header header -> + request.headers?.executeForEachHeader { Header header -> bb.addLine(getHeaderString(header)) } if (request.body) { @@ -65,6 +99,7 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { } } + @Override protected void when(BlockBuilder bb) { bb.addLine(getInputString(request)) bb.indent() @@ -77,6 +112,7 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { bb.unindent() } + @Override protected void then(BlockBuilder bb) { validateResponseCodeBlock(bb) if (response.headers) { @@ -89,6 +125,7 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { } } + @Override protected ContentType getResponseContentType() { ContentType contentType = recognizeContentTypeFromHeader(response.headers) if (contentType == ContentType.UNKNOWN) { @@ -97,6 +134,7 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { return contentType } + @Override protected String getBodyAsString() { Object bodyValue = extractServerValueFromBody(request.body.serverValue) String json = new JsonOutput().toJson(bodyValue) @@ -104,10 +142,16 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { return trimRepeatedQuotes(json) } + /** + * Returns a map of server side multipart parameters + */ protected Map getMultipartParameters() { return (Map) request?.multipart?.serverValue } + /** + * Maps the {@link Request} into a {@link ContentType} + */ protected ContentType getRequestContentType() { ContentType contentType = recognizeContentTypeFromHeader(request.headers) if (contentType == ContentType.UNKNOWN) { @@ -116,6 +160,10 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { return contentType } + /** + * Builds a String URL from {@link Request}'s test side values. It can be + * a concrete value of the URL or a path. + */ protected String buildUrl(Request request) { if (request.url) return getTestSideValue(buildUrlFromUrlPath(request.url)) @@ -124,6 +172,10 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { throw new IllegalStateException("URL is not set!") } + /** + * Depending on the presence of query parameters builds the String value + * of the URL. Retrieves any present test side values + */ @TypeChecked(TypeCheckingMode.SKIP) protected String buildUrlFromUrlPath(Url url) { if (hasQueryParams(url)) { @@ -138,6 +190,9 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { return MapConverter.getTestSideValues(url.serverValue) } + /** + * Returns a line of code to send a multi part parameter in the request + */ protected String getMultipartParameterLine(Map.Entry parameter) { if (parameter.value instanceof NamedProperty) { return ".multiPart(${getMultipartFileParameterContent(parameter.key, (NamedProperty) parameter.value)})" diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy similarity index 56% rename from accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy index ee8a8e64b1..58e406b66a 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/SingleTestGenerator.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy @@ -1,35 +1,58 @@ -package io.codearte.accurest +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.builder import groovy.transform.Canonical import groovy.transform.EqualsAndHashCode 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 io.codearte.accurest.util.AccurestDslConverter +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.config.TestFramework +import org.springframework.cloud.contract.verifier.file.ContractMetadata +import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter +import org.springframework.cloud.contract.verifier.config.TestMode -import static io.codearte.accurest.builder.ClassBuilder.createClass -import static io.codearte.accurest.builder.MethodBuilder.createTestMethod -import static io.codearte.accurest.util.NamesUtil.capitalize +import static ClassBuilder.createClass +import static MethodBuilder.createTestMethod +import static org.springframework.cloud.contract.verifier.util.NamesUtil.capitalize +/** + * Builds a single test for the given {@link ContractVerifierConfigProperties properties} + * + * @since 1.0.0 + */ @Slf4j class SingleTestGenerator { private static final String JSON_ASSERT_STATIC_IMPORT = 'com.toomuchcoding.jsonassert.JsonAssertion.assertThatJson' private static final String JSON_ASSERT_CLASS = 'com.toomuchcoding.jsonassert.JsonAssertion' - private final AccurestConfigProperties configProperties + private final ContractVerifierConfigProperties configProperties - SingleTestGenerator(AccurestConfigProperties configProperties) { + SingleTestGenerator(ContractVerifierConfigProperties configProperties) { this.configProperties = configProperties } + /** + * Returns String code representing a test class with test methods for + * each {@link ContractMetadata} + */ @PackageScope - String buildClass(Collection listOfFiles, String className, String classPackage) { + String buildClass(Collection listOfFiles, String className, String classPackage) { ClassBuilder clazz = createClass(capitalize(className), classPackage, configProperties) if (configProperties.imports) { @@ -55,13 +78,7 @@ class SingleTestGenerator { addJsonPathRelatedImports(clazz) - Map contracts = listOfFiles.collectEntries { - File stubsFile = it.path.toFile() - log.debug("Stub content from file [${stubsFile.text}]") - GroovyDsl stubContent = AccurestDslConverter.convert(stubsFile) - TestType testType = (stubContent.input || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP - return [(new ParsedDsl(it, stubContent, stubsFile)) : testType] - } + Map contracts = mapContractsToTheirTestTypes(listOfFiles) boolean conditionalImportsAdded = false contracts.each { ParsedDsl key, TestType value -> @@ -99,11 +116,21 @@ class SingleTestGenerator { return clazz.build() } + private Map mapContractsToTheirTestTypes(Collection listOfFiles) { + return listOfFiles.collectEntries { + File stubsFile = it.path.toFile() + log.debug("Stub content from file [${stubsFile.text}]") + org.springframework.cloud.contract.verifier.dsl.Contract stubContent = ContractVerifierDslConverter.convert(stubsFile) + TestType testType = (stubContent.input || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP + return [(new ParsedDsl(it, stubContent, stubsFile)): testType] + } + } + @Canonical @EqualsAndHashCode private static class ParsedDsl { - Contract contract - GroovyDsl groovyDsl + ContractMetadata contract + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl File stubsFile } @@ -111,7 +138,7 @@ class SingleTestGenerator { MESSAGING, HTTP } - private boolean isScenarioClass(Collection listOfFiles) { + private boolean isScenarioClass(Collection listOfFiles) { listOfFiles.find({ it.order != null }) != null } @@ -125,15 +152,15 @@ class SingleTestGenerator { } private ClassBuilder addMessagingRelatedEntries(ClassBuilder clazz) { - clazz.addField(['@Inject AccurestMessaging accurestMessaging', - 'AccurestObjectMapper accurestObjectMapper = new AccurestObjectMapper()' + clazz.addField(['@Inject ContractVerifierMessaging contractVerifierMessaging', + 'ContractVerifierObjectMapper contractVerifierObjectMapper = new ContractVerifierObjectMapper()' ]) clazz.addImport([ 'javax.inject.Inject', - 'io.codearte.accurest.messaging.AccurestObjectMapper', - 'io.codearte.accurest.messaging.AccurestMessage', - 'io.codearte.accurest.messaging.AccurestMessaging', + 'org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper', + 'org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage', + 'org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging', ]) - clazz.addStaticImport('io.codearte.accurest.messaging.AccurestMessagingUtil.headers') + clazz.addStaticImport('org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessagingUtil.headers') } private static boolean jsonAssertPresent() { diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy similarity index 71% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy index 0c9a0b5f83..7996f413f7 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy @@ -1,23 +1,39 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.Input +import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty import java.util.regex.Pattern /** - * @author Jakub Kubrynski + * @author Jakub Kubrynski, codearte.io */ @PackageScope @TypeChecked class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { - SpockMessagingMethodBodyBuilder(GroovyDsl stubDefinition) { + SpockMessagingMethodBodyBuilder(Contract stubDefinition) { super(stubDefinition) } @@ -26,7 +42,7 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { if (request.triggeredBy) { return request.triggeredBy.executionCommand } - return "accurestMessaging.send(inputMessage, '${request.messageFrom.serverValue}')" + return "contractVerifierMessaging.send(inputMessage, '${request.messageFrom.serverValue}')" } @Override @@ -62,7 +78,7 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected void validateResponseCodeBlock(BlockBuilder bb) { if (outputMessage) { - bb.addLine("""def response = accurestMessaging.receiveMessage('${outputMessage.sentTo.serverValue}')""") + bb.addLine("""def response = contractVerifierMessaging.receiveMessage('${outputMessage.sentTo.serverValue}')""") bb.addLine("""assert response != null""") } else { bb.addLine('noExceptionThrown()') @@ -71,14 +87,14 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected void validateResponseHeadersBlock(BlockBuilder bb) { - outputMessage.headers?.collect { Header header -> + outputMessage.headers?.executeForEachHeader { Header header -> processHeaderElement(bb, header.name, header.serverValue) } } @Override protected String getResponseAsString() { - return 'accurestObjectMapper.writeValueAsString(response.payload)' + return 'contractVerifierObjectMapper.writeValueAsString(response.payload)' } @Override @@ -113,7 +129,7 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { @Override protected String getInputString() { - String request = 'def inputMessage = accurestMessaging.create(' + String request = 'def inputMessage = contractVerifierMessaging.create(' if (inputMessage.messageBody) { request = "${request}'''${bodyAsString}'''\n " } @@ -121,7 +137,7 @@ class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { request = "${request},[\n" } def headers = [] - inputMessage.messageHeaders?.collect { Header header -> + inputMessage.messageHeaders?.executeForEachHeader { Header header -> headers << " ${getHeaderString(header)}" } request = "${request}${headers.join(',\n')}" diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy similarity index 66% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodRequestProcessingBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy index c149c13bb8..cc60ff5055 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/SpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy @@ -1,26 +1,46 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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.NamedProperty -import io.codearte.accurest.dsl.internal.Request +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.verifier.dsl.internal.Request +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.getGroovyMultipartFileParameterContent +import static org.springframework.cloud.contract.verifier.util.ContentUtils.getGroovyMultipartFileParameterContent /** - * @author Jakub Kubrynski + * A {@link RequestProcessingMethodBodyBuilder} implementation that uses Spock + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 */ @PackageScope @TypeChecked abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessingMethodBodyBuilder { - SpockMethodRequestProcessingBodyBuilder(GroovyDsl stubDefinition) { + SpockMethodRequestProcessingBodyBuilder(Contract stubDefinition) { super(stubDefinition) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy similarity index 59% rename from accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy index 53567ed1a2..58b81803a4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/AccurestConfigProperties.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy @@ -1,8 +1,29 @@ -package io.codearte.accurest.config -/** - * @author Jakub Kubrynski +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ -class AccurestConfigProperties { + +package org.springframework.cloud.contract.verifier.config + +/** + * Represents Contract Verifier configuration properties + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 + */ +class ContractVerifierConfigProperties { /** * For which unit test library tests should be generated @@ -34,18 +55,13 @@ class AccurestConfigProperties { */ String ruleClassForTests - /** - * Which version of JSON Assert (com.toomuchcoding.jsonassert:jsonassert) to use - */ - String jsonAssertVersion = "+" - /** * Patterns that should not be taken into account for processing */ List excludedFiles = [] /** - * Patterns for which Accurest should generate @Ignored tests + * Patterns for which generated tests should be @Ignored */ List ignoredFiles = [] diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestFramework.groovy similarity index 66% rename from accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestFramework.groovy index 42d420ee7b..8b5f14e707 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/config/TestFramework.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestFramework.groovy @@ -1,7 +1,27 @@ -package io.codearte.accurest.config +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.config /** - * @author Jakub Kubrynski + * Contains main building blocks for a test class for the given framework + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 */ enum TestFramework { JUNIT("public ", "public void ", ";", ".java", "Test", "org.junit.Ignore", ["org.junit.FixMethodOrder", "org.junit.runners.MethodSorters"], "@FixMethodOrder(MethodSorters.NAME_ASCENDING)"), diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy new file mode 100644 index 0000000000..a6df25c9e3 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.config + +/** + * Provides different testing modes + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 + */ +enum TestMode { + /** + * Uses Spring's MockMvc + */ + MOCKMVC, + + /** + * Uses direct HTTP invocations + */ + EXPLICIT, + + /** + * Uses JAX-RS client + */ + JAXRSCLIENT +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/Contract.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/Contract.groovy new file mode 100644 index 0000000000..57ccd03dea --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/Contract.groovy @@ -0,0 +1,93 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl + +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString +import groovy.transform.TypeChecked +import org.springframework.cloud.contract.verifier.dsl.internal.Input +import org.springframework.cloud.contract.verifier.dsl.internal.OutputMessage +import org.springframework.cloud.contract.verifier.dsl.internal.Request +import org.springframework.cloud.contract.verifier.dsl.internal.Response + +/** + * The point of entry to the DSL + * + * @since 1.0.0 + */ +@TypeChecked +@EqualsAndHashCode +@ToString(includeFields = true, includePackage = false, includeNames = true) +class Contract { + + Integer priority + Request request + Response response + String label + String description + Input input + OutputMessage outputMessage + + protected Contract() {} + + /** + * Factory method to create the DSL + */ + static Contract make(Closure closure) { + Contract dsl = new Contract() + closure.delegate = dsl + closure() + return dsl + } + + void priority(int priority) { + this.priority = priority + } + + void label(String label) { + this.label = label + } + + void description(String description) { + this.description = description + } + + void request(@DelegatesTo(Request) Closure closure) { + this.request = new Request() + closure.delegate = request + closure() + } + + void response(@DelegatesTo(Response) Closure closure) { + this.response = new Response() + closure.delegate = response + closure() + } + + void input(@DelegatesTo(Input) Closure closure) { + this.input = new Input() + closure.delegate = input + closure() + } + + void outputMessage(@DelegatesTo(OutputMessage) Closure closure) { + this.outputMessage = new OutputMessage() + closure.delegate = outputMessage + closure() + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Body.groovy similarity index 59% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Body.groovy index df799d87f8..07051bd494 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Body.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Body.groovy @@ -1,9 +1,30 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString +/** + * Represents a body of a request / response or a message + * + * @since 1.0.0 + */ @ToString(includePackage = false, includeFields = true, includeNames = true) @EqualsAndHashCode(includeFields = true) @CompileStatic diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ClientDslProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ClientDslProperty.groovy new file mode 100644 index 0000000000..4e0a7aad8e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ClientDslProperty.groovy @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.CompileStatic + +/** + * Represents a client side {@link DslProperty} + * + * @since 1.0.0 + */ +@CompileStatic +class ClientDslProperty extends DslProperty { + + ClientDslProperty(Object singleValue) { + super(singleValue) + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Common.groovy similarity index 83% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Common.groovy index a6d86e080b..f167521fa4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Common.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Common.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.PackageScope import groovy.transform.TypeChecked @@ -6,8 +22,12 @@ import groovy.transform.TypeChecked import java.util.regex.Pattern /** + * Contains useful common methods for the DSL. + * * @TypeChecked instead of @CompileStatic due to usage of double dispatch. * Double dispatch doesn't work if you're using @CompileStatic + * + * @since 1.0.0 */ @TypeChecked @PackageScope diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/DslProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/DslProperty.groovy new file mode 100644 index 0000000000..b7bea9e3fb --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/DslProperty.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +/** + * Represents an element of a DSL that can contain client or sever side values + * + * @since 1.0.0 + */ +@CompileStatic +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeNames = true) +class DslProperty { + + final T clientValue + final T serverValue + + DslProperty(T clientValue, T serverValue) { + this.clientValue = clientValue + this.serverValue = serverValue + } + + DslProperty(T singleValue) { + this.clientValue = singleValue + this.serverValue = singleValue + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionProperty.groovy new file mode 100644 index 0000000000..8948cccf0e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionProperty.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.CompileStatic + +/** + * Represents a property that will become an executable method in the + * generated tests + * + * @since 1.0.0 + */ +@CompileStatic +class ExecutionProperty { + + private static final String PLACEHOLDER_VALUE = '\\$it' + + final String executionCommand + + ExecutionProperty(String executionCommand) { + this.executionCommand = executionCommand + } + + /** + * Inserts the provided code as a parameter to the method and returns + * the code that represents that method execution + */ + String insertValue(String valueToInsert) { + return executionCommand.replaceAll(PLACEHOLDER_VALUE, valueToInsert) + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Header.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Header.groovy new file mode 100644 index 0000000000..3ab86a08b6 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Header.groovy @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +/** + * Represents a header of a request / response or a message + * + * @since 1.0.0 + */ +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@CompileStatic +class Header extends DslProperty { + + String name + + Header(String name, DslProperty dslProperty) { + super(dslProperty.clientValue, dslProperty.serverValue) + this.name = name + } + + Header(String name, Object value) { + super(value) + this.name = name + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Headers.groovy similarity index 54% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Headers.groovy index 98e7bed9bc..03af32fbe9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Headers.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Headers.groovy @@ -1,9 +1,30 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked +/** + * Represents a set of headers of a request / response or a message + * + * @since 1.0.0 + */ @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) @TypeChecked @@ -20,12 +41,16 @@ class Headers { entries << new Header(headerKey, headerValue) } - void collect(Closure closure) { + void executeForEachHeader(Closure closure) { entries?.each { header -> closure(header) } } + /** + * Converts the headers into their stub side representations and returns as + * a map of String key => Object value. + */ Map asStubSideMap() { def acc = [:].withDefault { [] as Collection } return entries.inject(acc as Map) { Map map, Header header -> diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Input.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Input.groovy similarity index 58% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Input.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Input.groovy index 0b833c4090..34a16d1579 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Input.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Input.groovy @@ -1,10 +1,32 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked +/** + * Represents an input for messaging. The input can be a message or some + * action inside the application. + * + * @since 1.0.0 + */ @TypeChecked @EqualsAndHashCode @ToString(includePackage = false, includeNames = true) @@ -24,22 +46,37 @@ class Input extends Common { this.messageBody = input.messageBody } + /** + * Helper method to provide a better name for the producer side + */ ServerDslProperty producer(Object clientValue) { return new ServerDslProperty(clientValue) } + /** + * Helper method to provide a better name for the consumer side + */ ClientDslProperty consumer(Object clientValue) { return new ClientDslProperty(clientValue) } + /** + * Name of a destination from which message would come to trigger action in the system + */ void messageFrom(String messageFrom) { this.messageFrom = new DslProperty<>(messageFrom) } + /** + * Name of a destination from which message would come to trigger action in the system + */ void messageFrom(DslProperty messageFrom) { this.messageFrom = messageFrom } + /** + * Function that needs to be executed to trigger action in the system + */ void triggeredBy(String triggeredBy) { this.triggeredBy = new ExecutionProperty(triggeredBy) } @@ -54,7 +91,7 @@ class Input extends Common { closure() } - public static class BodyType extends DslProperty { + static class BodyType extends DslProperty { BodyType(Object clientValue, Object serverValue) { super(clientValue, serverValue) @@ -70,6 +107,7 @@ class Input extends Common { } } + @CompileStatic @EqualsAndHashCode @ToString(includePackage = false) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/JSONCompareMode.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/JSONCompareMode.groovy new file mode 100644 index 0000000000..8fb8d92738 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/JSONCompareMode.groovy @@ -0,0 +1,26 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +/** + * Represents JSON comparison modes + * + * @since 1.0.0 + */ +enum JSONCompareMode { + STRICT, LENIENT, NON_EXTENSIBLE, STRICT_ORDER +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/MatchingStrategy.groovy similarity index 59% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/MatchingStrategy.groovy index 191af8d7ee..f4d1ec0248 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/MatchingStrategy.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/MatchingStrategy.groovy @@ -1,9 +1,30 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString; +/** + * Represents a matching strategy for a JSON + * + * @since 1.0.0 + */ @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) @CompileStatic @@ -33,7 +54,6 @@ class MatchingStrategy extends DslProperty { } enum Type { - EQUAL_TO("equalTo"), CONTAINS("containing"), MATCHING("matches"), NOT_MATCHING("doesNotMatch"), EQUAL_TO_JSON("equalToJson"), EQUAL_TO_XML("equalToXml"), ABSENT("absent") diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Multipart.groovy similarity index 66% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Multipart.groovy index 1ebc06e1e7..554afad2ae 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Multipart.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Multipart.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/NamedProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/NamedProperty.groovy new file mode 100644 index 0000000000..6c1ca066c7 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/NamedProperty.groovy @@ -0,0 +1,48 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +/** + * Represents a property that has name and content. Used together with + * multipart requests. + * + * @since 1.0.0 + */ +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +@CompileStatic +class NamedProperty { + + private static final String NAME = 'name' + private static final String CONTENT = 'content' + + DslProperty name + DslProperty value + + NamedProperty(DslProperty name, DslProperty value) { + this.name = name + this.value = value + } + + NamedProperty(Map namedMap) { + this(namedMap?.get(NAME), namedMap?.get(CONTENT)) + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OptionalProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OptionalProperty.groovy new file mode 100644 index 0000000000..d822cb043f --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OptionalProperty.groovy @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.CompileStatic + +/** + * Represents a property that may or may not be there + * + * @since 1.0.0 + */ +@CompileStatic +class OptionalProperty { + final Object value + + OptionalProperty(Object value) { + this.value = value + } + + /** + * String version of a regular expression that wraps the provided value + * in an optional function + */ + String optionalPattern() { + return "($value)?" + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OutputMessage.groovy similarity index 70% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OutputMessage.groovy index b173c6481c..0435ac5a76 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/OutputMessage.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OutputMessage.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameter.groovy similarity index 50% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameter.groovy index c0ca01c97b..21e6aab67c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/QueryParameter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameter.groovy @@ -1,11 +1,32 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -import static io.codearte.accurest.util.ValidateUtils.validateServerValueIsAvailable +import static org.springframework.cloud.contract.verifier.util.ValidateUtils.validateServerValueIsAvailable +/** + * Represents a single HTTP query parameter + * + * @since 1.0.0 + */ @EqualsAndHashCode(includeFields = true) @ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) @CompileStatic diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameters.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameters.groovy new file mode 100644 index 0000000000..dd69ff707a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameters.groovy @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString +import groovy.transform.TypeChecked + +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false, includeFields = true, ignoreNulls = true, includeNames = true) +@TypeChecked +class QueryParameters { + + List parameters = [] + + void parameter(Map singleParameter) { + Map.Entry first = singleParameter.entrySet().first() + parameters << new QueryParameter(first?.key, first?.value) + } + + void parameter(String parameterName, Object parameterValue) { + parameters << new QueryParameter(parameterName, parameterValue) + } + +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatterns.groovy similarity index 69% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatterns.groovy index 1c18226fd9..4315e7965c 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/RegexPatterns.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatterns.groovy @@ -1,9 +1,30 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.CompileStatic import java.util.regex.Pattern +/** + * Contains most common regular expression patterns + * + * @since 1.0.0 + */ @CompileStatic class RegexPatterns { @@ -15,7 +36,6 @@ class RegexPatterns { private static final Pattern EMAIL = Pattern.compile('[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,4}'); private static final Pattern URL = Pattern.compile('((www\\.|(http|https|ftp|news|file)+\\:\\/\\/)[_.a-z0-9-]+\\.[a-z0-9\\/_:@=.+?,##%&~-]*[^.|\\\'|\\# |!|\\(|?|,| |>|<|;|\\)])') - String onlyAlphaUnicode() { return ONLY_ALPHA_UNICODE.pattern() } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Request.groovy similarity index 83% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Request.groovy index 54d57e8c53..8e189a9b60 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Request.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Request.groovy @@ -1,9 +1,31 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked +/** + * Represents the request side of the HTTP communication + * + * @since 1.0.0 + */ @TypeChecked @EqualsAndHashCode @ToString(includePackage = false, includeNames = true) diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Response.groovy similarity index 67% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Response.groovy index 9078add18f..44da4a5aa9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/internal/Response.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Response.groovy @@ -1,10 +1,31 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked +/** + * Represents the response side of the HTTP communication + * + * @since 1.0.0 + */ @TypeChecked @EqualsAndHashCode @ToString(includePackage = false, includeFields = true) @@ -55,7 +76,7 @@ class Response extends Common { this.delay = toDslProperty(timeInMilliseconds) } - public void async() { + void async() { this.async = true } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ServerDslProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ServerDslProperty.groovy new file mode 100644 index 0000000000..3f2cf0e59e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ServerDslProperty.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +/** + * Represents a server side {@link DslProperty} + * + * @since 1.0.0 + */ +@CompileStatic +@EqualsAndHashCode(includeFields = true) +@ToString(includePackage = false) +class ServerDslProperty extends DslProperty { + + ServerDslProperty(Object singleValue) { + super(singleValue) + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Url.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Url.groovy new file mode 100644 index 0000000000..8c5b3e8a0f --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Url.groovy @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +import static org.springframework.cloud.contract.verifier.util.ValidateUtils.validateServerValueIsAvailable + +/** + * Represents a URL that may contain query parameters + * + * @since 1.0.0 + */ +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +@CompileStatic +class Url extends DslProperty { + + QueryParameters queryParameters + + Url(DslProperty prop) { + super(prop.clientValue, prop.serverValue) + validateServerValueIsAvailable(prop.serverValue, "Url") + } + + Url(Object url) { + super(url) + validateServerValueIsAvailable(url, "Url") + } + + void queryParameters(@DelegatesTo(QueryParameters) Closure closure) { + this.queryParameters = new QueryParameters() + closure.delegate = queryParameters + closure() + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/UrlPath.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/UrlPath.groovy new file mode 100644 index 0000000000..62a8d8c60e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/UrlPath.groovy @@ -0,0 +1,41 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import groovy.transform.CompileStatic +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString + +/** + * Represents a url path + * + * @since 1.0.0 + */ +@ToString(includePackage = false, includeFields = true, includeNames = true) +@EqualsAndHashCode(includeFields = true) +@CompileStatic +class UrlPath extends Url { + + UrlPath(String path) { + super(path) + } + + UrlPath(DslProperty path) { + super(path) + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy new file mode 100755 index 0000000000..914c705bb6 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy @@ -0,0 +1,126 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.wiremock + +import groovy.json.JsonBuilder +import groovy.transform.PackageScope +import groovy.transform.TypeChecked +import org.springframework.cloud.contract.verifier.dsl.internal.Headers +import org.springframework.cloud.contract.verifier.util.MapConverter +import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.verifier.util.ContentType +import org.springframework.cloud.contract.verifier.util.ContentUtils + +import static ContentUtils.extractValue +import static MapConverter.transformValues + +/** + * Common abstraction over WireMock Request / Response conversion implementations + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @since 1.0.0 + */ +@TypeChecked +@PackageScope +abstract class BaseWireMockStubStrategy { + + /** + * Returns the stub side values from the object + */ + protected getStubSideValue(Object object) { + return MapConverter.getStubSideValues(object) + } + + private static Closure transform = { + it instanceof DslProperty ? transformValues(it.clientValue, transform) : it + } + + /** + * For the given {@link org.springframework.cloud.contract.verifier.util.ContentType} returns the String version of the body + */ + String parseBody(Object value, ContentType contentType) { + return parseBody(value.toString(), contentType) + } + + /** + * For the given {@link ContentType} returns the Boolean version of the body + */ + Boolean parseBody(Boolean value, ContentType contentType) { + return value + } + + /** + * For the given {@link ContentType} returns the String version of the body + */ + String parseBody(Map map, ContentType contentType) { + def transformedMap = MapConverter.getStubSideValues(map) + return parseBody(toJson(transformedMap), contentType) + } + + /** + * For the given {@link ContentType} returns the String version of the body + */ + String parseBody(List list, ContentType contentType) { + List result = [] + list.each { + if (it instanceof Map) { + result += MapConverter.getStubSideValues(it) + } else { + result += parseBody(it, contentType) + } + } + return parseBody(toJson(result), contentType) + } + + /** + * For the given {@link ContentType} returns the String version of the body + */ + String parseBody(GString value, ContentType contentType) { + Object processedValue = extractValue(value, contentType, { DslProperty dslProperty -> dslProperty.clientValue }) + if (processedValue instanceof GString) { + return parseBody(processedValue.toString(), contentType) + } + return parseBody(processedValue, contentType) + } + + /** + * For the given {@link ContentType} returns the String version of the body + */ + String parseBody(String value, ContentType contentType) { + return value + } + + private static toJson(Object value) { + return new JsonBuilder(value).toString() + } + + /** + * Attempts to guess the {@link ContentType} from body and headers. Returns + * {@link ContentType#UNKNOWN} if it fails to guess. + */ + protected ContentType tryToGetContentType(Object body, Headers headers) { + ContentType contentType = ContentUtils.recognizeContentTypeFromHeader(headers) + if (contentType == ContentType.UNKNOWN) { + if (!body) { + return ContentType.UNKNOWN + } + return ContentUtils.getClientContentType(body) + } + return contentType + } +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy similarity index 78% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy index 07955fc699..0fad82f131 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockRequestStubStrategy.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy @@ -1,4 +1,21 @@ -package io.codearte.accurest.dsl +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.wiremock + import com.github.tomakehurst.wiremock.http.RequestMethod import com.github.tomakehurst.wiremock.matching.RequestPattern import com.github.tomakehurst.wiremock.matching.ValuePattern @@ -6,36 +23,42 @@ import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode -import io.codearte.accurest.dsl.internal.Body -import io.codearte.accurest.dsl.internal.DslProperty -import io.codearte.accurest.dsl.internal.MatchingStrategy -import io.codearte.accurest.dsl.internal.NamedProperty -import io.codearte.accurest.dsl.internal.OptionalProperty -import io.codearte.accurest.dsl.internal.QueryParameters -import io.codearte.accurest.dsl.internal.RegexPatterns -import io.codearte.accurest.dsl.internal.Request -import io.codearte.accurest.util.ContentType -import io.codearte.accurest.util.ContentUtils -import io.codearte.accurest.util.JsonPaths -import io.codearte.accurest.util.JsonToJsonPathsConverter -import io.codearte.accurest.util.MapConverter +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Body +import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameters +import org.springframework.cloud.contract.verifier.util.ContentUtils +import org.springframework.cloud.contract.verifier.util.JsonPaths +import org.springframework.cloud.contract.verifier.util.MapConverter +import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.verifier.dsl.internal.OptionalProperty +import org.springframework.cloud.contract.verifier.dsl.internal.RegexPatterns +import org.springframework.cloud.contract.verifier.dsl.internal.Request +import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter +import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy +import org.springframework.cloud.contract.verifier.util.ContentType import java.util.regex.Pattern -import static io.codearte.accurest.util.ContentUtils.getEqualsTypeFromContentType -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromMatchingStrategy -import static io.codearte.accurest.util.RegexpBuilders.buildGStringRegexpForStubSide -import static io.codearte.accurest.util.RegexpBuilders.buildJSONRegexpMatch +import static ContentUtils.getEqualsTypeFromContentType +import static ContentUtils.recognizeContentTypeFromContent +import static ContentUtils.recognizeContentTypeFromHeader +import static ContentUtils.recognizeContentTypeFromMatchingStrategy +import static org.springframework.cloud.contract.verifier.util.RegexpBuilders.buildGStringRegexpForStubSide +import static org.springframework.cloud.contract.verifier.util.RegexpBuilders.buildJSONRegexpMatch +/** + * Converts a {@link Request} into {@link RequestPattern} + * + * @since 1.0.0 + */ @TypeChecked @PackageScope class WireMockRequestStubStrategy extends BaseWireMockStubStrategy { private final Request request - WireMockRequestStubStrategy(GroovyDsl groovyDsl) { + WireMockRequestStubStrategy(Contract groovyDsl) { this.request = groovyDsl.request } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy similarity index 54% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy index 1d19dfcb38..96eda8c33b 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockResponseStubStrategy.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.dsl +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.wiremock import com.github.tomakehurst.wiremock.client.ResponseDefinitionBuilder import com.github.tomakehurst.wiremock.http.HttpHeader @@ -6,23 +22,27 @@ import com.github.tomakehurst.wiremock.http.HttpHeaders import com.github.tomakehurst.wiremock.http.ResponseDefinition import groovy.transform.PackageScope import groovy.transform.TypeChecked -import io.codearte.accurest.dsl.internal.Request -import io.codearte.accurest.dsl.internal.Response -import io.codearte.accurest.util.ContentType +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.internal.Request +import org.springframework.cloud.contract.verifier.dsl.internal.Response +import org.springframework.cloud.contract.verifier.util.ContentType -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromContent -import static io.codearte.accurest.util.ContentUtils.recognizeContentTypeFromHeader +import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromContent +import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromHeader +/** + * Converts a {@link Request} into {@link ResponseDefinition} + * + * @since 1.0.0 + */ @TypeChecked @PackageScope class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { - private final Request request private final Response response - WireMockResponseStubStrategy(GroovyDsl groovyDsl) { + WireMockResponseStubStrategy(Contract groovyDsl) { this.response = groovyDsl.response - this.request = groovyDsl.request } @PackageScope @@ -58,6 +78,7 @@ class WireMockResponseStubStrategy extends BaseWireMockStubStrategy { } private void appendResponseDelayTime(ResponseDefinitionBuilder builder) { + // TODO: Add a missing test for this if (response.delay) { builder.withFixedDelay(response.delay.clientValue as Integer) } diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy similarity index 60% rename from accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy index 2f1cb8b0f4..e40850cbe4 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/dsl/WireMockStubStrategy.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy @@ -1,12 +1,33 @@ -package io.codearte.accurest.dsl +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.wiremock import com.github.tomakehurst.wiremock.http.ResponseDefinition import com.github.tomakehurst.wiremock.matching.RequestPattern import com.github.tomakehurst.wiremock.stubbing.StubMapping import groovy.transform.CompileDynamic import groovy.transform.CompileStatic -import io.codearte.accurest.file.Contract +import org.springframework.cloud.contract.verifier.file.ContractMetadata +/** + * Converts a {@link ContractMetadata} into a WireMock stub + * + * @since 1.0.0 + */ @CompileStatic class WireMockStubStrategy { @@ -15,10 +36,10 @@ class WireMockStubStrategy { private final WireMockRequestStubStrategy wireMockRequestStubStrategy private final WireMockResponseStubStrategy wireMockResponseStubStrategy private final Integer priority - private final Contract contract + private final ContractMetadata contract private final String rootName - WireMockStubStrategy(String rootName, Contract contract, GroovyDsl groovyDsl) { + WireMockStubStrategy(String rootName, ContractMetadata contract, org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl) { this.rootName = rootName this.contract = contract this.wireMockRequestStubStrategy = new WireMockRequestStubStrategy(groovyDsl) @@ -26,6 +47,9 @@ class WireMockStubStrategy { this.priority = groovyDsl.priority } + /** + * Converts {@link ContractMetadata} to String version of {@link StubMapping} + */ @CompileDynamic String toWireMockClientStub() { StubMapping stubMapping = new StubMapping() diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy similarity index 58% rename from accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy index cc00799c08..7b7ad47618 100755 --- a/accurest-core/src/main/groovy/io/codearte/accurest/file/ContractFileScanner.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy @@ -1,7 +1,24 @@ -package io.codearte.accurest.file +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.file import com.google.common.collect.ArrayListMultimap import com.google.common.collect.ListMultimap +import groovy.transform.CompileStatic import org.apache.commons.io.FilenameUtils import org.apache.commons.lang3.SystemUtils @@ -12,8 +29,14 @@ import java.nio.file.PathMatcher import java.util.regex.Pattern /** - * @author Jakub Kubrynski + * Scans the provided file path for the DSLs. There's a possibility to provide + * inclusion and exclusion filters. + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 */ +@CompileStatic class ContractFileScanner { private static final String MATCH_PREFIX = "glob:" @@ -24,8 +47,8 @@ class ContractFileScanner { ContractFileScanner(File baseDir, Set excluded, Set ignored) { this.baseDir = baseDir - excludeMatchers = processPatterns(excluded) - ignoreMatchers = processPatterns(ignored) + excludeMatchers = processPatterns(excluded ?: [] as Set) + ignoreMatchers = processPatterns(ignored ?: [] as Set) } private Set processPatterns(Set patterns) { @@ -40,13 +63,16 @@ class ContractFileScanner { }) as Set } - ListMultimap findContracts() { - ListMultimap result = ArrayListMultimap.create() + /** + * Returns for a map of paths for which a list of matching contracts has been found + */ + ListMultimap findContracts() { + ListMultimap result = ArrayListMultimap.create() appendRecursively(baseDir, result) return result } - private void appendRecursively(File baseDir, ListMultimap result) { + private void appendRecursively(File baseDir, ListMultimap result) { File[] files = baseDir.listFiles() if (!files) { return; @@ -59,7 +85,7 @@ class ContractFileScanner { if (hasScenarioFilenamePattern(path)) { order = index } - result.put(file.parentFile.toPath(), new Contract(path, matchesPattern(file, ignoreMatchers), files.size(), order)) + result.put(file.parentFile.toPath(), new ContractMetadata(path, matchesPattern(file, ignoreMatchers), files.size(), order)) } else { appendRecursively(file, result) } @@ -71,7 +97,7 @@ class ContractFileScanner { return SCENARIO_STEP_FILENAME_PATTERN.matcher(path.fileName.toString()).matches() } - boolean matchesPattern(File file, Set excludeMatchers) { + private boolean matchesPattern(File file, Set excludeMatchers) { for (PathMatcher matcher : excludeMatchers) { if (matcher.matches(file.toPath())) { return true; diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy new file mode 100644 index 0000000000..f201949740 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.file + +import groovy.transform.CompileStatic + +import java.nio.file.Path + +/** + * Contains metadata for a particular file with a DSL + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 + */ +@CompileStatic +class ContractMetadata { + final Path path; + final boolean ignored; + final int groupSize + final Integer order; + + ContractMetadata(Path path, boolean ignored, int groupSize, Integer order) { + this.groupSize = groupSize + this.path = path + this.ignored = ignored + this.order = order + } + + @Override + public String toString() { + return "ContractMetadata{" + + "fileName=" + path.fileName + + ", ignored=" + ignored + + ", groupSize=" + groupSize + + ", order=" + order + + '}'; + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BodyAsString.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy similarity index 51% rename from accurest-core/src/main/groovy/io/codearte/accurest/builder/BodyAsString.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy index 7b03c5d126..44963c84b3 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/builder/BodyAsString.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy @@ -1,19 +1,45 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util import groovy.json.JsonOutput import groovy.json.StringEscapeUtils -import io.codearte.accurest.dsl.internal.DslProperty -import io.codearte.accurest.util.MapConverter - -import static io.codearte.accurest.util.ContentUtils.extractValue +import groovy.transform.CompileStatic +import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import static ContentUtils.extractValue /** - * Class that constructs a String from Body + * Class that constructs a String from a body. The body can be a GString + * or a map. * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ -class BodyAsString { +@CompileStatic +class BodyAsStringUtil { + private BodyAsStringUtil() {} + + /** + * Returns the string representation of the body for the server side. + * That means that all the interpolations etc. will be resolved for the + * server side. + */ static String extractServerValueFrom(Object body) { Object bodyValue = extractServerValueFromBody(body) String json = new JsonOutput().toJson(bodyValue) @@ -21,6 +47,11 @@ class BodyAsString { return trimRepeatedQuotes(json) } + /** + * Returns the string representation of the body for the client side. + * That means that all the interpolations etc. will be resolved for the + * client side. + */ static String extractClientValueFrom(Object body) { Object bodyValue = extractClientValueFromBody(body); String json = new JsonOutput().toJson(bodyValue) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy new file mode 100644 index 0000000000..48887c3744 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util + +/** + * Represents content type + * + * @since 1.0.0 + */ +enum ContentType { + + JSON("application/json"), + XML("application/xml"), + UNKNOWN("application/octet-stream") + + final String mimeType + + ContentType(String mimeType) { + this.mimeType = mimeType + } + +} \ No newline at end of file diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy similarity index 91% rename from accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy index b8608f767a..c2168f564d 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/ContentUtils.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy @@ -1,16 +1,32 @@ -package io.codearte.accurest.util +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util import groovy.json.JsonException import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.transform.TypeChecked import groovy.util.logging.Slf4j -import io.codearte.accurest.dsl.internal.DslProperty -import io.codearte.accurest.dsl.internal.ExecutionProperty -import io.codearte.accurest.dsl.internal.Headers -import io.codearte.accurest.dsl.internal.MatchingStrategy -import io.codearte.accurest.dsl.internal.NamedProperty -import io.codearte.accurest.dsl.internal.OptionalProperty +import org.springframework.cloud.contract.verifier.dsl.internal.Headers import org.codehaus.groovy.runtime.GStringImpl +import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy +import org.springframework.cloud.contract.verifier.dsl.internal.OptionalProperty import java.util.regex.Matcher import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy new file mode 100644 index 0000000000..31c29365f3 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util + +import groovy.transform.CompileStatic +import org.codehaus.groovy.control.CompilerConfiguration +import org.springframework.cloud.contract.verifier.dsl.Contract + +/** + * Converts a file or String into a {@link Contract} + * + * @author Marcin Grzejszczak + * + * @since 1.0.0 + */ +@CompileStatic +class ContractVerifierDslConverter { + + static Contract convert(String dsl) { + return groovyShell().evaluate(dsl) as Contract + } + + static Contract convert(File dsl) { + return groovyShell().evaluate(dsl) as Contract + } + + private static GroovyShell groovyShell() { + return new GroovyShell(ContractVerifierDslConverter.classLoader, new Binding(), new CompilerConfiguration(sourceEncoding: 'UTF-8')) + } +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java similarity index 91% rename from accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java index 0b927452cb..5dd82a7fb1 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/DelegatingJsonVerifiable.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java @@ -1,4 +1,20 @@ -package io.codearte.accurest.util; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util; import java.util.LinkedList; import java.util.regex.Pattern; @@ -8,7 +24,12 @@ import com.toomuchcoding.jsonassert.JsonVerifiable; import static org.apache.commons.lang3.StringEscapeUtils.escapeJava; /** + * Implementation of the {@link MethodBufferingJsonVerifiable} that contains a list + * of String method commands that need to be executed to assert JSONs. + * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ class DelegatingJsonVerifiable implements MethodBufferingJsonVerifiable { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java new file mode 100644 index 0000000000..000d6e75a4 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util; + +import java.util.LinkedList; + +import com.toomuchcoding.jsonassert.JsonVerifiable; + +/** + * Helper class that represents a finished assertion of a JSON. + * Contains a list of all necessary method calls to assert the JSON. + * + * @author Marcin Grzejszczak + * + * @since 1.0.0 + */ +class FinishedDelegatingJsonVerifiable extends DelegatingJsonVerifiable { + + FinishedDelegatingJsonVerifiable(JsonVerifiable delegate, + LinkedList methodsBuffer) { + super(delegate, methodsBuffer); + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy new file mode 100644 index 0000000000..f737a53602 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy @@ -0,0 +1,29 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util + +import groovy.transform.CompileStatic + +/** + * Represents a set of Strings - set of method calls to assert a JSON + * + * @since 1.0.0 + */ +@CompileStatic +class JsonPaths extends HashSet { +} + diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy similarity index 90% rename from accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy index 131dde47e1..f4c35bb866 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/JsonToJsonPathsConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy @@ -1,10 +1,26 @@ -package io.codearte.accurest.util +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util import com.toomuchcoding.jsonassert.JsonAssertion import groovy.json.JsonOutput import groovy.json.JsonSlurper -import io.codearte.accurest.dsl.internal.ExecutionProperty -import io.codearte.accurest.dsl.internal.OptionalProperty +import org.springframework.cloud.contract.verifier.dsl.internal.OptionalProperty +import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty import java.util.regex.Pattern @@ -21,7 +37,7 @@ class JsonToJsonPathsConverter { * In case of issues with size assertion just provide this property as system property * equal to "false" and then size assertion will be disabled */ - private static final String SIZE_ASSERTION_SYSTEM_PROP = "accurest.assert.size" + private static final String SIZE_ASSERTION_SYSTEM_PROP = "spring.cloud.contract.verifier.assert.size" private static final Boolean SERVER_SIDE = false private static final Boolean CLIENT_SIDE = true diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy similarity index 59% rename from accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy index 4f21f880ff..ed83f76a3d 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MapConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy @@ -1,22 +1,54 @@ -package io.codearte.accurest.util +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util import groovy.json.JsonSlurper -import io.codearte.accurest.dsl.internal.DslProperty +import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty /** + * Converts an object into either client or server side representation. + * Iterates over the structure of an object (depending on whether it's an + * iterable or a primitive type etc.), converts the {@link DslProperty} into their + * client / server representation and returns the result + * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ class MapConverter { public static final boolean STUB_SIDE = true public static final boolean TEST_SIDE = false + /** + * Returns the object with client side values of {@link org.springframework.cloud.contract.verifier.dsl.internal.DslProperty} + */ static def transformToClientValues(def value) { return transformValues(value) { it instanceof DslProperty ? it.clientValue : it } } + /** + * Iterates over the structure of the object and executes the closure + * on each element of that structure. + * + * Returns the transformed structure + */ static def transformValues(def value, Closure closure) { if (value instanceof String && value) { try { @@ -35,6 +67,10 @@ class MapConverter { return transformValue(closure, value) } + /** + * Transforms a value with the given closure. Needs to be protected, otherwise + * method access exception will occur at runtime. + */ protected static Object transformValue(Closure closure, Object value) { return extractValue(value, { Object val-> Object newValue = closure(val) @@ -60,6 +96,10 @@ class MapConverter { } } + /** + * If {@code clientSide} is {@code true} returns the client side value for the + * provided object + */ static Object getClientOrServerSideValues(json, boolean clientSide) { return transformValues(json) { if (it instanceof DslProperty) { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java new file mode 100644 index 0000000000..12774b14bb --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util; + +/** + * Contract for classes that buffer method executions + * + * @author Marcin Grzejszczak + * + * @since 1.0.0 + */ +public interface MethodBuffering { + + String method(); +} diff --git a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java similarity index 56% rename from accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java index df22b85bc8..746bf3a9a9 100644 --- a/accurest-core/src/main/groovy/io/codearte/accurest/util/MethodBufferingJsonVerifiable.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java @@ -1,9 +1,30 @@ -package io.codearte.accurest.util; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util; import com.toomuchcoding.jsonassert.JsonVerifiable; /** + * A wrapper over {@link JsonVerifiable} that allows to store the method + * name in order to print it out in the generated test + * * @author Marcin Grzejszczak + * + * @since 1.0.0 */ public interface MethodBufferingJsonVerifiable extends JsonVerifiable, MethodBuffering { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy new file mode 100644 index 0000000000..6957ed3d8d --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy @@ -0,0 +1,111 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util + +/** + * A utility class that helps to convert names + * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 + */ +class NamesUtil { + + /** + * Returns the first element before the last separator presence. + * Returns empty string if separator is not found. + */ + static String beforeLast(String string, String separator) { + if (string?.indexOf(separator) > -1) { + return string.substring(0, string.lastIndexOf(separator)) + } + return '' + } + + /** + * Returns the first element after the last separator presence + * Returns the provided string if separator is not found. + */ + static String afterLast(String string, String separator) { + if (string?.indexOf(separator) > -1) { + return string.substring(string.lastIndexOf(separator) + 1) + } + return string + } + + /** + * Returns the first element after the last dot presence + * Returns the provided string if separator is not found. + */ + static String afterLastDot(String string) { + return afterLast(string, '.') + } + + /** + * Converts a string into a camel case format + */ + static String camelCase(String className) { + if (!className) { + return className + } + String firstChar = className.charAt(0).toLowerCase() as String + return firstChar + className.substring(1) + } + + /** + * Capitalizes the provided string + */ + static String capitalize(String className) { + if (!className) { + return className + } + String firstChar = className.charAt(0).toUpperCase() as String + return firstChar + className.substring(1) + } + + /** + * Returns the whole string to the last present dot. + * Returns input string if there is no dot + */ + static String toLastDot(String string) { + if (string?.indexOf('.') > -1) { + return string.substring(0, string.lastIndexOf('.')) + } + return string + } + + /** + * Converts the Java package notation to a path format + */ + static String packageToDirectory(String packageName) { + return packageName.replace('.' as char, File.separatorChar) + } + + /** + * Converts the path format to a Java package notation + */ + static String directoryToPackage(String directory) { + return directory.replace(File.separator, '.') + } + + /** + * Converts illegal package characters to underscores + */ + static String convertIllegalPackageChars(String packageName) { + return packageName.replace('-', '_') + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy new file mode 100644 index 0000000000..cb284679a5 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy @@ -0,0 +1,155 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util + +import groovy.transform.TypeChecked +import org.codehaus.groovy.runtime.GStringImpl +import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty + +import java.util.regex.Pattern + +import static ContentUtils.extractValue +import static org.apache.commons.lang3.StringEscapeUtils.escapeJson + +/** + * Useful utility methods to work with regular expresisons + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @since 1.0.0 + */ +@TypeChecked +class RegexpBuilders { + + /** + * Converts the {@link GString} passed values into their stub side String representations + */ + static String buildGStringRegexpForStubSide(GString gString) { + new GStringImpl( + gString.values.collect(this.&buildGStringRegexpForStubSide) as Object[], + gString.strings.collect(this.&escapeSpecialRegexChars) as String[] + ) + } + + /** + * Converts the {@link Pattern} passed values into their stub side String representations + */ + static String buildGStringRegexpForStubSide(Pattern pattern) { + return pattern.pattern() + } + + /** + * Converts the {@link org.springframework.cloud.contract.verifier.dsl.internal.DslProperty} passed values into their stub side String representations + */ + static String buildGStringRegexpForStubSide(DslProperty dslProperty) { + return buildGStringRegexpForStubSide(dslProperty.clientValue) + } + + /** + * Converts the {@link Object} passed values into their stub side String representations + */ + static String buildGStringRegexpForStubSide(Object o) { + return escapeSpecialRegexChars(o.toString()) + } + + /** + * Converts the {@link GString} passed values into their test side String representations + */ + static String buildGStringRegexpForTestSide(GString gString) { + new GStringImpl( + gString.values.collect(this.&buildGStringRegexpForTestSide) as Object[], + gString.strings.collect(this.&escapeSpecialRegexChars) as String[] + ) + } + + /** + * Converts the {@link Pattern} passed values into their test side String representations + */ + static String buildGStringRegexpForTestSide(Pattern pattern) { + return pattern.pattern() + } + + /** + * Converts the {@link DslProperty} passed values into their test side String representations + */ + static String buildGStringRegexpForTestSide(DslProperty dslProperty) { + return buildGStringRegexpForTestSide(dslProperty.clientValue) + } + + /** + * Converts the {@link Object} passed values into their test side String representations + */ + static String buildGStringRegexpForTestSide(Object o) { + return o.toString().replaceAll('\\\\', '\\\\\\\\') + } + + private final static Pattern SPECIAL_REGEX_CHARS = Pattern.compile('[{}()\\[\\].+*?^$\\\\|]') + + private static String escapeSpecialRegexChars(String str) { + return SPECIAL_REGEX_CHARS.matcher(str).replaceAll('\\\\\\\\$0') + } + + private final static String WS = /\s*/ + + static String buildJSONRegexpMatch(GString gString) { + return buildJSONRegexpMatch(extractValue(gString, ContentType.JSON, { DslProperty dslProperty -> dslProperty.clientValue })) + } + + static String buildJSONRegexpMatch(Map jsonMap) { + return WS + "\\{" + jsonMap.collect(this.&buildJSONRegexpMatch).join(",") + "\\}" + WS + } + + static String buildJSONRegexpMatch(List jsonList) { + return WS + "\\[" + jsonList.collect(this.&buildJSONRegexpMatch).join(",") + "\\]" + WS + } + + /** + * Converts the map into String representation of regular expressions + */ + static String buildJSONRegexpMatch(Map.Entry entry) { + return buildJSONRegexpMatchString(escapeJson(entry.key)) + ":" + buildJSONRegexpMatch(entry.value) + } + + /** + * Converts the object into String representation of regular expressions + */ + static String buildJSONRegexpMatch(Object value) { + return buildJSONRegexpMatchStringOptionalQuotes(escapeJson(value.toString())) + } + + /** + * Converts the pattern into String representation of regular expressions + */ + static String buildJSONRegexpMatch(Pattern pattern) { + return buildJSONRegexpMatchStringOptionalQuotes(pattern.pattern()) + } + + /** + * Converts the String into String representation of regular expressions + */ + static String buildJSONRegexpMatchString(String value) { + return WS + '"' + value + '"' + WS + } + + /** + * Converts the String into an optional String representation of regular expressions + */ + static String buildJSONRegexpMatchStringOptionalQuotes(String value) { + return WS + '"?' + value + '"?' + WS + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java new file mode 100644 index 0000000000..2fad0fcd6a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java @@ -0,0 +1,33 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util; + +/** + * Utility class that wraps an object that should be traversed + * when building a list of methods to execute in the generated test. + * + * @author Marcin Grzejszczak + * + * @since 1.0.0 + */ +class ShouldTraverse { + final Object value; + + ShouldTraverse(Object value) { + this.value = value; + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ValidateUtils.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ValidateUtils.groovy new file mode 100644 index 0000000000..98aebb1ca8 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ValidateUtils.groovy @@ -0,0 +1,69 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util + +import groovy.transform.TypeChecked +import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy + +import java.util.regex.Pattern + +import static org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy.Type.ABSENT +import static org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy.Type.EQUAL_TO + +/** + * Checks the validity of DSL entries. + * + * Do not change to {@code @CompileStatic} since it's using double dispatch. + * + * @since 1.0.0 + */ +@TypeChecked +class ValidateUtils { + + static Object validateServerValueIsAvailable(Object value) { + validateServerValueIsAvailable(value, "Server value") + return value + } + + static Object validateServerValueIsAvailable(Object value, String msg) { + validateServerValue(value, msg) + return value + } + + static void validateServerValue(Pattern pattern, String msg) { + throw new IllegalStateException("$msg can't be a pattern for the server side") + } + + static List ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE = [EQUAL_TO, ABSENT] + + static void validateServerValue(MatchingStrategy matchingStrategy, String msg) { + if (!ALLOWED_MATCHING_TYPES_ON_SERVER_SIDE.contains(matchingStrategy.type)) { + throw new IllegalStateException("$msg can't be of a matching type: $matchingStrategy.type for the server side") + } + validateServerValue(matchingStrategy.serverValue, msg) + } + + static void validateServerValue(DslProperty value, String msg) { + validateServerValue(value.serverValue, msg) + } + + static void validateServerValue(Object value, String msg) { + // OK + } + +} diff --git a/accurest-core/src/main/resources/stubs/wiremocks/other/sample.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/other/sample.json similarity index 100% rename from accurest-core/src/main/resources/stubs/wiremocks/other/sample.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/other/sample.json diff --git a/accurest-core/src/main/resources/stubs/wiremocks/sample.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/sample.json similarity index 100% rename from accurest-core/src/main/resources/stubs/wiremocks/sample.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/sample.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy new file mode 100644 index 0000000000..85f8c84fd4 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier + +import org.springframework.cloud.contract.verifier.builder.SingleTestGenerator +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.config.TestFramework +import spock.lang.Specification + +class GeneratorScannerSpec extends Specification { + + private SingleTestGenerator classGenerator = Mock(SingleTestGenerator) + + def "should find all .json files and generate 6 classes for them"() { + given: + File resource = new File(this.getClass().getResource("/directory/with/stubs/stubsRepositoryIndicator").toURI()) + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties() + properties.contractsDslDir = resource.parentFile + TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) + when: + testGenerator.generateTestClasses("org.springframework.cloud.contract.verifier") + then: + 6 * classGenerator.buildClass(_, _, _) >> "qwerty" + } + + def "should create class with full package"() { + given: + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(targetFramework: TestFramework.SPOCK) + properties.contractsDslDir = new File(this.getClass().getResource("/directory/with/stubs/package").toURI()) + TestGenerator testGenerator = new TestGenerator(properties, classGenerator, Stub(FileSaver)) + when: + testGenerator.generateTestClasses("org.springframework.cloud.contract.verifier") + then: + 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier') >> "spec" + 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier.v1') >> "spec1" + 1 * classGenerator.buildClass(_, 'exceptionsSpec', 'org.springframework.cloud.contract.verifier.v2') >> "spec2" + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy new file mode 100644 index 0000000000..261416ca7e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier + +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.config.TestFramework +import org.springframework.cloud.contract.verifier.config.TestMode + +class MainTest { + public static void main(String[] args) { + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties( + contractsDslDir: new File('/some/path/dsl'), + generatedTestSourcesDir: new File('/tmp/contracts'), + targetFramework: TestFramework.SPOCK, testMode: TestMode.MOCKMVC, basePackageForTests: 'io.test', + staticImports: ['com.package.Test.*'], imports: ['org.package.Test'], excludedFiles: ["**/other"]) + println new TestGenerator(properties).generate() + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy new file mode 100644 index 0000000000..c47554348a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 + } +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy similarity index 83% rename from accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy index d8610d92a9..462c623cc4 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/ContractHttpDocsSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy @@ -1,6 +1,22 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.dsl.GroovyDsl +package org.springframework.cloud.contract.verifier.builder + +import org.springframework.cloud.contract.verifier.dsl.Contract import spock.lang.Specification /** * Tests used for the documentation @@ -9,9 +25,9 @@ import spock.lang.Specification */ class ContractHttpDocsSpec extends Specification { - GroovyDsl httpDsl = + Contract httpDsl = // tag::http_dsl[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { // Definition of HTTP request part of the contract // (this can be a valid request or invalid depending // on type of contract being specified). @@ -33,9 +49,9 @@ class ContractHttpDocsSpec extends Specification { } // end::http_dsl[] - GroovyDsl request = + Contract request = // tag::request[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { // HTTP request method (GET/POST/PUT/DELETE). method 'GET' @@ -50,9 +66,9 @@ class ContractHttpDocsSpec extends Specification { } // end::request[] - GroovyDsl url = + Contract url = // tag::url[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { method 'GET' @@ -66,9 +82,9 @@ class ContractHttpDocsSpec extends Specification { } // end::url[] - GroovyDsl urlPaths = + Contract urlPaths = // tag::urlpath[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { //... @@ -111,9 +127,9 @@ class ContractHttpDocsSpec extends Specification { } // end::urlpath[] - GroovyDsl headers = + Contract headers = // tag::headers[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { //... @@ -131,9 +147,9 @@ class ContractHttpDocsSpec extends Specification { } // end::headers[] - GroovyDsl body = + Contract body = // tag::body[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { //... @@ -148,9 +164,9 @@ class ContractHttpDocsSpec extends Specification { } // end::body[] - GroovyDsl bodyAsXml = + Contract bodyAsXml = // tag::bodyAsXml[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { //... @@ -166,9 +182,9 @@ class ContractHttpDocsSpec extends Specification { } // end::bodyAsXml[] - GroovyDsl response = + Contract response = // tag::response[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { //... } @@ -180,9 +196,9 @@ class ContractHttpDocsSpec extends Specification { } // end::response[] - GroovyDsl regex = + Contract regex = // tag::regex[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -211,9 +227,9 @@ class ContractHttpDocsSpec extends Specification { } // end::regex[] - GroovyDsl optionals = + Contract optionals = // tag::optionals[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { priority 1 request { method 'POST' @@ -266,9 +282,9 @@ class ContractHttpDocsSpec extends Specification { stripped(blockBuilder.toString()) == stripped(expectedTest) } - GroovyDsl method = + Contract method = // tag::method[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { method 'PUT' url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy similarity index 64% rename from accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy index 38a6a8b442..cf419bd745 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/JaxRsClientMethodBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy @@ -1,9 +1,24 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.dsl.WireMockStubStrategy -import io.codearte.accurest.dsl.WireMockStubVerifier -import io.codearte.accurest.file.Contract +package org.springframework.cloud.contract.verifier.builder + +import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier +import org.springframework.cloud.contract.verifier.file.ContractMetadata +import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy import spock.lang.Issue import spock.lang.Specification @@ -11,7 +26,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub def "should generate assertions for simple response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -35,14 +50,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#187") def "should generate assertions for null and boolean values with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -65,17 +80,17 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property2").isNull()""") blockBuilder.toString().contains("""assertThatJson(parsedJson).field("property1").isEqualTo("true")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub()) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#79") def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -101,17 +116,17 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").hasSize(2)""") blockBuilder.toString().contains("""assertThatJson(parsedJson).array("property2").contains("b").isEqualTo("sthElse")""") and: - stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub()) + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub()) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#82") def "should generate proper request when body constructed from map with a list with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -132,15 +147,15 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - 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")' + methodBuilderName | methodBuilder | bodyString + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('{\"items\":[\"HOP\"]}', 'application/json')""" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("{\\"items\\":[\\"HOP\\"]}", "application/json")' } @Issue("#88") def "should generate proper request when body constructed from GString with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -161,14 +176,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - 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")' + methodBuilderName | methodBuilder | bodyString + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('property1=VAL1', 'application/octet-stream')""" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"property1=VAL1\\"", "application/octet-stream")' } def "should generate assertions for array in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -195,13 +210,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for array inside response body element with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -227,13 +242,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for nested objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -259,13 +274,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should generate regex assertions for map objects in response body with #methodBodyName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -297,13 +312,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should generate regex assertions for string objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -329,13 +344,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should ignore 'Accept' header and use 'request' method with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -356,14 +371,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | requestString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "request('text/plain')" - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")' + methodBuilderName | methodBuilder | requestString + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "request('text/plain')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")' } def "should ignore 'Content-Type' header and use 'entity' method with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "GET" url "test" @@ -389,14 +404,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - 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")'] + methodBuilderName | methodBuilder | requestStrings + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ["""entity('', 'text/plain')""", """header('Timer', '123')"""] + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")'] } def "should generate a call with an url path and query parameters with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath('/users') { @@ -443,15 +458,15 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | modifyStringIfRequired - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } + methodBuilderName | methodBuilder | modifyStringIfRequired + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } } @Issue('#169') def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { @@ -498,14 +513,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | modifyStringIfRequired - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } + methodBuilderName | methodBuilder | modifyStringIfRequired + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } } def "should generate test for empty body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('POST') url("/ws/payments") @@ -526,14 +541,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | bodyString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "entity('', 'application/octet-stream')" - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"\\"", "application/octet-stream"' + methodBuilderName | methodBuilder | bodyString + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "entity('', 'application/octet-stream')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"\\"", "application/octet-stream"' } def "should generate test for String in response body with #methodBodyName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "POST" url "test" @@ -554,15 +569,15 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - 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");' + methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "String responseAsString = response.readEntity(String)" | 'responseBody == "test"' + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (responseAsString);' | 'assertThat(responseBody).isEqualTo("test");' } @Issue('#171') def "should generate test with uppercase method name with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "get" url "/v1/some_cool_requests/e86df6f693de4b35ae648464c5b0dc08" @@ -587,14 +602,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | methodString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ".method('GET')" - "JaxRsClientJUnitMethodBodyBuilder" | { GroovyDsl dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")' + methodBuilderName | methodBuilder | methodString + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ".method('GET')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")' } def "should generate a call with an url path and query parameters with JUnit - we'll put it into docs"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath('/users') { diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy similarity index 71% rename from accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy index 22dba316f2..98e02596de 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy @@ -1,7 +1,22 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.dsl.Accurest -import io.codearte.accurest.dsl.GroovyDsl +package org.springframework.cloud.contract.verifier.builder + +import org.springframework.cloud.contract.verifier.dsl.Contract import spock.lang.Specification /** * @author Marcin Grzejszczak @@ -11,7 +26,7 @@ class MessagingMethodBodyBuilderSpec extends Specification { def "should work for triggered based messaging with Spock"() { given: // tag::trigger_method_dsl[] -def contractDsl = GroovyDsl.make { +def contractDsl = Contract.make { label 'some_label' input { triggeredBy('bookReturnedTriggered()') @@ -38,11 +53,11 @@ def contractDsl = GroovyDsl.make { bookReturnedTriggered() then: - def response = accurestMessaging.receiveMessage('activemq:output') + def response = contractVerifierMessaging.receiveMessage('activemq:output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") ''' @@ -52,7 +67,7 @@ def contractDsl = GroovyDsl.make { def "should work for triggered based messaging with JUnit"() { given: - def contractDsl = GroovyDsl.make { + def contractDsl = Contract.make { label 'some_label' input { triggeredBy('bookReturnedTriggered()') @@ -78,11 +93,11 @@ def contractDsl = GroovyDsl.make { bookReturnedTriggered(); // then: - AccurestMessage response = accurestMessaging.receiveMessage("activemq:output"); + ContractVerifierMessage response = contractVerifierMessaging.receiveMessage("activemq:output"); assertThat(response).isNotNull(); assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo"); // and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload())); assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); ''' // end::trigger_method_junit_test[] @@ -92,7 +107,7 @@ def contractDsl = GroovyDsl.make { def "should generate tests triggered by a message for Spock"() { given: // tag::trigger_message_dsl[] -def contractDsl = GroovyDsl.make { +def contractDsl = Contract.make { label 'some_label' input { messageFrom('jms:input') @@ -124,20 +139,20 @@ def contractDsl = GroovyDsl.make { // tag::trigger_message_spock[] """\ given: - def inputMessage = accurestMessaging.create( + def inputMessage = contractVerifierMessaging.create( '''{"bookName":"foo"}''', ['sample': 'header'] ) when: - accurestMessaging.send(inputMessage, 'jms:input') + contractVerifierMessaging.send(inputMessage, 'jms:input') then: - def response = accurestMessaging.receiveMessage('jms:output') + def response = contractVerifierMessaging.receiveMessage('jms:output') assert response !- null response.getHeader('BOOK-NAME') == 'foo' and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") """ // end::trigger_message_spock[] @@ -146,7 +161,7 @@ and: def "should generate tests triggered by a message for JUnit"() { given: - def contractDsl = GroovyDsl.make { + def contractDsl = Contract.make { label 'some_label' input { messageFrom('jms:input') @@ -177,20 +192,20 @@ and: // tag::trigger_message_junit[] ''' // given: - AccurestMessage inputMessage = accurestMessaging.create( + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( "{\\"bookName\\":\\"foo\\"}" , headers() .header("sample", "header")); // when: - accurestMessaging.send(inputMessage, "jms:input"); + contractVerifierMessaging.send(inputMessage, "jms:input"); // then: - AccurestMessage response = accurestMessaging.receiveMessage("jms:output"); + ContractVerifierMessage response = contractVerifierMessaging.receiveMessage("jms:output"); assertThat(response).isNotNull(); assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo"); // and: - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload())); assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); ''' // end::trigger_message_junit[] @@ -200,7 +215,7 @@ and: def "should generate tests without destination, triggered by a message"() { given: // tag::trigger_no_output_dsl[] -def contractDsl = GroovyDsl.make { +def contractDsl = Contract.make { label 'some_label' input { messageFrom('jms:delete') @@ -224,13 +239,13 @@ def contractDsl = GroovyDsl.make { // tag::trigger_no_output_spock[] ''' given: - def inputMessage = accurestMessaging.create( + def inputMessage = contractVerifierMessaging.create( \'\'\'{"bookName":"foo"}\'\'\', ['sample': 'header'] ) when: - accurestMessaging.send(inputMessage, 'jms:delete') + contractVerifierMessaging.send(inputMessage, 'jms:delete') then: noExceptionThrown() @@ -242,7 +257,7 @@ then: def "should generate tests without destination, triggered by a message for JUnit"() { given: - def contractDsl = GroovyDsl.make { + def contractDsl = Contract.make { label 'some_label' input { messageFrom('jms:delete') @@ -265,13 +280,13 @@ then: // tag::trigger_no_output_junit[] ''' // given: - AccurestMessage inputMessage = accurestMessaging.create( + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( "{\\"bookName\\":\\"foo\\"}" , headers() .header("sample", "header")); // when: - accurestMessaging.send(inputMessage, "jms:delete"); + contractVerifierMessaging.send(inputMessage, "jms:delete"); // then: bookWasDeleted(); @@ -282,7 +297,7 @@ then: def "should generate tests without headers for JUnit"() { given: - def contractDsl = GroovyDsl.make { + def contractDsl = Contract.make { label 'some_label' input { messageFrom('jms:input') @@ -309,18 +324,18 @@ then: String expectedMsg = ''' // given: - AccurestMessage inputMessage = accurestMessaging.create( + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( "{\\"bookName\\":\\"foo\\"}" , headers() .header("sample", "header")); // when: - accurestMessaging.send(inputMessage, "jms:input"); + contractVerifierMessaging.send(inputMessage, "jms:input"); // then: - AccurestMessage response = accurestMessaging.receiveMessage("jms:output"); + ContractVerifierMessage response = contractVerifierMessaging.receiveMessage("jms:output"); assertThat(response).isNotNull(); - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload())); assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); ''' stripped(test) == stripped(expectedMsg) @@ -328,7 +343,7 @@ then: def "should generate tests without headers for Spock"() { given: - def contractDsl = GroovyDsl.make { + def contractDsl = Contract.make { label 'some_label' input { messageFrom('jms:input') @@ -355,18 +370,18 @@ then: String expectedMsg = """ given: - def inputMessage = accurestMessaging.create('''{"bookName":"foo"}''' + def inputMessage = contractVerifierMessaging.create('''{"bookName":"foo"}''' ,[ 'sample': 'header' ]) when: - accurestMessaging.send(inputMessage, 'jms:input') + contractVerifierMessaging.send(inputMessage, 'jms:input') then: - def response = accurestMessaging.receiveMessage('jms:output') + def response = contractVerifierMessaging.receiveMessage('jms:output') assert response != null - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload)) + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") """ stripped(test) == stripped(expectedMsg) @@ -380,7 +395,7 @@ then: given: def contractDsl = // tag::consumer_producer[] -Accurest.make { +Contract.make { label 'some_label' input { messageFrom value(consumer('jms:output'), producer('jms:input')) @@ -408,18 +423,18 @@ Accurest.make { String expectedMsg = ''' // given: - AccurestMessage inputMessage = accurestMessaging.create( + ContractVerifierMessage inputMessage = contractVerifierMessaging.create( "{\\"bookName\\":\\"foo\\"}" , headers() .header("sample", "header")); // when: - accurestMessaging.send(inputMessage, "jms:input"); + contractVerifierMessaging.send(inputMessage, "jms:input"); // then: - AccurestMessage response = accurestMessaging.receiveMessage("jms:output"); + ContractVerifierMessage response = contractVerifierMessaging.receiveMessage("jms:output"); assertThat(response).isNotNull(); - DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload())); + DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.getPayload())); assertThatJson(parsedJson).field("bookName").isEqualTo("foo"); ''' stripped(test) == stripped(expectedMsg) diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy similarity index 76% rename from accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy index 538125006e..3b2e77c4b5 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1,20 +1,35 @@ -package io.codearte.accurest.builder +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.dsl.Accurest -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.dsl.WireMockStubVerifier +package org.springframework.cloud.contract.verifier.builder + +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Shared import spock.lang.Specification import java.util.regex.Pattern /** - * @author Jakub Kubrynski + * @author Jakub Kubrynski, codearte.io */ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStubVerifier { @Shared - GroovyDsl dslWithOptionalsInString = Accurest.make { + Contract dslWithOptionalsInString = Contract.make { priority 1 request { method 'POST' @@ -40,7 +55,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } @Shared - GroovyDsl dslWithOptionals = GroovyDsl.make { + Contract dslWithOptionals = Contract.make { priority 1 request { method 'POST' @@ -79,7 +94,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub def "should generate assertions for simple response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -103,14 +118,14 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#187") def "should generate assertions for null and boolean values with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -136,14 +151,14 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#79") def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -172,14 +187,14 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue("#82") def "should generate proper request when body constructed from map with a list #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -200,15 +215,15 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """.body('''{\"items\":[\"HOP\"]}''')""" - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("{\\"items\\":[\\"HOP\\"]}")' + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """.body('''{\"items\":[\"HOP\"]}''')""" + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("{\\"items\\":[\\"HOP\\"]}")' } @Issue("#88") def "should generate proper request when body constructed from GString with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -229,15 +244,15 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """.body('''property1=VAL1''')""" - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("\\"property1=VAL1\\"")' + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """.body('''property1=VAL1''')""" + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("\\"property1=VAL1\\"")' } @Issue("185") def "should generate assertions for a response body containing map with integers as keys with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -263,13 +278,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for array in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -296,13 +311,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for array inside response body element with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -328,13 +343,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for nested objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -360,13 +375,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate regex assertions for map objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -396,13 +411,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate regex assertions for string objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -428,14 +443,14 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue(["#126", "#143"]) def "should generate escaped regex assertions for string objects in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" url "test" @@ -460,13 +475,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate a call with an url path and query parameters with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'GET' urlPath('/users') { @@ -507,14 +522,14 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('#169') def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'GET' url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { @@ -555,13 +570,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should generate test for empty body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method('POST') url("/ws/payments") @@ -581,14 +596,14 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ".body('''''')" - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")" + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ".body('''''')" + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")" } def "should generate test for String in response body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "POST" url "test" @@ -609,15 +624,15 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - 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");' + methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (response.getBody().asString());' | 'assertThat(responseBody).isEqualTo("test");' } @Issue('113') def "should generate regex test for String in response header with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'POST' url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) @@ -648,15 +663,15 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - 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]+");' + methodBuilderName | methodBuilder | headerEvaluationString + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' } @Issue('115') def "should generate regex with helper method with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'POST' url $(client(regex('/partners/[0-9]+/users')), server('/partners/1000/users')) @@ -687,14 +702,14 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub and: stubMappingIsValidWireMockStub(contractDsl) where: - 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]+");' + methodBuilderName | methodBuilder | headerEvaluationString + "MockMvcSpockMethodBuilder" | { Contract 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" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");' } def "should work with more complex stuff and jsonpaths with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { priority 10 request { method 'POST' @@ -729,13 +744,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should work properly with GString url with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'PUT' @@ -762,13 +777,13 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } def "should resolve properties in GString with regular expression with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { priority 1 request { method 'POST' @@ -801,8 +816,8 @@ 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 MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('42') @@ -844,7 +859,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub @Issue('72') def "should make the execute method work with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method """PUT""" url """/fraudcheck""" @@ -889,9 +904,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub assert test.contains(assertionString) } where: - 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"))'''] + methodBuilderName | methodBuilder | assertionStrings + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''', '''assertThatLocationIsNull(response.header('Location'))'''] + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] } def "should support inner map and list definitions with #methodBuilderName"() { @@ -902,7 +917,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub Pattern NUMBERS = Pattern.compile(/[\d\.]*/) Pattern DATETIME = ANYSTRING - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "PUT" url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/client_data" @@ -956,9 +971,9 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub !test.contains("clientValue") !test.contains("cursor") where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '"street":"Light Street"' - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"street\\":\\"Light Street\\"' + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '"street":"Light Street"' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"street\\":\\"Light Street\\"' } @@ -966,7 +981,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub given: Pattern ONLY_ALPHA_UNICODE = Pattern.compile(/[\p{L}]*/) - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "PUT" url "/v1/payments/e86df6f693de4b35ae648464c5b0dc09/енев" @@ -996,14 +1011,14 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub !test.contains("\\u041f") where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('177') def "should generate proper test code when having multiline body with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "PUT" url "/multiline" @@ -1022,16 +1037,16 @@ World.''') then: test.contains(bodyString) where: - methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """'''hello, + methodBuilderName | methodBuilder | bodyString + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """'''hello, World.'''""" - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"hello,\\nWorld.\\"' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"hello,\\nWorld.\\"' } @Issue('180') def "should generate proper test code when having multipart parameters with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "PUT" url "/multipart" @@ -1058,21 +1073,21 @@ World.'''""" test.contains(requestString) } where: - 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());'] + methodBuilderName | methodBuilder | requestStrings + "MockMvcSpockMethodBuilder" | { Contract 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" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['"content-type", "multipart/form-data;boundary=AaB03x"', + '.param("formParameter", "\\"formParameterValue\\"")', + '.param("someBooleanParameter", "true")', + '.multiPart("file", "filename.csv", "file content".getBytes());'] } @Issue('180') def "should generate proper test code when having multipart parameters with named as map with #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "PUT" url "/multipart" @@ -1097,14 +1112,14 @@ World.'''""" test.contains('.multiPart') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('#216') def "should parse JSON with arrays using Spock"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" urlPath('/auth/oauth/check_token') { @@ -1138,7 +1153,7 @@ World.'''""" @Issue('#216') def "should parse JSON with arrays using JUnit"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method "GET" urlPath('/auth/oauth/check_token') { @@ -1171,7 +1186,7 @@ World.'''""" def "should work with execution property"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'PUT' url '/fraudcheck' @@ -1195,14 +1210,14 @@ World.'''""" test.contains('''assertThatRejectionReasonIsNull(''') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('262') def "should generate proper test code with map inside list"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'GET' urlPath '/foos' @@ -1233,7 +1248,7 @@ World.'''""" @Issue('266') def "should generate proper test code with top level array using #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'GET' urlPath '/api/tags' @@ -1260,14 +1275,14 @@ World.'''""" test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('266') def "should generate proper test code with top level array or arrays using #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'GET' urlPath '/api/categories' @@ -1293,14 +1308,14 @@ World.'''""" test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Boot").value()') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('47') def "should generate async body when async flag set in response"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'GET' url '/test' @@ -1320,14 +1335,14 @@ World.'''""" and: stubMappingIsValidWireMockStub(contractDsl) where: - methodBuilderName | methodBuilder | bodyDefinitionString - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '.when().async()' - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.when().async()' + methodBuilderName | methodBuilder | bodyDefinitionString + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '.when().async()' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.when().async()' } def "should generate proper test code with array of primitives using #methodBuilderName"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'GET' urlPath '/api/tags' @@ -1354,14 +1369,14 @@ World.'''""" test.contains('assertThatJson(parsedJson).array("partners").array("payment_methods").arrayField().isEqualTo("CASH").value()') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { GroovyDsl dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { GroovyDsl dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } } @Issue('#273') def "should not escape dollar in Spock regex tests"() { given: - GroovyDsl contractDsl = GroovyDsl.make { + Contract contractDsl = Contract.make { request { method 'GET' urlPath '/get' @@ -1381,14 +1396,14 @@ World.'''""" } - GroovyDsl dslForDocs = + Contract dslForDocs = // tag::dsl_example[] - io.codearte.accurest.dsl.GroovyDsl.make { + Contract.make { request { method 'PUT' url '/api/12' headers { - header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json' + header 'Content-Type': 'application/vnd.org.springframework.cloud.contract.verifier.twitter-places-analyzer.v1+json' } body '''\ [{ diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy similarity index 67% rename from accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy index 6fbcac3f45..d4b3bb3485 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/SingleTestGeneratorSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy @@ -1,14 +1,30 @@ -package io.codearte.accurest +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.builder -import io.codearte.accurest.config.AccurestConfigProperties -import io.codearte.accurest.config.TestMode -import io.codearte.accurest.file.Contract import org.junit.Rule import org.junit.rules.TemporaryFolder +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.config.TestMode +import org.springframework.cloud.contract.verifier.file.ContractMetadata import spock.lang.Specification -import static io.codearte.accurest.config.TestFramework.JUNIT -import static io.codearte.accurest.config.TestFramework.SPOCK +import static org.springframework.cloud.contract.verifier.config.TestFramework.JUNIT +import static org.springframework.cloud.contract.verifier.config.TestFramework.SPOCK class SingleTestGeneratorSpec extends Specification { @@ -30,7 +46,7 @@ class SingleTestGeneratorSpec extends Specification { def setup() { file = tmpFolder.newFile() file.write(""" - io.codearte.accurest.dsl.GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'PUT' url 'url' @@ -44,9 +60,9 @@ class SingleTestGeneratorSpec extends Specification { def "should build MockMvc test class for #testFramework"() { given: - AccurestConfigProperties properties = new AccurestConfigProperties(); + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(); properties.targetFramework = testFramework - Contract contract = new Contract(file.toPath(), true, 1, 2) + ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2) contract.ignored >> true contract.order >> 2 SingleTestGenerator testGenerator = new SingleTestGenerator(properties) @@ -65,10 +81,10 @@ class SingleTestGeneratorSpec extends Specification { def "should build JaxRs test class for #testFramework"() { given: - AccurestConfigProperties properties = new AccurestConfigProperties(); + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(); properties.testMode = TestMode.JAXRSCLIENT properties.targetFramework = testFramework - Contract contract = new Contract(file.toPath(), true, 1, 2) + ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2) contract.ignored >> true contract.order >> 2 SingleTestGenerator testGenerator = new SingleTestGenerator(properties) @@ -89,7 +105,7 @@ class SingleTestGeneratorSpec extends Specification { given: File secondFile = tmpFolder.newFile() secondFile.write(""" - io.codearte.accurest.dsl.GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { label 'some_label' input { messageFrom('delete') @@ -104,13 +120,13 @@ class SingleTestGeneratorSpec extends Specification { } """) and: - AccurestConfigProperties properties = new AccurestConfigProperties(); + ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(); properties.targetFramework = testFramework - Contract contract = new Contract(file.toPath(), true, 1, 2) + ContractMetadata contract = new ContractMetadata(file.toPath(), true, 1, 2) contract.ignored >> true contract.order >> 2 and: - Contract contract2 = new Contract(secondFile.toPath(), true, 1, 2) + ContractMetadata contract2 = new ContractMetadata(secondFile.toPath(), true, 1, 2) contract2.ignored >> true contract2.order >> 2 and: @@ -121,7 +137,7 @@ class SingleTestGeneratorSpec extends Specification { then: classStrings.each { clazz.contains(it) } - clazz.contains('@Inject AccurestMessaging') + clazz.contains('@Inject ContractVerifierMessaging') where: testFramework | classStrings diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy similarity index 84% rename from accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy index 2b5157a3f7..458e94ab9e 100755 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/WireMockGroovyDslSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy @@ -1,9 +1,26 @@ -package io.codearte.accurest.dsl +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl import groovy.json.JsonBuilder import groovy.json.JsonSlurper -import io.codearte.accurest.file.Contract -import io.codearte.accurest.util.AssertionUtil +import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy +import org.springframework.cloud.contract.verifier.file.ContractMetadata +import org.springframework.cloud.contract.verifier.util.AssertionUtil import spock.lang.Issue import spock.lang.Specification @@ -11,7 +28,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub to wireMock stub for the client side'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -36,7 +53,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual(''' { @@ -60,7 +77,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue("#79") def 'should convert groovy dsl stub to wireMock stub for the client side with a body containing a map'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url '/ingredients' @@ -81,7 +98,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual(''' { @@ -107,7 +124,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue("#86") def 'should convert groovy dsl stub with GString and regexp'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('POST') url('/ws/payments') @@ -129,7 +146,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual(''' { @@ -159,7 +176,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with Body as String to wireMock stub for the client side'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -181,7 +198,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -204,7 +221,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with simple Body as String to wireMock stub for the client side'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('GET') url $(client(regex('/[0-9]{2}')), server('/12')) @@ -228,7 +245,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual(''' { @@ -254,7 +271,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToJson when body match is defined as map'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -276,7 +293,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -304,7 +321,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToJson when content type ends with json'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url "/users" @@ -349,7 +366,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToXml when content type ends with xml'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url "/users" @@ -394,7 +411,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToXml when content type is parsable xml'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url "/users" @@ -431,7 +448,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should support xml as a response body'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url "/users" @@ -464,7 +481,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToJson'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url "/users" @@ -499,7 +516,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToXml'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url "/users" @@ -536,7 +553,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with regexp Body as String to wireMock stub for the client side'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('GET') url $(client(regex('/[0-9]{2}')), server('/12')) @@ -560,7 +577,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -586,7 +603,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with a regexp and an integer in request body'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'PUT' url '/fraudcheck' @@ -615,7 +632,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -648,7 +665,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate request with urlPath and queryParameters for client side"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath($(client("users"), server("items"))) { @@ -716,7 +733,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate request with urlPathPattern and queryParameters for client side\ when both contains regular expressions"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath($(client(regex("/users/[0-9]+")), server("/users/1"))) { @@ -755,7 +772,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate request with urlPath for client side"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath $(client("boxes"), server("items")) @@ -784,7 +801,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate simple request with urlPath for client side"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath "boxes" @@ -813,7 +830,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should not allow regexp in url for server value"() { when: - GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url(regex(/users\/[0-9]*/)) { @@ -834,7 +851,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should not allow regexp in query parameter for server value"() { when: - GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url("abc") { @@ -854,7 +871,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should not allow query parameter unresolvable for a server value"() { when: - GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath("users") { @@ -875,7 +892,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should not allow query parameter with a different absent variation for server/client"() { when: - GroovyDsl.make dsl + org.springframework.cloud.contract.verifier.dsl.Contract.make dsl then: def e = thrown(IllegalStateException) e.message.contains "Absent cannot only be used only on one side" @@ -925,7 +942,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate request with url and queryParameters for client side"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' url($(client(regex(/users\/[0-9]*/)), server("users/123"))) { @@ -967,7 +984,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with rich tree Body as String to wireMock stub for the client side'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -1004,7 +1021,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1038,7 +1055,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use regexp matches when request body match is defined using a map with a pattern'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'POST' url '/reissue-payment-order' @@ -1098,7 +1115,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate stub for empty body"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('POST') url("test") @@ -1131,7 +1148,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate stub with priority"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { priority 9 request { method('POST') @@ -1161,7 +1178,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue("#127") def 'should use "test" as an alias for "server"'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('POST') body( @@ -1173,7 +1190,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1195,7 +1212,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue("#121") def 'should generate stub with empty list as a value of a field'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('POST') body( @@ -1207,7 +1224,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1230,7 +1247,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should generate stub properly resolving GString with regular expression'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { priority 1 request { method 'POST' @@ -1255,7 +1272,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1289,7 +1306,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should generate stub properly resolving GString with regular expression in url'() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'PUT' @@ -1306,7 +1323,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1334,7 +1351,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue('42') def 'should generate stub without optional parameters'() { when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub() then: AssertionUtil.assertThatJsonsAreEqual((''' { @@ -1366,7 +1383,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie stubMappingIsValidWireMockStub(wireMockStub) where: contractDsl << [ - GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { priority 1 request { method 'POST' @@ -1390,7 +1407,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie ) } }, - GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { priority 1 request { method 'POST' @@ -1432,13 +1449,13 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } String toWireMockClientJsonStub(groovyDsl) { - new WireMockStubStrategy("Test", new Contract(null, false, 0, null), groovyDsl).toWireMockClientStub() + new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), groovyDsl).toWireMockClientStub() } @Issue('180') def 'should generate stub with multipart parameters'() { given: - GroovyDsl contractDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method "PUT" url "/multipart" @@ -1455,7 +1472,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie } } when: - String wireMockStub = new WireMockStubStrategy("Test", new Contract(null, false, 0, null), contractDsl).toWireMockClientStub() + String wireMockStub = new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub() then: println wireMockStub AssertionUtil.assertThatJsonsAreEqual((''' @@ -1483,7 +1500,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue('#219') def "should generate request with an optional queryParameter for client side"() { given: - GroovyDsl groovyDsl = GroovyDsl.make { + org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' urlPath ('/some/api') { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy new file mode 100644 index 0000000000..f0d7a9d50a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl + +import com.github.tomakehurst.wiremock.stubbing.StubMapping +import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy +import org.springframework.cloud.contract.verifier.file.ContractMetadata + +import java.util.regex.Pattern + +trait WireMockStubVerifier { + + void stubMappingIsValidWireMockStub(String mappingDefinition) { + StubMapping stubMapping = StubMapping.buildFrom(mappingDefinition) + stubMapping.request.bodyPatterns.findAll { it.matches }.every { + Pattern.compile(it.matches) + } + assert !mappingDefinition.contains('org.springframework.cloud.contract.verifier.dsl.internal') + } + + void stubMappingIsValidWireMockStub(org.springframework.cloud.contract.verifier.dsl.Contract contractDsl) { + stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub()) + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy new file mode 100644 index 0000000000..4d3144371e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal + +import spock.lang.Specification + +class ExecutionPropertySpec extends Specification { + + def 'should insert passed value in place of $it placeholder'() { + given: + String commandToExecute = 'commandToExecute($it)' + ExecutionProperty executionProperty = new ExecutionProperty(commandToExecute) + and: + String valueToInsert = 'someObject.itsValue' + when: + String commandWithInsertedValue = executionProperty.insertValue(valueToInsert) + then: + 'commandToExecute(someObject.itsValue)' == commandWithInsertedValue + } + +} diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy similarity index 73% rename from accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy index 3dca400003..4f3b7cdcde 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/dsl/internal/RegexPatternsSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.dsl.internal +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.dsl.internal import spock.lang.Specification diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy similarity index 61% rename from accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy index c699a2a3a1..73e7fc85c0 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/file/ContractFileScannerSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.file +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.file import com.google.common.collect.ListMultimap import spock.lang.Specification @@ -6,7 +22,7 @@ import spock.lang.Specification import java.nio.file.Path /** - * @author Jakub Kubrynski + * @author Jakub Kubrynski, codearte.io */ class ContractFileScannerSpec extends Specification { @@ -17,13 +33,13 @@ class ContractFileScannerSpec extends Specification { Set ignored = ["other/different/**"] as Set ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored) when: - ListMultimap result = scanner.findContracts() + ListMultimap result = scanner.findContracts() then: result.keySet().size() == 3 result.get(baseDir.toPath().resolve("different")).size() == 1 result.get(baseDir.toPath().resolve("other")).size() == 2 and: - Collection ignoredSet = result.get(baseDir.toPath().resolve("other").resolve("different")) + Collection ignoredSet = result.get(baseDir.toPath().resolve("other").resolve("different")) ignoredSet.size() == 1 ignoredSet.ignored == [true] } @@ -35,11 +51,11 @@ class ContractFileScannerSpec extends Specification { Set ignored = ["bar/**"] as Set ContractFileScanner scanner = new ContractFileScanner(baseDir, excluded, ignored) when: - ListMultimap result = scanner.findContracts() + ListMultimap result = scanner.findContracts() then: result.entries().size() == 2 and: - Collection ignoredSet = result.get(baseDir.toPath().resolve("bar")) + Collection ignoredSet = result.get(baseDir.toPath().resolve("bar")) ignoredSet.size() == 1 ignoredSet.ignored == [true] } @@ -49,7 +65,7 @@ class ContractFileScannerSpec extends Specification { File baseDir = new File(this.getClass().getResource("/directory/with/scenario").toURI()) ContractFileScanner scanner = new ContractFileScanner(baseDir, [] as Set, [] as Set) when: - ListMultimap contracts = scanner.findContracts() + ListMultimap contracts = scanner.findContracts() then: contracts.values().size() == 3 contracts.values().find { it.path.fileName.toString().startsWith('01') }.groupSize == 3 diff --git a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy similarity index 96% rename from accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy index 5cfdfab42d..958dddf585 100644 --- a/accurest-core/src/test/groovy/io/codearte/accurest/util/JsonToJsonPathsConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.util +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util import com.jayway.jsonpath.Configuration import com.jayway.jsonpath.DocumentContext diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/accurest-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator similarity index 100% rename from accurest-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy new file mode 100644 index 0000000000..38f5869fc5 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy @@ -0,0 +1,48 @@ +import org.springframework.cloud.contract.verifier.dsl.Contract + +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +Contract.make { + request { + method('PUT') + headers { + header 'Content-Type': 'application/json' + } + body("""\ + { + "name": "Jan", + "id": "${value(client('abc'), server('def'))}", + } + """ + ) + url $(client('/[0-9]{2}'), server('/12')) + } + response { + status 200 + body("""\ + { + "name": "Jan", + "id": "${value(client('123'), server('321'))}", + "surname": "${value(client('Kowalsky'), server('$checkIfSurnameValid($value)'))}" + } + """ + ) + headers { + header 'Content-Type': 'text/plain' + } + } +} diff --git a/accurest-core/src/test/resources/main.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/main.json similarity index 100% rename from accurest-core/src/test/resources/main.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/main.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy new file mode 100644 index 0000000000..958ccd0673 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy @@ -0,0 +1,16 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy new file mode 100644 index 0000000000..71935b4d5f --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy @@ -0,0 +1,61 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin + +import org.gradle.api.GradleException +import org.gradle.api.internal.ConventionTask +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.springframework.cloud.contract.verifier.ContractVerifierException +import org.springframework.cloud.contract.verifier.TestGenerator +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties + +/** + * Task used to generate server side tests + * + * @since 1.0.0 + */ +class GenerateServerTestsTask extends ConventionTask { + + @InputDirectory + File contractsDslDir + @OutputDirectory + File generatedTestSourcesDir + + //TODO: How to deal with @Input*, @Output* and that domain object? + ContractVerifierConfigProperties configProperties + + @TaskAction + void generate() { + project.logger.info("Spring Cloud Contract Verifier Plugin: Invoking test sources generation") + + project.sourceSets.test.groovy { + project.logger.info("Registering ${getConfigProperties().generatedTestSourcesDir} as test source directory") + srcDir getConfigProperties().generatedTestSourcesDir + } + + try { + //TODO: What with that? How to pass? + TestGenerator generator = new TestGenerator(getConfigProperties()) + int generatedClasses = generator.generate() + project.logger.info("Generated {} test classes", generatedClasses) + } catch (ContractVerifierException e) { + throw new GradleException("Spring Cloud Contract Verifier Plugin exception: ${e.message}", e) + } + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy new file mode 100644 index 0000000000..e8f565eb46 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy @@ -0,0 +1,49 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin + +import org.gradle.api.internal.ConventionTask +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.OutputDirectory +import org.gradle.api.tasks.TaskAction +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter +import org.springframework.cloud.contract.verifier.wiremock.RecursiveFilesConverter + +//TODO: Implement as an incremental task: https://gradle.org/docs/current/userguide/custom_tasks.html#incremental_tasks ? +/** + * Generates WireMock stubs from the contracts + * + * @since 1.0.0 + */ +class GenerateWireMockClientStubsFromDslTask extends ConventionTask { + + @InputDirectory + File contractsDslDir + @OutputDirectory + File stubsOutputDir + + ContractVerifierConfigProperties configProperties + + @TaskAction + void generate() { + logger.info("Spring Cloud Contract Verifier Plugin: Invoking DSL to WireMock client stubs conversion") + logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), getConfigProperties()) + converter.processFiles() + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy new file mode 100644 index 0000000000..e699653491 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy @@ -0,0 +1,114 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.Task +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties + +/** + * Gradle plugin for Spring Cloud Contract Verifier that from the DSL contract can + *
    + *
  • generate tests
  • + *
  • generate stubs
  • + *
+ * + * Also adds the necessary {@code testCompile} dependencies + * + *
    + *
  • WireMock
  • + *
  • JSON Assert
  • + *
  • AssertJ
  • + *
+ * + * @author Jakub Kubrynski, codearte.io + * + * @since 1.0.0 + */ +class SpringCloudContractVerifierGradlePlugin implements Plugin { + + private static final String GENERATE_SERVER_TESTS_TASK_NAME = 'generateContractTests' + private static final String DSL_TO_WIREMOCK_CLIENT_TASK_NAME = 'generateWireMockClientStubs' + + private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin + private static final String GROUP_NAME = "Verification" + private static final String EXTENSION_NAME = 'contractVerifier' + + private Project project + + @Override + void apply(Project project) { + this.project = project + ContractVerifierConfigProperties extension = project.extensions.create(EXTENSION_NAME, ContractVerifierConfigProperties) + + project.check.dependsOn(GENERATE_SERVER_TESTS_TASK_NAME) + + setConfigurationDefaults(extension) + createGenerateTestsTask(extension) + createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) + project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.10-beta") + project.dependencies.add("testCompile", "com.toomuchcoding.jsonassert:jsonassert:0.4.7") + project.dependencies.add("testCompile", "org.assertj:assertj-core:2.3.0") + + project.afterEvaluate { + def hasIdea = project.plugins.findPlugin(IDEA_PLUGIN_CLASS) + if (hasIdea) { + project.idea { + module { + testSourceDirs += extension.generatedTestSourcesDir + testSourceDirs += extension.contractsDslDir + } + } + } + } + } + + private void setConfigurationDefaults(ContractVerifierConfigProperties extension) { + extension.with { + generatedTestSourcesDir = project.file("${project.buildDir}/generated-test-sources/contracts") + contractsDslDir = defaultContractsDir() //TODO: Use sourceset + basePackageForTests = 'org.springframework.cloud.contract.verifier.tests' + } + } + + private File defaultContractsDir() { + project.file("${project.rootDir}/src/test/resources/contracts") + } + + private void createGenerateTestsTask(ContractVerifierConfigProperties extension) { + Task task = project.tasks.create(GENERATE_SERVER_TESTS_TASK_NAME, GenerateServerTestsTask) + task.description = "Generate server tests from the contracts" + task.group = GROUP_NAME + task.conventionMapping.with { + contractsDslDir = { extension.contractsDslDir } + generatedTestSourcesDir = { extension.generatedTestSourcesDir } + configProperties = { extension } + } + } + + private void createAndConfigureGenerateWireMockClientStubsFromDslTask(ContractVerifierConfigProperties extension) { + Task task = project.tasks.create(DSL_TO_WIREMOCK_CLIENT_TASK_NAME, GenerateWireMockClientStubsFromDslTask) + task.description = "Generate WireMock client stubs from the contracts" + task.group = GROUP_NAME + task.conventionMapping.with { + contractsDslDir = { extension.contractsDslDir } + stubsOutputDir = { extension.stubsOutputDir } + configProperties = { extension } + } + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties new file mode 100644 index 0000000000..d5479da71a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties @@ -0,0 +1,17 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +implementation-class=org.springframework.cloud.contract.verifier.plugin.SpringCloudContractVerifierGradlePlugin \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy similarity index 64% rename from accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy index 015825ccf1..8634877b49 100755 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/BasicFunctionalSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy @@ -1,5 +1,21 @@ -package io.codearte.accurest.plugin -import io.codearte.accurest.util.AssertionUtil +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin +import org.springframework.cloud.contract.verifier.util.AssertionUtil import org.gradle.testkit.runner.BuildResult import spock.lang.Stepwise @@ -7,12 +23,12 @@ import static org.gradle.testkit.runner.TaskOutcome.SUCCESS import static org.gradle.testkit.runner.TaskOutcome.UP_TO_DATE @Stepwise -class BasicFunctionalSpec extends AccurestIntegrationSpec { +class BasicFunctionalSpec extends ContractVerifierIntegrationSpec { - private static final String GENERATED_TEST = "build//generated-test-sources//accurest//accurest//com//ofg//twitter_places_analyzer//PairIdSpec.groovy" - private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//com//ofg//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.json" - private static final String GROOVY_DSL_CONTRACT = "repository//mappings//com//ofg//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.groovy" - private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-accurest.com.ofg.twitter_places_analyzer.PairIdSpec.xml" + private static final String GENERATED_TEST = "build//generated-test-sources//contracts//contracts//spring//cloud//twitter_places_analyzer//PairIdSpec.groovy" + private static final String GENERATED_CLIENT_JSON_STUB = "build//production//bootSimple-stubs//repository//mappings//spring//cloud//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.json" + private static final String GROOVY_DSL_CONTRACT = "repository//mappings//spring//cloud//twitter-places-analyzer//pairId//collerate_PlacesFrom_Tweet.groovy" + private static final String TEST_EXECUTION_XML_REPORT = "build/test-results/TEST-contracts.spring.cloud.twitter_places_analyzer.PairIdSpec.xml" def setup() { setupForProject("functionalTest/bootSimple") @@ -24,7 +40,7 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { BuildResult result = run("check", "publishToMavenLocal") then: result.task(":generateWireMockClientStubs").outcome == SUCCESS - result.task(":generateAccurest").outcome == SUCCESS + result.task(":generateContractTests").outcome == SUCCESS and: "tests generated" fileExists(GENERATED_TEST) @@ -68,26 +84,26 @@ class BasicFunctionalSpec extends AccurestIntegrationSpec { assert !fileExists(GENERATED_CLIENT_JSON_STUB) assert !fileExists(TEST_EXECUTION_XML_REPORT) when: - runTasksSuccessfully('generateWireMockClientStubs', 'generateAccurest') + runTasksSuccessfully('generateWireMockClientStubs', 'generateContractTests') then: fileExists(GENERATED_CLIENT_JSON_STUB) fileExists(GENERATED_TEST) when: "running generation without change inputs" - def secondExecutionResult = run('generateWireMockClientStubs', 'generateAccurest') + def secondExecutionResult = run('generateWireMockClientStubs', 'generateContractTests') then: "tasks should be up-to-date" - validateTasksOutcome(secondExecutionResult, UP_TO_DATE, 'generateWireMockClientStubs', 'generateAccurest') + validateTasksOutcome(secondExecutionResult, UP_TO_DATE, 'generateWireMockClientStubs', 'generateContractTests') when: "inputs changed" def groovyDslFile = file(GROOVY_DSL_CONTRACT) groovyDslFile.text = groovyDslFile.text.replace("200", "599") and: "tasks run" - def thirdExecutionResult = run('generateWireMockClientStubs', 'generateAccurest') + def thirdExecutionResult = run('generateWireMockClientStubs', 'generateContractTests') then: "tasks should be reexecuted" - validateTasksOutcome(thirdExecutionResult, SUCCESS, 'generateWireMockClientStubs', 'generateAccurest') + validateTasksOutcome(thirdExecutionResult, SUCCESS, 'generateWireMockClientStubs', 'generateContractTests') and: "changes visible in generate files" file(GENERATED_CLIENT_JSON_STUB).text.contains("599") diff --git a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy similarity index 70% rename from accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy index 779d156be3..6e3ced3368 100644 --- a/accurest-gradle-plugin/src/test/groovy/io/codearte/accurest/plugin/AccurestIntegrationSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.plugin +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin import org.apache.commons.io.FileUtils import org.gradle.testkit.runner.BuildResult @@ -13,12 +29,8 @@ import java.util.zip.ZipException import java.util.zip.ZipFile import static java.nio.charset.StandardCharsets.UTF_8 -/** - * @author Olga Maciaszek-Sharma - * @author Denis Stepanov - * @since 23.02.16 - */ -abstract class AccurestIntegrationSpec extends Specification { + +abstract class ContractVerifierIntegrationSpec extends Specification { File testProjectDir @@ -31,20 +43,22 @@ abstract class AccurestIntegrationSpec extends Specification { public static final String SPOCK = "targetFramework = 'Spock'" public static final String JUNIT = "targetFramework = 'JUnit'" - public static final String MVC_SPEC = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec'" - public static final String MVC_TEST = "baseClassForTests = 'com.blogspot.toomuchcoding.MvcTest'" + public static final String MVC_SPEC = "baseClassForTests = 'org.springframework.cloud.MvcSpec'" + public static final String MVC_TEST = "baseClassForTests = 'org.springframework.cloud.MvcTest'" protected void setupForProject(String projectRoot) { copyResourcesToRoot(projectRoot) - String accurestGradlePluginLibsDir = System.getProperty("accurest-gradle-plugin-libs-dir").replace('\\', '\\\\') - String messagingLibDir = System.getProperty("messaging-libs-dir").replace('\\', '\\\\') + String gradlePluginSysProp = System.getProperty("contract-verifier-gradle-plugin-libs-dir") + String gradlePluginLibsDir = (gradlePluginSysProp ?: new File("build/").toString()).replace('\\', '\\\\') + String messagingLibDirProp = System.getProperty("messaging-libs-dir") + String messagingLibDir = (messagingLibDirProp ?: new File("build/").toString()).replace('\\', '\\\\') buildFile.write """ ext.messagingLibsDir = '$messagingLibDir' buildscript { dependencies { - classpath fileTree(dir: '$accurestGradlePluginLibsDir', include: '*.jar') + classpath fileTree(dir: '$gradlePluginLibsDir', include: '*.jar') } } @@ -117,7 +131,7 @@ abstract class AccurestIntegrationSpec extends Specification { return new File('build.gradle', testProjectDir) } - protected boolean jarContainsAccurestContracts(String path) { + protected boolean jarContainsContractVerifierContracts(String path) { assert fileExists(path) File rootFile = file(path) boolean containsGroovyFiles = false diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy new file mode 100755 index 0000000000..9f63a1b29c --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy @@ -0,0 +1,47 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin + +import spock.lang.Stepwise + +@Stepwise +class MessagingProjectSpec extends ContractVerifierIntegrationSpec { + + def setup() { + setupForProject("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', "publishToMavenLocal") + jarContainsContractVerifierContracts('build/libs') + } + + def "should pass basic flow for JUnit"() { + given: + runTasksSuccessfully('clean') + assert fileExists('build.gradle') + expect: + switchToJunitTestFramework('org.springframework.cloud.samples.book.MessagingBaseSpec', 'org.springframework.cloud.samples.book.MessagingBaseTest') + runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsContractVerifierContracts('build/libs') + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy new file mode 100755 index 0000000000..25b6754d60 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin + +import spock.lang.Stepwise + +@Stepwise +class SampleJerseyProjectSpec extends ContractVerifierIntegrationSpec { + + def setup() { + setupForProject("functionalTest/sampleJerseyProject") + 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', "publishToMavenLocal") + jarContainsContractVerifierContracts('fraudDetectionService/build/libs') + } + + def "should pass basic flow for JUnit"() { + given: + switchToJunitTestFramework() + assert fileExists('build.gradle') + expect: + runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsContractVerifierContracts('fraudDetectionService/build/libs') + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy new file mode 100755 index 0000000000..5b31c3d4dd --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin + +import spock.lang.Stepwise + +@Stepwise +class SampleProjectSpec extends ContractVerifierIntegrationSpec { + + def setup() { + setupForProject("functionalTest/sampleProject") + 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', "publishToMavenLocal") + jarContainsContractVerifierContracts('fraudDetectionService/build/libs') + } + + def "should pass basic flow for JUnit"() { + given: + switchToJunitTestFramework() + assert fileExists('build.gradle') + expect: + runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsContractVerifierContracts('fraudDetectionService/build/libs') + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy new file mode 100755 index 0000000000..f822982bef --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.plugin + +import spock.lang.Stepwise + +@Stepwise +class ScenarioProjectSpec extends ContractVerifierIntegrationSpec { + + def setup() { + setupForProject("functionalTest/scenarioProject") + 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', "publishToMavenLocal") + jarContainsContractVerifierContracts('fraudDetectionService/build/libs') + } + + def "should pass basic flow for JUnit"() { + given: + assert fileExists('build.gradle') + expect: + switchToJunitTestFramework() + runTasksSuccessfully('check', "publishToMavenLocal") + jarContainsContractVerifierContracts('fraudDetectionService/build/libs') + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle similarity index 88% rename from accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 602bb14cc8..1acee5de97 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -5,16 +5,16 @@ buildscript { } apply plugin: 'groovy' -apply plugin: 'accurest' +apply plugin: 'contract-verifier' apply plugin: 'maven-publish' -group = 'io.codearte.accurest.testprojects' +group = 'org.springframework.cloud.testprojects' ext { contractsDir = file("repository/mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) - contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) + contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/contracts/')) } configurations { @@ -49,9 +49,9 @@ dependencies { testCompile "ch.qos.logback:logback-classic:1.1.2" } -accurest { - baseClassForTests = 'com.ofg.twitter.places.BaseMockMvcSpec' - basePackageForTests = 'accurest' +contractVerifier { + baseClassForTests = 'org.springframework.cloud.contract.verifier.twitter.places.BaseMockMvcSpec' + basePackageForTests = 'contracts' contractsDslDir = contractsDir // generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/") stubsOutputDir = wireMockStubsOutputDir @@ -64,7 +64,7 @@ task createWireMockStubsOutputDir << { } generateWireMockClientStubs.dependsOn { createWireMockStubsOutputDir } -generateAccurest.dependsOn generateWireMockClientStubs +generateContractTests.dependsOn generateWireMockClientStubs wrapper { gradleVersion '2.2.1' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties new file mode 100644 index 0000000000..7c325172fd --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties @@ -0,0 +1,22 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +groupId=org.springframework.cloud.contract.verifier +jacksonMapper=1.9.13 +restAssuredVersion=2.4.0 +springVersion=4.1.7.RELEASE + +springBootVersion=1.3.3.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties new file mode 100755 index 0000000000..f510690c32 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,22 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#Sat Feb 21 20:13:29 CET 2015 +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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy new file mode 100644 index 0000000000..2f01af1c93 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + priority 2 + request { + method 'PUT' + url '/api/12' + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] +''' + } + response { + status 200 + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy new file mode 100644 index 0000000000..c98b51279d --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + request { + method 'PUT' + url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) + headers { + header 'Content-Type': 'application/json' + } + body '''\ + [{ + "text": "Gonna see you at Warsaw" + }] +''' + } + response { + headers { + header 'Content-Type': $(client('application/json'), server(regex('application/json.*'))) + header 'Location': $(client('https://localhost:8080'), server(execute('isEmpty($it)'))) + } + body ( + path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))), + correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)'))) + ) + status 200 + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle new file mode 100644 index 0000000000..f452413fb1 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle @@ -0,0 +1,17 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +rootProject.name='bootSimple' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy similarity index 56% rename from accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy index 3a7671793c..38b7dfc178 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/PairIdController.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy @@ -1,4 +1,20 @@ -package com.ofg.twitter.place +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.twitter.place import groovy.transform.TypeChecked import groovy.util.logging.Slf4j @@ -21,7 +37,7 @@ class PairIdController { method = PUT, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) - String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { + String getPlacesFromTweets(@PathVariable long pairId, @RequestBody List tweets) { log.info("Inside PairIdController, doing very important logic") if (tweets?.text != ["Gonna see you at Warsaw"]) { throw new IllegalArgumentException("Wrong text in tweet: ${tweets?.text}") diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java similarity index 69% rename from accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java index 5d1e9c2835..9417289cec 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/com/ofg/twitter/place/Tweet.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java @@ -1,4 +1,4 @@ -package com.ofg.twitter.place; +package org.springframework.cloud.contract.verifier.twitter.place; public class Tweet { private String text; diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy new file mode 100644 index 0000000000..9f482e0b4c --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.twitter.places + +import org.springframework.cloud.contract.verifier.twitter.place.PairIdController +import org.springframework.http.MediaType +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import spock.lang.Specification + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status + +class AcceptanceSpec extends Specification { + + def "should have controller up and running"() { + given: + MockMvc mockMvc = MockMvcBuilders.standaloneSetup(new PairIdController()).build() + expect: + mockMvc.perform(put("/api/${1}"). + contentType(MediaType.APPLICATION_JSON). + content("""[{"text":"Gonna see you at Warsaw"}]""")). + andExpect(status().isOk()) + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy new file mode 100644 index 0000000000..6057d7081a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy @@ -0,0 +1,39 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.twitter.places + +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import org.springframework.cloud.contract.verifier.twitter.place.PairIdController +import spock.lang.Specification + +// tag::base_class[] +abstract class BaseMockMvcSpec extends Specification { + + def setup() { + RestAssuredMockMvc.standaloneSetup(new PairIdController()) + } + + void isProperCorrelationId(Integer correlationId) { + assert correlationId == 123456 + } + + void isEmpty(String value) { + assert value == null + } + +} +// end::base_class[] diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy new file mode 100644 index 0000000000..0b49bdfb4a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import ch.qos.logback.classic.encoder.PatternLayoutEncoder +import ch.qos.logback.core.ConsoleAppender + +String console = "CONSOLE" +String logPattern = "%d{yyyy-MM-dd HH:mm:ss.SSSZ, Europe/Warsaw} | %-5level | %X{correlationId} | %thread | %logger{1} | %m%n" + +appender(console, ConsoleAppender) { + encoder(PatternLayoutEncoder) { + pattern = logPattern + } +} + +root(INFO, [console]) +logger("org.springframework.cloud.contract.verifier", DEBUG) diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle similarity index 85% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle index 8b476c9267..2f5a549e19 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle @@ -6,16 +6,16 @@ buildscript { } apply plugin: 'groovy' -apply plugin: 'accurest' +apply plugin: 'contract-verifier' apply plugin: 'maven-publish' -group = 'io.codearte.accurest.testprojects' +group = 'org.springframework.cloud.testprojects' ext { contractsDir = file("repository/mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/') - contractsOutputDir = new File(stubsOutputDirRoot, 'repository/accurest/') + contractsOutputDir = new File(stubsOutputDirRoot, 'repository/contracts/') targetFramework = 'Spock' } @@ -58,10 +58,10 @@ dependencies { testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' // needed if you're going to use Spring MockMvc } -accurest { - //baseClassForTests = 'io.codearte.accurest.samples.book.MessagingBaseTest' - baseClassForTests = 'io.codearte.accurest.samples.book.MessagingBaseSpec' - basePackageForTests = 'accurest' +contractVerifier { + //baseClassForTests = 'org.springframework.cloud.samples.book.MessagingBaseTest' + baseClassForTests = 'org.springframework.cloud.samples.book.MessagingBaseSpec' + basePackageForTests = 'contracts' //targetFramework = 'JUnit' targetFramework = 'Spock' contractsDslDir = contractsDir @@ -75,7 +75,7 @@ task createWireMockStubsOutputDir << { } generateWireMockClientStubs.dependsOn { createWireMockStubsOutputDir } -generateAccurest.dependsOn generateWireMockClientStubs +generateContractTests.dependsOn generateWireMockClientStubs wrapper { gradleVersion '2.12' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties new file mode 100644 index 0000000000..7293ee6bc8 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties @@ -0,0 +1,22 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +groupId=org.springframework.cloud +jacksonMapper=1.9.13 +restAssuredVersion=2.9.0 +springVersion=4.2.3.RELEASE + +springBootVersion=1.3.3.RELEASE \ No newline at end of file diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties new file mode 100755 index 0000000000..7f6620ddcf --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,22 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy new file mode 100644 index 0000000000..202c8808fe --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy @@ -0,0 +1,28 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + request { + url '/foo' + method 'GET' + } + response { + status 200 + body 'bar' + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy new file mode 100644 index 0000000000..4c73b42e4d --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy @@ -0,0 +1,31 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + label 'some_label' + input { + messageFrom('delete') + messageBody([ + bookName: 'foo' + ]) + messageHeaders { + header('sample', 'header') + } + assertThat('bookWasDeleted()') + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy new file mode 100644 index 0000000000..3d4ba32c3a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + label 'some_label' + input { + triggeredBy('bookReturnedTriggered()') + } + outputMessage { + sentTo('output') + body('''{ "bookName" : "foo" }''') + headers { + header('BOOK-NAME', 'foo') + } + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy new file mode 100644 index 0000000000..91ae4361ef --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.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') + } + } +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle new file mode 100644 index 0000000000..f452413fb1 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle @@ -0,0 +1,17 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +rootProject.name='bootSimple' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy new file mode 100644 index 0000000000..3d9e527fb5 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.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 + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookListener.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookListener.groovy similarity index 67% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookListener.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookListener.groovy index 60838893b8..6399b53a79 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookListener.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookListener.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.book +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.samples.book import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy new file mode 100644 index 0000000000..22353e827f --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.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 + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookService.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookService.groovy similarity index 61% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookService.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookService.groovy index 25e943fc93..b44a36a834 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/io/codearte/accurest/samples/book/BookService.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookService.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.book +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.samples.book import groovy.transform.CompileStatic import groovy.util.logging.Slf4j diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy new file mode 100644 index 0000000000..e7345c64c8 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.samples.book + +import org.springframework.boot.SpringApplication +import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.context.annotation.ImportResource +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@SpringBootApplication +@RestController +@ImportResource("classpath*:integration-context.xml") +class IntegrationMessagingApplication { + + @RequestMapping("/foo") + String foo() { + return "bar" + } + + static void main(String[] args) { + SpringApplication.run(IntegrationMessagingApplication.class, args) + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml similarity index 52% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml index e8c7accb04..f29045cdb2 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml @@ -1,4 +1,20 @@ + + - - - + diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud/samples/book/MessagingBaseSpec.groovy similarity index 56% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud/samples/book/MessagingBaseSpec.groovy index 0beb893d51..b0950a030c 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/io/codearte/accurest/samples/book/MessagingBaseSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud/samples/book/MessagingBaseSpec.groovy @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.book +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.samples.book import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud/samples/book/MessagingBaseTest.java similarity index 62% rename from accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud/samples/book/MessagingBaseTest.java index 47634cbf37..2cc4aa8abb 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/io/codearte/accurest/samples/book/MessagingBaseTest.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud/samples/book/MessagingBaseTest.java @@ -1,4 +1,20 @@ -package io.codearte.accurest.samples.book; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.samples.book; import org.assertj.core.api.Assertions; import org.junit.runner.RunWith; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle similarity index 75% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index 3e3e107564..5b67157601 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + buildscript { repositories { mavenLocal() @@ -8,14 +24,14 @@ buildscript { } } -group = 'io.codearte.accurest.testprojects' +group = 'org.springframework.cloud.testprojects' ext { restAssuredVersion = '2.5.0' spockVersion = '1.0-groovy-2.4' wiremockVersion = '2.0.10-beta' - accurestStubsBaseDirectory = 'src/test/resources/stubs' + contractVerifierStubsBaseDirectory = 'src/test/resources/stubs' } subprojects { @@ -36,20 +52,20 @@ subprojects { configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { apply plugin: 'spring-boot' - apply plugin: 'accurest' + apply plugin: 'contract-verifier' apply plugin: 'maven-publish' ext { contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) - contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) + contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/contracts/')) } - accurest { + contractVerifier { targetFramework = 'Spock' testMode = 'JaxRsClient' - baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' + baseClassForTests = 'org.springframework.cloud.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") stubsOutputDir = wireMockStubsOutputDir @@ -125,6 +141,6 @@ configure(project(':loanApplicationService')) { into "src/test/resources/" } - generateAccurest.dependsOn('copyCollaboratorStubs') + generateContractTests.dependsOn('copyCollaboratorStubs') } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy new file mode 100644 index 0000000000..2634bca6cc --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy new file mode 100644 index 0000000000..249de5bc5f --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 92% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java index 99a72fbf26..e671a56892 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.boot.SpringApplication; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java similarity index 73% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java index bb015f08a4..3eaaea3a42 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java @@ -1,15 +1,15 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheck; -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckResult; +import org.springframework.cloud.frauddetection.model.FraudCheck; +import org.springframework.cloud.frauddetection.model.FraudCheckResult; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestBody; import javax.ws.rs.*; import java.math.BigDecimal; -import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.FRAUD; -import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.OK; +import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.FRAUD; +import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.OK; @Controller @Path("/") diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java similarity index 83% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java index 83e15edc59..064e59196b 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudRestApplication.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; import java.util.Collections; import java.util.Set; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java similarity index 88% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java index 77471aee19..72551915bc 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; import java.math.BigDecimal; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java similarity index 92% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java index 28efc573f5..95fd5e04c4 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class FraudCheckResult { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b4fd951df2 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package org.springframework.cloud.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy similarity index 65% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy index 621d20ded4..1fab371acc 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/com/blogspot/toomuchcoding/MvcSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy @@ -1,6 +1,22 @@ -package com.blogspot.toomuchcoding -import com.blogspot.toomuchcoding.frauddetection.Application -import com.blogspot.toomuchcoding.frauddetection.FraudRestApplication +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud +import org.springframework.cloud.frauddetection.Application +import org.springframework.cloud.frauddetection.FraudRestApplication import org.eclipse.jetty.server.Server import org.glassfish.jersey.apache.connector.ApacheConnectorProvider import org.glassfish.jersey.client.ClientConfig diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java similarity index 91% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java index d36d31e510..93c9209621 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java @@ -1,7 +1,7 @@ -package com.blogspot.toomuchcoding; +package org.springframework.cloud; -import com.blogspot.toomuchcoding.frauddetection.Application; -import com.blogspot.toomuchcoding.frauddetection.FraudRestApplication; +import org.springframework.cloud.frauddetection.Application; +import org.springframework.cloud.frauddetection.FraudRestApplication; import org.eclipse.jetty.server.Server; import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; import org.glassfish.jersey.client.ClientConfig; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..1aa6b34ba4 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,22 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#Wed Jan 28 00:32:44 CET 2015 +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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java new file mode 100644 index 0000000000..e70eca242e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java @@ -0,0 +1,33 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.frauddetection; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableAutoConfiguration +@ComponentScan +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java similarity index 62% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java index a2d8ce1e74..64402473fa 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java @@ -1,11 +1,27 @@ -package com.blogspot.toomuchcoding.frauddetection; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus; -import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceRequest; -import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceResponse; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus; +package org.springframework.cloud.frauddetection; + +import org.springframework.cloud.frauddetection.model.FraudCheckStatus; +import org.springframework.cloud.frauddetection.model.FraudServiceRequest; +import org.springframework.cloud.frauddetection.model.FraudServiceResponse; +import org.springframework.cloud.frauddetection.model.LoanApplication; +import org.springframework.cloud.frauddetection.model.LoanApplicationResult; +import org.springframework.cloud.frauddetection.model.LoanApplicationStatus; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java new file mode 100644 index 0000000000..403da83818 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.frauddetection.model; + +public class Client { + + private String pesel; + + public String getPesel() { + return pesel; + } + + public void setPesel(String pesel) { + this.pesel = pesel; + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..4fb43b0cf8 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,21 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java new file mode 100644 index 0000000000..fc2aa4580c --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java @@ -0,0 +1,50 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.frauddetection.model; + +import java.math.BigDecimal; + +public class FraudServiceRequest { + + private String clientPesel; + + private BigDecimal loanAmount; + + public FraudServiceRequest() { + } + + public FraudServiceRequest(LoanApplication loanApplication) { + this.clientPesel = loanApplication.getClient().getPesel(); + this.loanAmount = loanApplication.getAmount(); + } + + public String getClientPesel() { + return clientPesel; + } + + public void setClientPesel(String clientPesel) { + this.clientPesel = clientPesel; + } + + public BigDecimal getLoanAmount() { + return loanAmount; + } + + public void setLoanAmount(BigDecimal loanAmount) { + this.loanAmount = loanAmount; + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java new file mode 100644 index 0000000000..79eb5b2c0d --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java @@ -0,0 +1,43 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.frauddetection.model; + +public class FraudServiceResponse { + + private FraudCheckStatus fraudCheckStatus; + + private String rejectionReason; + + public FraudServiceResponse() { + } + + public FraudCheckStatus getFraudCheckStatus() { + return fraudCheckStatus; + } + + public void setFraudCheckStatus(FraudCheckStatus fraudCheckStatus) { + this.fraudCheckStatus = fraudCheckStatus; + } + + public String getRejectionReason() { + return rejectionReason; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java new file mode 100644 index 0000000000..ad2c6c80a1 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java @@ -0,0 +1,52 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.frauddetection.model; + +import java.math.BigDecimal; + +public class LoanApplication { + + private Client client; + + private BigDecimal amount; + + private String loanApplicationId; + + public Client getClient() { + return client; + } + + public void setClient(Client client) { + this.client = client; + } + + public BigDecimal getAmount() { + return amount; + } + + public void setAmount(BigDecimal amount) { + this.amount = amount; + } + + public String getLoanApplicationId() { + return loanApplicationId; + } + + public void setLoanApplicationId(String loanApplicationId) { + this.loanApplicationId = loanApplicationId; + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java similarity index 53% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java index 523f4f2ea3..a9b0617c11 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java @@ -1,4 +1,20 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.frauddetection.model; public class LoanApplicationResult { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java new file mode 100644 index 0000000000..e939d49b8f --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java @@ -0,0 +1,21 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.frauddetection.model; + +public enum LoanApplicationStatus { + LOAN_APPLIED, LOAN_APPLICATION_REJECTED +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy similarity index 58% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy index 21ee7a4d39..d5104eb499 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy @@ -1,11 +1,27 @@ -package com.blogspot.toomuchcoding +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import com.blogspot.toomuchcoding.frauddetection.Application -import com.blogspot.toomuchcoding.frauddetection.LoanApplicationService -import com.blogspot.toomuchcoding.frauddetection.model.Client -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus +package org.springframework.cloud + +import org.springframework.cloud.frauddetection.Application +import org.springframework.cloud.frauddetection.LoanApplicationService +import org.springframework.cloud.frauddetection.model.Client +import org.springframework.cloud.frauddetection.model.LoanApplication +import org.springframework.cloud.frauddetection.model.LoanApplicationResult +import org.springframework.cloud.frauddetection.model.LoanApplicationStatus import com.github.tomakehurst.wiremock.junit.WireMockClassRule import org.junit.ClassRule import org.springframework.beans.factory.annotation.Autowired diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle new file mode 100644 index 0000000000..48db488159 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle @@ -0,0 +1,18 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +include ':fraudDetectionService' +include ':loanApplicationService' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle similarity index 75% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index 606fc7ba5d..b388ed0da6 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + buildscript { repositories { mavenCentral() @@ -13,10 +29,10 @@ ext { spockVersion = '1.0-groovy-2.4' wiremockVersion = '2.0.10-beta' - accurestStubsBaseDirectory = 'src/test/resources/stubs' + contractVerifierStubsBaseDirectory = 'src/test/resources/stubs' } -group = 'io.codearte.accurest.testprojects' +group = 'org.springframework.cloud.testprojects' subprojects { apply plugin: 'groovy' @@ -36,20 +52,20 @@ subprojects { configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { apply plugin: 'spring-boot' - apply plugin: 'accurest' + apply plugin: 'contract-verifier' apply plugin: 'maven-publish' ext { contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) - contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) + contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/contracts/')) } - accurest { + contractVerifier { targetFramework = 'Spock' testMode = 'MockMvc' - baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' + baseClassForTests = 'org.springframework.cloud.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") stubsOutputDir = wireMockStubsOutputDir @@ -122,6 +138,6 @@ configure(project(':loanApplicationService')) { into "src/test/resources/" } - generateAccurest.dependsOn('copyCollaboratorStubs') + generateContractTests.dependsOn('copyCollaboratorStubs') } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy new file mode 100644 index 0000000000..91246ddfee --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy @@ -0,0 +1,44 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy new file mode 100644 index 0000000000..5a2f1a1312 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java similarity index 72% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java index 5a1a60244e..bc8131fe49 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -11,7 +11,8 @@ import org.springframework.context.annotation.Configuration; public class Application { public static void main(String[] args) { - SpringApplication.run(Application.class, args); + SpringApplication.run( + org.springframework.cloud.frauddetection.Application.class, args); } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java similarity index 76% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java index e264462cce..213a037f87 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java @@ -1,15 +1,15 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheck; -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckResult; +import org.springframework.cloud.frauddetection.model.FraudCheck; +import org.springframework.cloud.frauddetection.model.FraudCheckResult; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.math.BigDecimal; -import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.FRAUD; -import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.OK; +import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.FRAUD; +import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.OK; import static org.springframework.web.bind.annotation.RequestMethod.PUT; @RestController diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java similarity index 88% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java index 77471aee19..72551915bc 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; import java.math.BigDecimal; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java similarity index 92% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java index 28efc573f5..95fd5e04c4 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class FraudCheckResult { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b4fd951df2 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package org.springframework.cloud.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy new file mode 100644 index 0000000000..dfff02db5e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy @@ -0,0 +1,31 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud + +import org.springframework.cloud.frauddetection.FraudDetectionController +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import spock.lang.Specification + +class MvcSpec extends Specification { + def setup() { + RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) + } + + void assertThatRejectionReasonIsNull(def rejectionReason) { + assert !rejectionReason + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java similarity index 63% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java index 084a65ebf5..8fa2aad6ff 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding; +package org.springframework.cloud; import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; import org.junit.Before; @@ -7,7 +7,7 @@ public class MvcTest { @Before public void setup() { - RestAssuredMockMvc.standaloneSetup(new com.blogspot.toomuchcoding.frauddetection.FraudDetectionController()); + RestAssuredMockMvc.standaloneSetup(new org.springframework.cloud.frauddetection.FraudDetectionController()); } public void assertThatRejectionReasonIsNull(Object rejectionReason) { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..1aa6b34ba4 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,22 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#Wed Jan 28 00:32:44 CET 2015 +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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 72% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java index 5a1a60244e..bc8131fe49 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -11,7 +11,8 @@ import org.springframework.context.annotation.Configuration; public class Application { public static void main(String[] args) { - SpringApplication.run(Application.class, args); + SpringApplication.run( + org.springframework.cloud.frauddetection.Application.class, args); } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java similarity index 79% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java index a2d8ce1e74..65ec787113 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java @@ -1,11 +1,11 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus; -import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceRequest; -import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceResponse; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus; +import org.springframework.cloud.frauddetection.model.FraudCheckStatus; +import org.springframework.cloud.frauddetection.model.FraudServiceRequest; +import org.springframework.cloud.frauddetection.model.FraudServiceResponse; +import org.springframework.cloud.frauddetection.model.LoanApplication; +import org.springframework.cloud.frauddetection.model.LoanApplicationResult; +import org.springframework.cloud.frauddetection.model.LoanApplicationStatus; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java similarity index 73% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java index 5e91273eda..1a85740dde 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class Client { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b4fd951df2 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package org.springframework.cloud.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java similarity index 91% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java index ac595998bc..f79ff3b740 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; import java.math.BigDecimal; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java similarity index 90% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java index 9f3353ecbf..dbf8384a53 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class FraudServiceResponse { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java similarity index 91% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java index 816087988b..58757331d0 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; import java.math.BigDecimal; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java similarity index 93% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java index 523f4f2ea3..11c3ee1d2c 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class LoanApplicationResult { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java similarity index 58% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java index 7f7f86e0ea..bdb886d0fc 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public enum LoanApplicationStatus { LOAN_APPLIED, LOAN_APPLICATION_REJECTED diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy similarity index 58% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy index 21ee7a4d39..d5104eb499 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy @@ -1,11 +1,27 @@ -package com.blogspot.toomuchcoding +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import com.blogspot.toomuchcoding.frauddetection.Application -import com.blogspot.toomuchcoding.frauddetection.LoanApplicationService -import com.blogspot.toomuchcoding.frauddetection.model.Client -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus +package org.springframework.cloud + +import org.springframework.cloud.frauddetection.Application +import org.springframework.cloud.frauddetection.LoanApplicationService +import org.springframework.cloud.frauddetection.model.Client +import org.springframework.cloud.frauddetection.model.LoanApplication +import org.springframework.cloud.frauddetection.model.LoanApplicationResult +import org.springframework.cloud.frauddetection.model.LoanApplicationStatus import com.github.tomakehurst.wiremock.junit.WireMockClassRule import org.junit.ClassRule import org.springframework.beans.factory.annotation.Autowired diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle new file mode 100644 index 0000000000..48db488159 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle @@ -0,0 +1,18 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +include ':fraudDetectionService' +include ':loanApplicationService' diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle similarity index 76% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index 6b72e88a6a..75060f4740 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -1,3 +1,19 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + buildscript { repositories { mavenCentral() @@ -13,10 +29,10 @@ ext { spockVersion = '1.0-groovy-2.4' wiremockVersion = '2.0.10-beta' - accurestStubsBaseDirectory = 'src/test/resources/stubs' + contractVerifierStubsBaseDirectory = 'src/test/resources/stubs' } -group = 'io.codearte.accurest.testprojects' +group = 'org.springframework.cloud.testprojects' subprojects { apply plugin: 'groovy' @@ -37,14 +53,14 @@ subprojects { configure([project(':fraudDetectionService'), project(':loanApplicationService')]) { apply plugin: 'spring-boot' - apply plugin: 'accurest' + apply plugin: 'contract-verifier' // tag::jar_setup[] ext { contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) - contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/')) + contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/contracts/')) } task copyContracts(type: Copy) { @@ -73,12 +89,12 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') } // end::jar_setup[] - accurest { + contractVerifier { // tag::target_framework[] targetFramework = 'Spock' // end::target_framework[] testMode = 'MockMvc' - baseClassForTests = 'com.blogspot.toomuchcoding.MvcSpec' + baseClassForTests = 'org.springframework.cloud.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") stubsOutputDir = wireMockStubsOutputDir @@ -126,6 +142,6 @@ configure(project(':loanApplicationService')) { into "src/test/resources/" } - generateAccurest.dependsOn('copyCollaboratorStubs') + generateContractTests.dependsOn('copyCollaboratorStubs') } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy new file mode 100644 index 0000000000..5a2f1a1312 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + request { + method 'PUT' + url '/fraudcheck' + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":123.123 + } + """ + ) + headers { + header('Content-Type', 'application/vnd.fraud.v1+json') + } + + } + response { + status 200 + body( + fraudCheckStatus: "OK", + rejectionReason: $(client(null), server(execute('assertThatRejectionReasonIsNull($it)'))) + ) + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy new file mode 100644 index 0000000000..2634bca6cc --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.springframework.cloud.contract.verifier.dsl.Contract + +Contract.make { + request { + method """PUT""" + url """/fraudcheck""" + body(""" + { + "clientPesel":"${value(client(regex('[0-9]{10}')), server('1234567890'))}", + "loanAmount":99999} + """ + ) + headers { + header("""Content-Type""", """application/vnd.fraud.v1+json""") + } + + } + response { + status 200 + body( """{ + "fraudCheckStatus": "${value(client('FRAUD'), server(regex('[A-Z]{5}')))}", + "rejectionReason": "Amount too high" +}""") + headers { + header('Content-Type': 'application/vnd.fraud.v1+json') + } + } + +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 72% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java index 5a1a60244e..bc8131fe49 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -11,7 +11,8 @@ import org.springframework.context.annotation.Configuration; public class Application { public static void main(String[] args) { - SpringApplication.run(Application.class, args); + SpringApplication.run( + org.springframework.cloud.frauddetection.Application.class, args); } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java similarity index 76% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java index e264462cce..213a037f87 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java @@ -1,15 +1,15 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheck; -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckResult; +import org.springframework.cloud.frauddetection.model.FraudCheck; +import org.springframework.cloud.frauddetection.model.FraudCheckResult; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.math.BigDecimal; -import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.FRAUD; -import static com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus.OK; +import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.FRAUD; +import static org.springframework.cloud.frauddetection.model.FraudCheckStatus.OK; import static org.springframework.web.bind.annotation.RequestMethod.PUT; @RestController diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java similarity index 88% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java index 77471aee19..72551915bc 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; import java.math.BigDecimal; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java similarity index 92% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java index 28efc573f5..95fd5e04c4 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class FraudCheckResult { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b4fd951df2 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package org.springframework.cloud.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy new file mode 100644 index 0000000000..dfff02db5e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy @@ -0,0 +1,31 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud + +import org.springframework.cloud.frauddetection.FraudDetectionController +import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc +import spock.lang.Specification + +class MvcSpec extends Specification { + def setup() { + RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) + } + + void assertThatRejectionReasonIsNull(def rejectionReason) { + assert !rejectionReason + } +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java similarity index 63% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java index 084a65ebf5..8fa2aad6ff 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/com/blogspot/toomuchcoding/MvcTest.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding; +package org.springframework.cloud; import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc; import org.junit.Before; @@ -7,7 +7,7 @@ public class MvcTest { @Before public void setup() { - RestAssuredMockMvc.standaloneSetup(new com.blogspot.toomuchcoding.frauddetection.FraudDetectionController()); + RestAssuredMockMvc.standaloneSetup(new org.springframework.cloud.frauddetection.FraudDetectionController()); } public void assertThatRejectionReasonIsNull(Object rejectionReason) { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..1aa6b34ba4 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,22 @@ +# +# Copyright 2013-2016 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#Wed Jan 28 00:32:44 CET 2015 +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 diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat diff --git a/stub-runner/stub-runner/src/test/resources/emptyrepo/.gitkeep b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep similarity index 100% rename from stub-runner/stub-runner/src/test/resources/emptyrepo/.gitkeep rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 72% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java index 5a1a60244e..bc8131fe49 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -11,7 +11,8 @@ import org.springframework.context.annotation.Configuration; public class Application { public static void main(String[] args) { - SpringApplication.run(Application.class, args); + SpringApplication.run( + org.springframework.cloud.frauddetection.Application.class, args); } } diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java similarity index 79% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java index a2d8ce1e74..65ec787113 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/LoanApplicationService.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java @@ -1,11 +1,11 @@ -package com.blogspot.toomuchcoding.frauddetection; +package org.springframework.cloud.frauddetection; -import com.blogspot.toomuchcoding.frauddetection.model.FraudCheckStatus; -import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceRequest; -import com.blogspot.toomuchcoding.frauddetection.model.FraudServiceResponse; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult; -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus; +import org.springframework.cloud.frauddetection.model.FraudCheckStatus; +import org.springframework.cloud.frauddetection.model.FraudServiceRequest; +import org.springframework.cloud.frauddetection.model.FraudServiceResponse; +import org.springframework.cloud.frauddetection.model.LoanApplication; +import org.springframework.cloud.frauddetection.model.LoanApplicationResult; +import org.springframework.cloud.frauddetection.model.LoanApplicationStatus; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java similarity index 73% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java index 5e91273eda..1a85740dde 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/Client.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class Client { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java new file mode 100644 index 0000000000..b4fd951df2 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java @@ -0,0 +1,5 @@ +package org.springframework.cloud.frauddetection.model; + +public enum FraudCheckStatus { + OK, FRAUD +} diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java similarity index 91% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java index ac595998bc..f79ff3b740 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceRequest.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; import java.math.BigDecimal; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java similarity index 90% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java index 9f3353ecbf..dbf8384a53 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudServiceResponse.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class FraudServiceResponse { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java similarity index 91% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java index 816087988b..58757331d0 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplication.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; import java.math.BigDecimal; diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java similarity index 93% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java index 523f4f2ea3..11c3ee1d2c 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationResult.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public class LoanApplicationResult { diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java similarity index 58% rename from accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java index 7f7f86e0ea..bdb886d0fc 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/LoanApplicationStatus.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java @@ -1,4 +1,4 @@ -package com.blogspot.toomuchcoding.frauddetection.model; +package org.springframework.cloud.frauddetection.model; public enum LoanApplicationStatus { LOAN_APPLIED, LOAN_APPLICATION_REJECTED diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy similarity index 59% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy index 5a7d0ae9a9..eae9a5c817 100644 --- a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/com/blogspot/toomuchcoding/LoanApplicationServiceSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy @@ -1,11 +1,27 @@ -package com.blogspot.toomuchcoding +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import com.blogspot.toomuchcoding.frauddetection.Application -import com.blogspot.toomuchcoding.frauddetection.LoanApplicationService -import com.blogspot.toomuchcoding.frauddetection.model.Client -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplication -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationResult -import com.blogspot.toomuchcoding.frauddetection.model.LoanApplicationStatus +package org.springframework.cloud + +import org.springframework.cloud.frauddetection.Application +import org.springframework.cloud.frauddetection.LoanApplicationService +import org.springframework.cloud.frauddetection.model.Client +import org.springframework.cloud.frauddetection.model.LoanApplication +import org.springframework.cloud.frauddetection.model.LoanApplicationResult +import org.springframework.cloud.frauddetection.model.LoanApplicationStatus import com.github.tomakehurst.wiremock.junit.WireMockClassRule import org.junit.ClassRule import org.springframework.beans.factory.annotation.Autowired diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json diff --git a/accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json similarity index 100% rename from accurest-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle new file mode 100644 index 0000000000..48db488159 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle @@ -0,0 +1,18 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +include ':fraudDetectionService' +include ':loanApplicationService' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/README.adoc new file mode 100644 index 0000000000..2488410263 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/README.adoc @@ -0,0 +1,23 @@ + = Spring Cloud Contract Verifier Messaging + +Spring Cloud Contract Verifier allows you to verify your application that uses messaging as means of communication. +All of our integrations are working with Spring but you can also set one yourself. + +== Integrations + +You can use one of the three integration configurations: + +- Apache Camel +- Spring Integration +- Spring Cloud Stream + +If you're using Spring Boot, the aforementioned test configurations will be appended automatically. + +== Manual Integration + +The `spring-cloud-contract-verifier-messaging-core` module contains 3 main interfaces: + +- `ContractVerifierMessage` - describes a message received / sent to a channel / queue / topic etc. +- `ContractVerifierMessageBuilder` - describes how to build a message +- `ContractVerifierMessaging` - class that allows you to build, send and receive messages + diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle new file mode 100644 index 0000000000..dc27dcd2b2 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String verifier = "spring-cloud-contract-verifier" + +dependencies { + compile project(":$verifier-root:$verifier-messaging-root:$verifier-messaging-core") + compile "org.apache.camel:camel-spring:${camelVersion}" + compile 'org.slf4j:slf4j-api:1.6.0' +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java new file mode 100644 index 0000000000..1d4a94257d --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java @@ -0,0 +1,56 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.camel; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; +import org.apache.camel.Message; + +import java.util.Map; + +/** + * @author Marcin Grzejszczak + */ +public class CamelMessage implements ContractVerifierMessage { + + private final Message delegate; + + public CamelMessage(Message delegate) { + this.delegate = delegate; + } + + @Override + @SuppressWarnings("unchecked") + public T getPayload() { + return (T) delegate.getBody(); + } + + @Override + public Map getHeaders() { + return delegate.getHeaders(); + } + + @Override + public Object getHeader(String key) { + return getHeaders().get(key); + } + + @Override + public Message convert() { + return delegate; + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java new file mode 100644 index 0000000000..71280d4700 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java @@ -0,0 +1,37 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.camel; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging; +import org.apache.camel.CamelContext; +import org.springframework.context.annotation.Bean; + +/** + * @author Marcin Grzejszczak + */ +public class ContractVerifierCamelConfiguration { + + @Bean ContractVerifierMessaging contractVerifierMessaging(CamelContext context, + ContractVerifierMessageBuilder builder) { + return new ContractVerifierCamelMessaging(context, builder); + } + + @Bean ContractVerifierMessageBuilder contractVerifierMessageBuilder() { + return new ContractVerifierCamelMessageBuilder(); + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java new file mode 100644 index 0000000000..77aa4f2c91 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.camel; + +import java.util.Map; + +import org.apache.camel.Message; +import org.apache.camel.impl.DefaultMessage; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; + +/** + * @author Marcin Grzejszczak + */ +public class ContractVerifierCamelMessageBuilder implements + ContractVerifierMessageBuilder { + + @Override + public ContractVerifierMessage create(T payload, Map headers) { + DefaultMessage message = new DefaultMessage(); + message.setBody(payload); + message.setHeaders(headers); + return new CamelMessage<>(message); + } + + @Override + public ContractVerifierMessage create(Message message) { + if (message == null) { + return null; + } + return new CamelMessage<>(message); + } +} diff --git a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java similarity index 51% rename from accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java index 914d962f47..14b0a7db36 100644 --- a/accurest-messaging/accurest-messaging-camel/src/main/java/io/codearte/accurest/messaging/camel/AccurestCamelMessaging.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java @@ -1,4 +1,20 @@ -package io.codearte.accurest.messaging.camel; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.camel; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -12,32 +28,34 @@ import org.apache.camel.impl.DefaultExchange; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging; import org.springframework.stereotype.Component; -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; -import io.codearte.accurest.messaging.AccurestMessaging; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; /** * @author Marcin Grzejszczak */ @Component -public class AccurestCamelMessaging implements AccurestMessaging { +public class ContractVerifierCamelMessaging implements + ContractVerifierMessaging { - private static final Logger log = LoggerFactory.getLogger(AccurestCamelMessaging.class); + private static final Logger log = LoggerFactory.getLogger( + ContractVerifierCamelMessaging.class); private final CamelContext context; - private final AccurestMessageBuilder builder; + private final ContractVerifierMessageBuilder builder; @Autowired @SuppressWarnings("unchecked") - public AccurestCamelMessaging(CamelContext context, AccurestMessageBuilder accurestMessageBuilder) { + public ContractVerifierCamelMessaging(CamelContext context, ContractVerifierMessageBuilder contractVerifierMessageBuilder) { this.context = context; - this.builder = accurestMessageBuilder; + this.builder = contractVerifierMessageBuilder; } @Override - public void send(AccurestMessage message, String destination) { + public void send(ContractVerifierMessage message, String destination) { try { ProducerTemplate producerTemplate = context.createProducerTemplate(); Exchange exchange = new DefaultExchange(context); @@ -58,7 +76,7 @@ public class AccurestCamelMessaging implements AccurestMessaging @Override @SuppressWarnings("unchecked") - public AccurestMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit) { + public ContractVerifierMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit) { try { ConsumerTemplate consumerTemplate = context.createConsumerTemplate(); Exchange exchange = consumerTemplate.receive(destination, timeUnit.toMillis(timeout)); @@ -71,19 +89,19 @@ public class AccurestCamelMessaging implements AccurestMessaging } @Override - public AccurestMessage receiveMessage(String destination) { + public ContractVerifierMessage receiveMessage(String destination) { return receiveMessage(destination, 5, TimeUnit.SECONDS); } @Override @SuppressWarnings("unchecked") - public AccurestMessage create(T t, Map headers) { + public ContractVerifierMessage create(T t, Map headers) { return builder.create(t, headers); } @Override @SuppressWarnings("unchecked") - public AccurestMessage create(Message message) { + public ContractVerifierMessage create(Message message) { return builder.create(message); } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..4515c7bbdb --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.contract.verifier.messaging.camel.ContractVerifierCamelConfiguration diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle new file mode 100644 index 0000000000..b69c26a76c --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle @@ -0,0 +1,34 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +String verifier = "spring-cloud-contract-verifier" + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +dependencies { + compile project(":$verifier-root:$verifier-messaging-root:$verifier-messaging-core") + compile "org.springframework:spring-messaging:${springVersion}" + compile 'org.slf4j:slf4j-api:1.6.0' +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java new file mode 100644 index 0000000000..3f1ddc2c97 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java @@ -0,0 +1,36 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.integration; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; + +/** + * @author Marcin Grzejszczak + */ +public class ContractVerifierIntegrationConfiguration { + + @Bean ContractVerifierMessaging contractVerifierMessaging(ApplicationContext applicationContext, ContractVerifierMessageBuilder contractVerifierMessageBuilder) { + return new ContractVerifierIntegrationMessaging(applicationContext, contractVerifierMessageBuilder); + } + + @Bean ContractVerifierMessageBuilder contractVerifierMessageBuilder() { + return new ContractVerifierIntegrationMessageBuilder(); + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java new file mode 100644 index 0000000000..60f10b1493 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.integration; + +import java.util.Map; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.support.MessageBuilder; + +/** + * @author Marcin Grzejszczak + */ +public class ContractVerifierIntegrationMessageBuilder implements + ContractVerifierMessageBuilder> { + + @Override + public ContractVerifierMessage> create(T payload, Map headers) { + return new IntegrationMessage<>(MessageBuilder.createMessage(payload, new MessageHeaders(headers))); + } + + @Override + public ContractVerifierMessage> create(Message message) { + if (message == null) { + return null; + } + return new IntegrationMessage<>(message); + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java new file mode 100644 index 0000000000..960e07d520 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java @@ -0,0 +1,102 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.integration; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; +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 org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; + +/** + * @author Marcin Grzejszczak + */ +@Component +public class ContractVerifierIntegrationMessaging implements + ContractVerifierMessaging> { + + private static final Logger log = LoggerFactory.getLogger( + ContractVerifierIntegrationMessaging.class); + + private final ApplicationContext context; + private final ContractVerifierMessageBuilder builder; + + @Autowired + @SuppressWarnings("unchecked") + public ContractVerifierIntegrationMessaging(ApplicationContext context, ContractVerifierMessageBuilder contractVerifierMessageBuilder) { + this.context = context; + this.builder = contractVerifierMessageBuilder; + } + + @Override + @SuppressWarnings("unchecked") + public void send(T payload, Map headers, String destination) { + send(builder.create(payload, headers), destination); + } + + @Override + public void send(ContractVerifierMessage> 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 ContractVerifierMessage> 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 ContractVerifierMessage> receiveMessage(String destination) { + return receiveMessage(destination, 5, TimeUnit.SECONDS); + } + + @Override + @SuppressWarnings("unchecked") + public ContractVerifierMessage> create(T t, Map headers) { + return builder.create(t, headers); + } + + @Override + @SuppressWarnings("unchecked") + public ContractVerifierMessage> create(Message message) { + return builder.create(message); + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java new file mode 100644 index 0000000000..b75e92eb69 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.integration; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +/** + * @author Marcin Grzejszczak + */ +public class IntegrationMessage implements ContractVerifierMessage> { + + private final Message delegate; + + public IntegrationMessage(Message 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 convert() { + return delegate; + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..2251d19bd0 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.contract.verifier.messaging.integration.ContractVerifierIntegrationConfiguration diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle new file mode 100644 index 0000000000..068826284e --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle @@ -0,0 +1,24 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + jcenter() +} + +dependencies { + compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0' + compile 'javax.inject:javax.inject:1' +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java new file mode 100644 index 0000000000..3c864f1bee --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java @@ -0,0 +1,30 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging; + +/** + * Contract for filtering out messages that do not match the structure in the Contract DSL + * + * @author Marcin Grzejszczak + */ +public interface ContractVerifierFilter { + + /** + * @return @{code true} if the message should be passed through, @{code false} if the message should be filtered out, + */ + boolean matches(ContractVerifierMessage message); +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java new file mode 100644 index 0000000000..c8510cd526 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.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 ContractVerifierMessage { + + /** + * Returns a payload of type {@code PAYLOAD} + */ + PAYLOAD getPayload(); + + /** + * Returns a map of headers + */ + Map 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(); +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java new file mode 100644 index 0000000000..7325ac29de --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging; + +import java.util.Map; + +/** + * Contract for creation of (@link ContractVerifierMessage}. You can create a message from + * payload and headers or from some type (e.g. Spring Messaging Message). + * + * @author Marcin Grzejszczak + */ +public interface ContractVerifierMessageBuilder { + + /** + * Creates a {@link ContractVerifierMessage} from payload and headers + */ + ContractVerifierMessage create(PAYLOAD payload, Map headers); + + /** + * Creates a {@link ContractVerifierMessage} from the {@code TYPE_TO_CONVERT_INTO} type + */ + ContractVerifierMessage create(TYPE_TO_CONVERT_INTO typeToConvertInto); +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java new file mode 100644 index 0000000000..01c377aa8f --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java @@ -0,0 +1,51 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging; + +import java.util.Map; +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 ContractVerifierMessaging extends + ContractVerifierMessageBuilder { + /** + * Sends the {@link ContractVerifierMessage} to the given destination. + */ + void send(ContractVerifierMessage message, String destination); + + /** + * Sends the given payload with headers, to the given destination. + */ + void send(PAYLOAD payload, Map headers, String destination); + + /** + * Receives the {@link ContractVerifierMessage} from the given destination. You can provide the timeout + * for receiving that message. + */ + ContractVerifierMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit); + + /** + * Receives the {@link ContractVerifierMessage} from the given destination. A default timeout will be applied. + */ + ContractVerifierMessage receiveMessage(String destination); +} diff --git a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessagingUtil.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java similarity index 60% rename from accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessagingUtil.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java index d2749c03ea..18de368aa5 100644 --- a/accurest-messaging/accurest-messaging-core/src/main/java/io/codearte/accurest/messaging/AccurestMessagingUtil.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java @@ -1,4 +1,20 @@ -package io.codearte.accurest.messaging; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging; import java.util.Collection; import java.util.HashMap; @@ -10,17 +26,17 @@ import java.util.Set; * * @author Marcin Grzejszczak */ -public class AccurestMessagingUtil { +public class ContractVerifierMessagingUtil { - public static AccurestHeaders headers() { - return new AccurestHeaders(); + public static ContractVerifierHeaders headers() { + return new ContractVerifierHeaders(); } - public static class AccurestHeaders implements Map { + public static class ContractVerifierHeaders implements Map { private final Map delegate = new HashMap<>(); - public AccurestHeaders header(String key, Object value) { + public ContractVerifierHeaders header(String key, Object value) { put(key, value); return this; } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java new file mode 100644 index 0000000000..dfbdcf461d --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +/** + * Wrapper over {@link ObjectMapper} that won't try to parse + * String but will directly return it. + * + * @author Marcin Grzejszczak + */ +public class ContractVerifierObjectMapper { + + private final ObjectMapper objectMapper; + + public ContractVerifierObjectMapper(ObjectMapper objectMapper) { + this.objectMapper = objectMapper; + } + + public ContractVerifierObjectMapper() { + this.objectMapper = new ObjectMapper(); + } + + public String writeValueAsString(Object payload) throws JsonProcessingException { + if (payload instanceof String) { + return payload.toString(); + } + return objectMapper.writeValueAsString(payload); + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java new file mode 100644 index 0000000000..c7c37514d5 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.noop; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; + +import java.util.Map; + +/** + * @author Marcin Grzejszczak + */ +public class NoOpContractVerifierMessage implements ContractVerifierMessage { + @Override + public Object getPayload() { + return null; + } + + @Override + public Map getHeaders() { + return null; + } + + @Override + public Object getHeader(String key) { + return null; + } + + @Override + public Object convert() { + return null; + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java new file mode 100644 index 0000000000..edd9a3142c --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.noop; + +import java.util.Map; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; + +/** + * @author Marcin Grzejszczak + */ +public class NoOpContractVerifierMessageBuilder + implements ContractVerifierMessageBuilder { + @Override + public ContractVerifierMessage create(Object o, Map headers) { + return new NoOpContractVerifierMessage(); + } + + @Override + public ContractVerifierMessage create(Object o) { + return new NoOpContractVerifierMessage(); + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java new file mode 100644 index 0000000000..da28a92d56 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.noop; + +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging; + +/** + * @author Marcin Grzejszczak + */ +public class NoOpContractVerifierMessaging implements ContractVerifierMessaging { + @Override + public void send(ContractVerifierMessage message, String destination) { + + } + + @Override + public void send(Object payload, Map headers, String destination) { + + } + + @Override + public ContractVerifierMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit) { + return null; + } + + @Override + public ContractVerifierMessage receiveMessage(String destination) { + return null; + } + + @Override + public ContractVerifierMessage create(Object o, Map headers) { + return null; + } + + @Override + public ContractVerifierMessage create(Object o) { + return null; + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle new file mode 100644 index 0000000000..6d894381a3 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +repositories { + mavenLocal() + jcenter() + maven { + url "http://repo.spring.io/snapshot" + } + maven { + url "http://repo.spring.io/milestone" + } +} + +String verifier = "spring-cloud-contract-verifier" + +dependencies { + compile project(":$verifier-root:$verifier-messaging-root:$verifier-messaging-core") + compile "org.springframework.cloud:spring-cloud-stream:${springStreamVersion}" + // for MessageCollector + compile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" +} \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java new file mode 100644 index 0000000000..00d445917d --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java @@ -0,0 +1,38 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.stream; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @author Marcin Grzejszczak + */ +@Configuration +public class ContractVerifierStreamAutoConfiguration { + + @Bean ContractVerifierMessaging contractVerifierMessaging(ApplicationContext applicationContext, ContractVerifierMessageBuilder contractVerifierMessageBuilder) { + return new ContractVerifierStreamMessaging(applicationContext, contractVerifierMessageBuilder); + } + + @Bean ContractVerifierMessageBuilder contractVerifierMessageBuilder() { + return new ContractVerifierStreamMessageBuilder(); + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java new file mode 100644 index 0000000000..90270657b4 --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.stream; + +import java.util.Map; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; +import org.springframework.messaging.support.MessageBuilder; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; + +/** + * @author Marcin Grzejszczak + */ +public class ContractVerifierStreamMessageBuilder implements + ContractVerifierMessageBuilder> { + + @Override + public ContractVerifierMessage> create(T payload, Map headers) { + return new StreamMessage<>(MessageBuilder.createMessage(payload, new MessageHeaders(headers))); + } + + @Override + public ContractVerifierMessage> create(Message message) { + if (message == null) { + return null; + } + return new StreamMessage<>(message); + } +} diff --git a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java similarity index 60% rename from accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java index 4fd456e637..3b885a4801 100644 --- a/accurest-messaging/accurest-messaging-stream/src/main/java/io/codearte/accurest/messaging/stream/AccurestStreamMessaging.java +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java @@ -1,8 +1,24 @@ -package io.codearte.accurest.messaging.stream; +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ -import io.codearte.accurest.messaging.AccurestMessage; -import io.codearte.accurest.messaging.AccurestMessageBuilder; -import io.codearte.accurest.messaging.AccurestMessaging; +package org.springframework.cloud.contract.verifier.messaging.stream; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessageBuilder; +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -19,17 +35,18 @@ import java.util.concurrent.TimeUnit; /** * @author Marcin Grzejszczak */ -public class AccurestStreamMessaging implements AccurestMessaging> { +public class ContractVerifierStreamMessaging implements + ContractVerifierMessaging> { - private static final Logger log = LoggerFactory.getLogger(AccurestStreamMessaging.class); + private static final Logger log = LoggerFactory.getLogger(ContractVerifierStreamMessaging.class); private final ApplicationContext context; private final MessageCollector messageCollector; - private final AccurestMessageBuilder builder; + private final ContractVerifierMessageBuilder builder; @Autowired @SuppressWarnings("unchecked") - public AccurestStreamMessaging(ApplicationContext context, AccurestMessageBuilder builder) { + public ContractVerifierStreamMessaging(ApplicationContext context, ContractVerifierMessageBuilder builder) { this.context = context; this.messageCollector = context.getBean(MessageCollector.class); this.builder = builder; @@ -42,7 +59,7 @@ public class AccurestStreamMessaging implements AccurestMessaging> message, String destination) { + public void send(ContractVerifierMessage> message, String destination) { try { MessageChannel messageChannel = context.getBean(resolvedDestination(destination), MessageChannel.class); messageChannel.send(message.convert()); @@ -55,7 +72,7 @@ public class AccurestStreamMessaging implements AccurestMessaging> receiveMessage(String destination, long timeout, TimeUnit timeUnit) { + public ContractVerifierMessage> receiveMessage(String destination, long timeout, TimeUnit timeUnit) { try { MessageChannel messageChannel = context.getBean(resolvedDestination(destination), MessageChannel.class); return builder.create(messageCollector.forChannel(messageChannel).poll(timeout, timeUnit)); @@ -80,19 +97,19 @@ public class AccurestStreamMessaging implements AccurestMessaging> receiveMessage(String destination) { + public ContractVerifierMessage> receiveMessage(String destination) { return receiveMessage(destination, 5, TimeUnit.SECONDS); } @Override @SuppressWarnings("unchecked") - public AccurestMessage> create(T t, Map headers) { + public ContractVerifierMessage> create(T t, Map headers) { return builder.create(t, headers); } @Override @SuppressWarnings("unchecked") - public AccurestMessage> create(Message message) { + public ContractVerifierMessage> create(Message message) { return builder.create(message); } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java new file mode 100644 index 0000000000..7582daf46a --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java @@ -0,0 +1,54 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.messaging.stream; + +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage; +import org.springframework.messaging.Message; +import org.springframework.messaging.MessageHeaders; + +/** + * @author Marcin Grzejszczak + */ +public class StreamMessage implements ContractVerifierMessage> { + + private final Message delegate; + + public StreamMessage(Message 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 convert() { + return delegate; + } + +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..6b6e2b930d --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories @@ -0,0 +1,3 @@ +# Auto Configuration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +org.springframework.cloud.contract.verifier.messaging.stream.ContractVerifierStreamAutoConfiguration diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy new file mode 100644 index 0000000000..8b23a3473c --- /dev/null +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy @@ -0,0 +1,28 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.verifier.util + +import org.skyscreamer.jsonassert.JSONAssert + +class AssertionUtil { + + private static boolean NON_STRICT = false + + public static void assertThatJsonsAreEqual(String expected, String actual) { + JSONAssert.assertEquals(expected, actual, NON_STRICT) + } +} diff --git a/stub-runner/stub-runner-boot/build.gradle b/stub-runner/stub-runner-boot/build.gradle deleted file mode 100644 index a10236151b..0000000000 --- a/stub-runner/stub-runner-boot/build.gradle +++ /dev/null @@ -1,22 +0,0 @@ -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - -dependencies { - compile project(':stub-runner-root:stub-runner-spring') - compile "org.springframework.boot:spring-boot-starter-web:${springBootVersion}" - - testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - testCompile project(':stub-runner-root:stub-runner-messaging-root:stub-runner-messaging-stream') - testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } -} \ No newline at end of file diff --git a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBoot.groovy b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBoot.groovy deleted file mode 100644 index d3ec34a69e..0000000000 --- a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerBoot.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package io.codearte.accurest.stubrunner.boot - -import org.springframework.boot.SpringApplication -import org.springframework.boot.autoconfigure.SpringBootApplication - -/** - * @author Marcin Grzejszczak - */ -@SpringBootApplication -class StubRunnerBoot { - - static void main(String[] args) { - SpringApplication.run(StubRunnerBoot.class, args); - } -} diff --git a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerConfig.groovy b/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerConfig.groovy deleted file mode 100644 index d0352a2624..0000000000 --- a/stub-runner/stub-runner-boot/src/main/groovy/io/codearte/accurest/stubrunner/boot/StubRunnerConfig.groovy +++ /dev/null @@ -1,28 +0,0 @@ -package io.codearte.accurest.stubrunner.boot - -import io.codearte.accurest.messaging.AccurestMessageBuilder -import io.codearte.accurest.messaging.AccurestMessaging -import io.codearte.accurest.messaging.noop.NoOpAccurestMessageBuilder -import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -/** - * @author Marcin Grzejszczak - */ -@Configuration -class StubRunnerConfig { - - @Bean - @ConditionalOnMissingBean - AccurestMessaging noOpAccurestMessaging() { - return new NoOpAccurestMessaging() - } - - @Bean - @ConditionalOnMissingBean - AccurestMessageBuilder noOpAccurestMessageBuilder() { - return new NoOpAccurestMessageBuilder() - } -} diff --git a/stub-runner/stub-runner-boot/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-boot/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 1f6ec12f3e..0000000000 --- a/stub-runner/stub-runner-boot/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration diff --git a/stub-runner/stub-runner-boot/src/test/resources/application.yml b/stub-runner/stub-runner-boot/src/test/resources/application.yml deleted file mode 100644 index 154bfe1b6a..0000000000 --- a/stub-runner/stub-runner-boot/src/test/resources/application.yml +++ /dev/null @@ -1,2 +0,0 @@ -stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService \ No newline at end of file diff --git a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar deleted file mode 100644 index 86c61d52ec4b9571f84240dc880daa2e9e5f5b71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1746 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJwREYr^0ql^9WtID{d1|?MEQiV35J8Cn-Na zJ1DiJv?wn%#ZWK3C_lffGBkvffjM}xRJbn?msW5yFtWU0W?%plroF!0O%4JM=U=an z*mH(UwdCzI5m~3!4|=PuXZ|qUxSLJs-}kb$dB%Ip^P{@5gEY1tjkxx8$;BHHGwt?e zE&5(lc3HvtiT8o3$i(xGi|2lc2y=<8Y-rf}ID6AP7961ES=3gdP0N#N2%2wI|U9La*jX!q(RaC(+5Y9PgfcBZ3DHgq-FmR zWAvPN|JzN?y$AZ5FPj&CoqwGl6n~H~i2{bnd$}npyMf_h#YkM37$JvA3@|)GF~g*_ z*B=xnN6)`r{=tmx>B8jgi|PelEsbtjW3_b0>l5#!Jbv6Q4qw6NXwW{>{Qcf|*F-7kF%T)__5$Z$tq9dMOLv*$5$!1-ViU9XS-^z{K3m zw=Nygy&0l$souP^NlvURE&cwNCDBG4b_?3J&9y1I(6;to<)Y^?$Il*Yc)D6ZOlr$g zlMKTLTNR~J6n`DJXe|-toB6OW+TX9%dDE|-(ng!D+;v^5Y#R=jYUaBLD(Tf9v~6-c zKT~s;&Xkmb#jZQGo*qB>M3v8AG5>MCrb(UEOzVob2ZnO#9{t3I$lzLNB>`GS%S|jO z$jnPG24^%zCJ|=bXL*rE(CSWgY zSRsWCT0w(s8)n8uw(TX*Qf%%;whfVufwqCNF&^76a{{t$Y`~Hbmu=|z0%#W~UtqBd omUghEIB-A$)6QQ - - 4.0.0 - io.codearte.accurest.stubs - streamService - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml b/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml deleted file mode 100644 index dc32790f53..0000000000 --- a/stub-runner/stub-runner-boot/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - streamService - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-junit/build.gradle b/stub-runner/stub-runner-junit/build.gradle deleted file mode 100644 index bd9a36bfe0..0000000000 --- a/stub-runner/stub-runner-junit/build.gradle +++ /dev/null @@ -1,17 +0,0 @@ -description = 'JUnit rule for stub-runner' - -dependencies { - compile project(':stub-runner-root:stub-runner') - - compile localGroovy() - compile 'junit:junit:4.12' - - testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } - testCompile 'cglib:cglib-nodep:2.2' - testCompile 'org.objenesis:objenesis:2.1' - testCompile 'ch.qos.logback:logback-classic:1.1.3' - testCompile 'org.assertj:assertj-core:2.3.0' - testCompile 'org.apache.commons:commons-io:1.3.2' -} diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java deleted file mode 100644 index ef05510e74..0000000000 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleCustomPortJUnitTest.java +++ /dev/null @@ -1,68 +0,0 @@ -package io.codearte.accurest.stubrunner.junit; - -import java.io.InputStream; -import java.net.URI; - -import org.apache.commons.io.IOUtils; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Marcin Grzejszczak - */ -public class AccurestRuleCustomPortJUnitTest { - - @BeforeClass - @AfterClass - public static void setupProps() { - System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); - System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); - } - - // tag::classrule_with_port[] - @ClassRule public static AccurestRule rule = new AccurestRule() - .repoRoot(repoRoot()) - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .withPort(12345) - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:12346"); - // end::classrule_with_port[] - - @Test - public void should_start_wiremock_servers() throws Exception { - // expect: 'WireMocks are running' - then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")); - then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull(); - // and: - then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue(); - // and: 'Stubs were registered' - then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); - then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); - // and: 'The port is fixed' - // tag::test_with_port[] - then(rule.findStubUrl("loanIssuance")).isEqualTo(URI.create("http://localhost:12345").toURL()); - then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL()); - // end::test_with_port[] - } - - private static String repoRoot() { - try { - return AccurestRuleCustomPortJUnitTest.class.getResource("/m2repo/repository/").toURI().toString(); - } catch (Exception e) { - return ""; - } - } - - private String httpGet(String url) throws Exception { - try(InputStream stream = URI.create(url).toURL().openStream()) { - return IOUtils.toString(stream); - } - } -} diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java deleted file mode 100644 index 407c78f781..0000000000 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleJUnitTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package io.codearte.accurest.stubrunner.junit; - -import java.io.InputStream; -import java.net.URI; - -import org.apache.commons.io.IOUtils; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.ClassRule; -import org.junit.Test; - -import static org.assertj.core.api.BDDAssertions.then; - -/** - * @author Marcin Grzejszczak - */ -public class AccurestRuleJUnitTest { - - @BeforeClass - @AfterClass - public static void setupProps() { - System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); - System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); - } - - // tag::classrule[] - @ClassRule public static AccurestRule rule = new AccurestRule() - .repoRoot(repoRoot()) - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer"); - // end::classrule[] - - // tag::test[] - @Test - public void should_start_wiremock_servers() throws Exception { - // expect: 'WireMocks are running' - then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isNotNull(); - then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")); - then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull(); - // and: - then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue(); - then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue(); - // and: 'Stubs were registered' - then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance"); - then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); - } - // end::test[] - - private static String repoRoot() { - try { - return AccurestRuleJUnitTest.class.getResource("/m2repo/repository/").toURI().toString(); - } catch (Exception e) { - return ""; - } - } - - private String httpGet(String url) throws Exception { - try(InputStream stream = URI.create(url).toURL().openStream()) { - return IOUtils.toString(stream); - } - } -} diff --git a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy b/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy deleted file mode 100644 index 7b5ee643fd..0000000000 --- a/stub-runner/stub-runner-junit/src/test/groovy/io/codearte/accurest/stubrunner/junit/AccurestRuleSpec.groovy +++ /dev/null @@ -1,42 +0,0 @@ -package io.codearte.accurest.stubrunner.junit - -import org.junit.AfterClass -import org.junit.BeforeClass -import org.junit.ClassRule -import spock.lang.Shared -import spock.lang.Specification - -/** - * @author Marcin Grzejszczak - */ -class AccurestRuleSpec extends Specification { - - @BeforeClass - @AfterClass - void setupProps() { - System.getProperties().setProperty("stubrunner.stubs.repository.root", ""); - System.getProperties().setProperty("stubrunner.stubs.classifier", "stubs"); - } - - // tag::classrule[] - @ClassRule @Shared AccurestRule rule = new AccurestRule() - .repoRoot(AccurestRuleSpec.getResource("/m2repo/repository").toURI().toString()) - .downloadStub("io.codearte.accurest.stubs", "loanIssuance") - .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer") - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - rule.findStubUrl('loanIssuance') != null - rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null - and: - rule.findAllRunningStubs().isPresent('loanIssuance') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' - } - // end::classrule[] -} diff --git a/stub-runner/stub-runner-junit/src/test/resources/logback.xml b/stub-runner/stub-runner-junit/src/test/resources/logback.xml deleted file mode 100644 index 0cfb35f4cd..0000000000 --- a/stub-runner/stub-runner-junit/src/test/resources/logback.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - \ No newline at end of file diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom deleted file mode 100644 index 9f04720f7d..0000000000 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml deleted file mode 100644 index d4ab9afc83..0000000000 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom deleted file mode 100644 index 9185d4bc8f..0000000000 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml b/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml deleted file mode 100644 index bf14a1ad21..0000000000 --- a/stub-runner/stub-runner-junit/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062111 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle deleted file mode 100644 index 0c284fdd5b..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/build.gradle +++ /dev/null @@ -1,26 +0,0 @@ -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - -dependencies { - compile project(':stub-runner-root:stub-runner-spring') - compile project(':accurest-messaging-root:accurest-messaging-camel') - compile "org.apache.camel:camel-spring-boot-starter:${camelVersion}" - compile "org.apache.camel:camel-jackson:${camelVersion}" - - testCompile "org.springframework:spring-beans:${springVersion}" - testCompile "org.apache.camel:camel-jms:${camelVersion}" - testCompile 'org.apache.activemq:activemq-camel:5.12.1' - testCompile 'org.apache.activemq:activemq-pool:5.12.1' - testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } -} \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy deleted file mode 100644 index a00e1d6c85..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy +++ /dev/null @@ -1,35 +0,0 @@ -package io.codearte.accurest.stubrunner.messaging.camel - -import io.codearte.accurest.dsl.GroovyDsl -import io.codearte.accurest.stubrunner.BatchStubRunner -import io.codearte.accurest.stubrunner.StubConfiguration -import org.apache.camel.RoutesBuilder -import org.apache.camel.spring.SpringRouteBuilder -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration - -/** - * Camel configuration that iterates over the downloaded Groovy DSLs - * and registers a route for each DSL. - * - * @author Marcin Grzejszczak - */ -@Configuration -class StubRunnerCamelConfiguration { - - @Bean - RoutesBuilder myRouter(BatchStubRunner batchStubRunner) { - return new SpringRouteBuilder() { - @Override - public void configure() throws Exception { - Map> accurestContracts = batchStubRunner.accurestContracts - (accurestContracts.values().flatten() as Collection).findAll { it?.input?.messageFrom?.clientValue && it?.outputMessage?.sentTo }.each { - from(it.input.messageFrom.clientValue) - .filter(new StubRunnerCamelPredicate(it)) - .process(new StubRunnerCamelProcessor(it)) - .to(it.outputMessage.sentTo.clientValue) - } - } - }; - } -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy deleted file mode 100644 index 87b2f8590e..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/main/groovy/io/codearte/accurest/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy +++ /dev/null @@ -1,36 +0,0 @@ -package io.codearte.accurest.stubrunner.messaging.camel - -import groovy.transform.PackageScope -import io.codearte.accurest.builder.BodyAsString -import io.codearte.accurest.dsl.GroovyDsl -import org.apache.camel.Exchange -import org.apache.camel.Message -import org.apache.camel.Processor - -/** - * Sends forward a message defined in the DSL. Also removes headers from the - * input message and provides the headers from the DSL. - * - * @author Marcin Grzejszczak - */ -@PackageScope -class StubRunnerCamelProcessor implements Processor { - - private final GroovyDsl groovyDsl - - StubRunnerCamelProcessor(GroovyDsl groovyDsl) { - this.groovyDsl = groovyDsl - } - - @Override - void process(Exchange exchange) throws Exception { - Message input = exchange.in - input.body = BodyAsString.extractClientValueFrom(groovyDsl.outputMessage.body) - groovyDsl.input.messageHeaders.entries.each { - input.removeHeader(it.name) - } - groovyDsl.outputMessage.headers.entries.each { - input.setHeader(it.name, it.clientValue) - } - } -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/BookReturned.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/BookReturned.groovy deleted file mode 100644 index b6523d2e5c..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/groovy/io/codearte/accurest/stubrunner/messaging/camel/BookReturned.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package io.codearte.accurest.stubrunner.messaging.camel - -import com.fasterxml.jackson.annotation.JsonCreator -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode - -@CompileStatic -@EqualsAndHashCode -class BookReturned implements Serializable { - final String bookName - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - BookReturned(String bookName) { - this.bookName = bookName - } -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/application.yml b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/application.yml deleted file mode 100644 index 6fadb526ec..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/application.yml +++ /dev/null @@ -1,2 +0,0 @@ -stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:camelService \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar deleted file mode 100644 index 17df8f09aba8807877246768aa758e8d3b85ff94..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1754 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJwREYr;41Xc~mea@@)mG{R+ey3^G{tB<1I4 z2c?#j7UiX;80w`L<>!}GhK6u5Fh?Ab3_lPm8D3h!&A`a=f|-Ef1c;&(5BzWANxS;> zx?b4Me`C_Y_w&)lxR4vg0U2th(?kQqax-B)Oz3*OEoWQH4(JgDNmcF#w)bDWU|GjryR~0#)85rN+d~Cx3 zp&0=Jn-*PQTEgXhv#q-EhlE+$<28)`UrwC%^un)@hD(c17adWH4(h)WyMF3XPIk?k zyk$(44)0^!_!e#E-*T*oc~Bd>&yDSmn>dhy4E)8Zc)*03nf)m?cC)53mji?6IS{MiNi{C1IjJS7Dae823k;kcn1SQldzR~v0nhRCcZ1(d<6FYNVKL9w zC!QY^lx|AhjmdVq%<25?-MhyN+8zGM|6H0Fyit{BB2QSTyvL%AkIvW`>~BxHWwUKc zozT+_D$|=(-6!U$7ISxI#l^}$52+M7$o`h8n%7_dXH?6Z>A5%gei>yhefC+o>QwL! zV}FIxzuIyfx~!2qR>ifjIo`Ky^5t5+dBX9`fEFj4s}iPX?ihP*{Ikt!ws*2o9U~&6 zYoV10Xc;ayv7jI`FTEI?;TV}jm~odQz%T>?0fx7ZAR1n(1bCxrLoZc8ia}sWqb87q zYeOny&`kiTh819-q67j282&nz0hvgp1wM@+e?kCA<3b=4Nh7?N0hu7jjH{TD02=_z zS_}=1S8-0|Nlz(iyk_ diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom deleted file mode 100644 index 4e8bab7de0..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - camelService - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index f8f49e32bb..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - camelService - 0.0.1-SNAPSHOT - - - true - - 20160409062112 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata-local.xml deleted file mode 100644 index e71db595a7..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - camelService - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata.xml deleted file mode 100644 index e71db595a7..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-camel/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/camelService/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - camelService - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle deleted file mode 100644 index f8b8a8277d..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/build.gradle +++ /dev/null @@ -1,23 +0,0 @@ -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - -dependencies { - compile project(':stub-runner-root:stub-runner-spring') - compile project(':accurest-messaging-root:accurest-messaging-integration') - compile "org.springframework.integration:spring-integration-java-dsl:${springIntegrationDslVersion}" - compile 'com.fasterxml.jackson.core:jackson-databind:2.7.0' - - testCompile "org.springframework.boot:spring-boot-starter-integration:${springBootVersion}" - testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } -} \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy deleted file mode 100644 index 2bb6fa19ca..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/groovy/io/codearte/accurest/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package io.codearte.accurest.stubrunner.messaging.integration - -import io.codearte.accurest.builder.BodyAsString -import io.codearte.accurest.dsl.GroovyDsl -import org.springframework.integration.transformer.GenericTransformer -import org.springframework.messaging.Message -import org.springframework.messaging.MessageHeaders -import org.springframework.messaging.support.MessageBuilder - -/** - * Sends forward a message defined in the DSL. - * - * @author Marcin Grzejszczak - */ -class StubRunnerIntegrationTransformer implements GenericTransformer, Message> { - - private final GroovyDsl groovyDsl - - StubRunnerIntegrationTransformer(GroovyDsl groovyDsl) { - this.groovyDsl = groovyDsl - } - - @Override - Message transform(Message source) { - if (!groovyDsl.outputMessage) { - return source - } - String payload = BodyAsString.extractClientValueFrom(groovyDsl.outputMessage.body) - Map headers = groovyDsl.outputMessage.headers.asStubSideMap() - return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) - } -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/resources/META-INF/spring.factories deleted file mode 100644 index dfd989c8bc..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.stubrunner.messaging.integration.StubRunnerIntegrationConfiguration diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/BookReturned.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/BookReturned.groovy deleted file mode 100644 index c5826c848d..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/groovy/io/codearte/accurest/stubrunner/messaging/integration/BookReturned.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package io.codearte.accurest.stubrunner.messaging.integration - -import com.fasterxml.jackson.annotation.JsonCreator -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode - -@CompileStatic -@EqualsAndHashCode -class BookReturned implements Serializable { - final String bookName - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - BookReturned(String bookName) { - this.bookName = bookName - } -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml deleted file mode 100644 index 3bec94b4b9..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/application.yml +++ /dev/null @@ -1,2 +0,0 @@ -stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:integrationService:0.0.1-SNAPSHOT \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar deleted file mode 100644 index 86c61d52ec4b9571f84240dc880daa2e9e5f5b71..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1746 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJwREYr^0ql^9WtID{d1|?MEQiV35J8Cn-Na zJ1DiJv?wn%#ZWK3C_lffGBkvffjM}xRJbn?msW5yFtWU0W?%plroF!0O%4JM=U=an z*mH(UwdCzI5m~3!4|=PuXZ|qUxSLJs-}kb$dB%Ip^P{@5gEY1tjkxx8$;BHHGwt?e zE&5(lc3HvtiT8o3$i(xGi|2lc2y=<8Y-rf}ID6AP7961ES=3gdP0N#N2%2wI|U9La*jX!q(RaC(+5Y9PgfcBZ3DHgq-FmR zWAvPN|JzN?y$AZ5FPj&CoqwGl6n~H~i2{bnd$}npyMf_h#YkM37$JvA3@|)GF~g*_ z*B=xnN6)`r{=tmx>B8jgi|PelEsbtjW3_b0>l5#!Jbv6Q4qw6NXwW{>{Qcf|*F-7kF%T)__5$Z$tq9dMOLv*$5$!1-ViU9XS-^z{K3m zw=Nygy&0l$souP^NlvURE&cwNCDBG4b_?3J&9y1I(6;to<)Y^?$Il*Yc)D6ZOlr$g zlMKTLTNR~J6n`DJXe|-toB6OW+TX9%dDE|-(ng!D+;v^5Y#R=jYUaBLD(Tf9v~6-c zKT~s;&Xkmb#jZQGo*qB>M3v8AG5>MCrb(UEOzVob2ZnO#9{t3I$lzLNB>`GS%S|jO z$jnPG24^%zCJ|=bXL*rE(CSWgY zSRsWCT0w(s8)n8uw(TX*Qf%%;whfVufwqCNF&^76a{{t$Y`~Hbmu=|z0%#W~UtqBd omUghEIB-A$)6QQ - - 4.0.0 - io.codearte.accurest.stubs - integrationService - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index 20ba9761d8..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - integrationService - 0.0.1-SNAPSHOT - - - true - - 20160409062112 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata-local.xml deleted file mode 100644 index b93b655f1f..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - integrationService - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata.xml deleted file mode 100644 index b93b655f1f..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-integration/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/integrationService/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - integrationService - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle deleted file mode 100644 index b03e790ea4..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/build.gradle +++ /dev/null @@ -1,24 +0,0 @@ -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - -dependencies { - compile project(':stub-runner-root:stub-runner-spring') - compile project(':accurest-messaging-root:accurest-messaging-stream') - compile "org.springframework.integration:spring-integration-java-dsl:${springIntegrationDslVersion}" - - testCompile "org.springframework:spring-context:${springVersion}" - testCompile "org.springframework:spring-beans:${springVersion}" - testCompile "org.springframework.cloud:spring-cloud-stream-test-support:${springStreamVersion}" - testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } -} \ No newline at end of file diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy deleted file mode 100644 index c8e61b665f..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/groovy/io/codearte/accurest/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy +++ /dev/null @@ -1,32 +0,0 @@ -package io.codearte.accurest.stubrunner.messaging.stream - -import io.codearte.accurest.builder.BodyAsString -import io.codearte.accurest.dsl.GroovyDsl -import org.springframework.integration.transformer.GenericTransformer -import org.springframework.messaging.Message -import org.springframework.messaging.MessageHeaders -import org.springframework.messaging.support.MessageBuilder - -/** - * Sends forward a message defined in the DSL. - * - * @author Marcin Grzejszczak - */ -class StubRunnerStreamTransformer implements GenericTransformer, Message> { - - private final GroovyDsl groovyDsl - - StubRunnerStreamTransformer(GroovyDsl groovyDsl) { - this.groovyDsl = groovyDsl - } - - @Override - Message transform(Message source) { - if (!groovyDsl.outputMessage) { - return source - } - String payload = BodyAsString.extractClientValueFrom(groovyDsl.outputMessage.body) - Map headers = groovyDsl.outputMessage.headers.asStubSideMap() - return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) - } -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 7b69d1b85a..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.stubrunner.messaging.stream.StubRunnerStreamConfiguration diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/BookReturned.groovy b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/BookReturned.groovy deleted file mode 100644 index 0dd3ca4216..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/groovy/io/codearte/accurest/stubrunner/messaging/stream/BookReturned.groovy +++ /dev/null @@ -1,16 +0,0 @@ -package io.codearte.accurest.stubrunner.messaging.stream - -import com.fasterxml.jackson.annotation.JsonCreator -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode - -@CompileStatic -@EqualsAndHashCode -class BookReturned implements Serializable { - final String bookName - - @JsonCreator(mode = JsonCreator.Mode.PROPERTIES) - BookReturned(String bookName) { - this.bookName = bookName - } -} diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml deleted file mode 100644 index bad844ba2a..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - streamService - 0.0.1-SNAPSHOT - - - true - - 20160409062112 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar deleted file mode 100644 index 79d37267a7ee83102cfdc309ae5a55aa0f550b44..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1756 zcmWIWW@h1HVBp|j&|{wF!2kqIAOZ+Df!NnI#8KDN&rP41Apk|;rh2A#(m(~0KrDi+ z(AUw=)6F$FM9W7$;qWfsl_EwJs?>Q2GO`V9`iT)9^C@ueFb6-1{th+lJfJj zgHlUMi}F%a4E55B^7G3oLqj+jn5*t6hL;0zX$3a}Bg=P21_l<8$)>%w+|3384$psR zH=TCPXkB+#OINmw>uBtvolzejdkJwX{rj$#wB7pN?sDCurkYc3CF#7bx|ET##z+3X z>BaJWyD}%peo{@?yJo}l1sDCQbhH<(vvE9d>!Wex`I%R9FE4PLdWOlSK2K}aBYqc_ zzysGBE~eZK?K*ZMt=qVHv98CPpGRV=r-m+x;YoP7P(Q8cz=ZjgKa{wBzG|3$PeU|o zbLlr%he^--lgm8w3m!c9ayI7g_pj`r7=(n1G%!@WybbOh2KvMW=p|x8#Rxf6T7e-_ zgBdEVey6z(83@=ckG~kLmBBB!H?pR2i|q?vmrG?^mwIkjSsAe8f8M07DuEW;H|Nfr z^Jz`&V>MW*m{NJqGr&qmgnzrx$9wC~s73JpJFGk>^+2tbWBI0?DIH%^{cM9wbC>J- zvuGU6+b~gsDeGsmTPB0m&k2HJwFO4zieVEC7`f-i3HAzG)^nC0;F@qsa`Giv#!#Ov zGB2(ySAH~y{XAdUtuGzN)4wlWaM7J7u2p&RvnMz2vprq^Lc{m_<`l{Gxw}I5FK$mkqEg&YfWvNMq;e)M;QYnhRj$5>ri1N*R*ca{ZSL?j#*H3Aq z%~tNZE>*S-hf6i{T?Cc%>JQpBIi8=Xxl3nCO2J~+omx+ipM0XqXRw(6IA7DG&T6K0 z#oGfzxpa?yVnbwgEwnNLlzfn~TyA1PL1tchF*wUHGKnzbE=hnIfk1%ats{trmn#9@ zsM^rW6_8>OSkkBoB;neSN*Qz$K&oLy7^pCT00D--j%7e5lH>7d1o;yJKpGbUnMfMp z1r5jqIc7+f!YpVczy<(w7ehniRU9T@FLqcV#SU7LgKQgS21d5+HPBLQ?nSl@k)46I zfwD6$+py*YWZMLQsT!AU==lO@7bst# - - 4.0.0 - io.codearte.accurest.stubs - streamService - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml deleted file mode 100644 index dc32790f53..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata-local.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - streamService - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml b/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml deleted file mode 100644 index dc32790f53..0000000000 --- a/stub-runner/stub-runner-messaging/stub-runner-messaging-stream/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/streamService/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - streamService - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 60fb0401e6..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,4 +0,0 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.stubrunner.spring.cloud.StubRunnerSpringCloudAutoConfiguration,\ -io.codearte.accurest.stubrunner.spring.cloud.ribbon.StubRunnerRibbonAutoConfiguration diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml deleted file mode 100644 index 0cfb35f4cd..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/logback.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - \ No newline at end of file diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom deleted file mode 100644 index 9f04720f7d..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml deleted file mode 100644 index d4ab9afc83..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom deleted file mode 100644 index 9185d4bc8f..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml b/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml deleted file mode 100644 index bf14a1ad21..0000000000 --- a/stub-runner/stub-runner-spring-cloud/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062111 - - diff --git a/stub-runner/stub-runner-spring/build.gradle b/stub-runner/stub-runner-spring/build.gradle deleted file mode 100644 index acb0432826..0000000000 --- a/stub-runner/stub-runner-spring/build.gradle +++ /dev/null @@ -1,20 +0,0 @@ -description = 'Spring configuration for stub-runner' - -dependencies { - compile project(':stub-runner-root:stub-runner') - - compile localGroovy() - compile "org.springframework:spring-context:${springVersion}" - - testCompile('org.spockframework:spock-core:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } - testCompile 'cglib:cglib-nodep:2.2' - testCompile 'org.objenesis:objenesis:2.1' - testCompile "org.springframework.boot:spring-boot-starter:${springBootVersion}" - testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" - testCompile('org.spockframework:spock-spring:1.0-groovy-2.4') { - exclude(group: 'org.codehaus.groovy') - } - testCompile 'ch.qos.logback:logback-classic:1.1.3' -} diff --git a/stub-runner/stub-runner-spring/src/main/resources/META-INF/spring.factories b/stub-runner/stub-runner-spring/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 24ddd934bf..0000000000 --- a/stub-runner/stub-runner-spring/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# Auto Configuration -org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ -io.codearte.accurest.stubrunner.spring.StubRunnerConfiguration \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy b/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy deleted file mode 100644 index a6800015b6..0000000000 --- a/stub-runner/stub-runner-spring/src/test/groovy/io/codearte/accurest/stubrunner/spring/StubRunnerConfigurationSpec.groovy +++ /dev/null @@ -1,41 +0,0 @@ -package io.codearte.accurest.stubrunner.spring - -import io.codearte.accurest.stubrunner.StubFinder -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.boot.autoconfigure.EnableAutoConfiguration -import org.springframework.boot.test.SpringApplicationContextLoader -import org.springframework.context.annotation.Configuration -import org.springframework.context.annotation.Import -import org.springframework.test.context.ContextConfiguration -import spock.lang.Specification - -/** - * @author Marcin Grzejszczak - */ -// tag::test[] -@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader) -class StubRunnerConfigurationSpec extends Specification { - - @Autowired StubFinder stubFinder - - def 'should start WireMock servers'() { - expect: 'WireMocks are running' - stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') != null - stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') - stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null - and: - stubFinder.findAllRunningStubs().isPresent('loanIssuance') - stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer') - stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer') - and: 'Stubs were registered' - "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance' - "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer' - } - - @Configuration - @Import(StubRunnerConfiguration) - @EnableAutoConfiguration - static class Config {} -} -// end::test[] \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/src/test/resources/application.yml b/stub-runner/stub-runner-spring/src/test/resources/application.yml deleted file mode 100644 index 25ca710cb7..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/application.yml +++ /dev/null @@ -1,2 +0,0 @@ -stubrunner.stubs.repository.root: classpath:m2repo/repository/ -stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/src/test/resources/logback.xml b/stub-runner/stub-runner-spring/src/test/resources/logback.xml deleted file mode 100644 index 0cfb35f4cd..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/logback.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - \ No newline at end of file diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom deleted file mode 100644 index 9f04720f7d..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml deleted file mode 100644 index d4ab9afc83..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/fraudDetectionServer/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - fraudDetectionServer - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062112 - - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom deleted file mode 100644 index 9185d4bc8f..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom +++ /dev/null @@ -1,9 +0,0 @@ - - - 4.0.0 - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - pom - diff --git a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml b/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml deleted file mode 100644 index bf14a1ad21..0000000000 --- a/stub-runner/stub-runner-spring/src/test/resources/m2repo/repository/io/codearte/accurest/stubs/loanIssuance/maven-metadata.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - io.codearte.accurest.stubs - loanIssuance - 0.0.1-SNAPSHOT - - - 0.0.1-SNAPSHOT - - 20160409062111 - - diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/Arguments.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/Arguments.groovy deleted file mode 100644 index cccf0f91aa..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/Arguments.groovy +++ /dev/null @@ -1,27 +0,0 @@ -package io.codearte.accurest.stubrunner - -import groovy.transform.CompileStatic -import groovy.transform.PackageScope -import groovy.transform.ToString - -/** - * Arguments passed to the {@link StubRunner} application - * - * @see StubRunner - */ -@CompileStatic -@ToString(includeNames = true) -@PackageScope -class Arguments { - final StubRunnerOptions stubRunnerOptions - final String context - final String repositoryPath - final StubConfiguration stub - - Arguments(StubRunnerOptions stubRunnerOptions, String repositoryPath = "", StubConfiguration stub = null) { - this.stubRunnerOptions = stubRunnerOptions - this.context = context - this.repositoryPath = repositoryPath - this.stub = stub - } -} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy deleted file mode 100644 index 6c7061da7e..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/BatchStubRunnerFactory.groovy +++ /dev/null @@ -1,43 +0,0 @@ -package io.codearte.accurest.stubrunner - -import groovy.transform.CompileStatic -import io.codearte.accurest.messaging.AccurestMessaging -import io.codearte.accurest.messaging.noop.NoOpAccurestMessaging - -/** - * Manages lifecycle of multiple {@link StubRunner} instances. - * - * @see StubRunner - * @see BatchStubRunner - */ -@CompileStatic -class BatchStubRunnerFactory { - - private final StubRunnerOptions stubRunnerOptions - private final StubDownloader stubDownloader - private final AccurestMessaging accurestMessaging - - BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions) { - this(stubRunnerOptions, new AetherStubDownloader(stubRunnerOptions), new NoOpAccurestMessaging()) - } - - BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, AccurestMessaging accurestMessaging) { - this(stubRunnerOptions, new AetherStubDownloader(stubRunnerOptions), accurestMessaging) - } - - BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader) { - this(stubRunnerOptions, stubDownloader, new NoOpAccurestMessaging()) - } - - BatchStubRunnerFactory(StubRunnerOptions stubRunnerOptions, StubDownloader stubDownloader, AccurestMessaging accurestMessaging) { - this.stubRunnerOptions = stubRunnerOptions - this.stubDownloader = stubDownloader - this.accurestMessaging = accurestMessaging - } - - BatchStubRunner buildBatchStubRunner() { - StubRunnerFactory stubRunnerFactory = new StubRunnerFactory(stubRunnerOptions, stubDownloader, accurestMessaging) - return new BatchStubRunner(stubRunnerFactory.createStubsFromServiceConfiguration()) - } - -} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy deleted file mode 100644 index dbd73859b9..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/GroovyDslWrapper.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package io.codearte.accurest.stubrunner - -import groovy.transform.CompileStatic -import groovy.transform.PackageScope -import io.codearte.accurest.dsl.GroovyDsl - -/** - * @author Marcin Grzejszczak - */ -@PackageScope -@CompileStatic -class GroovyDslWrapper { - - @Delegate final GroovyDsl groovyDsl - - GroovyDslWrapper(GroovyDsl groovyDsl) { - this.groovyDsl = groovyDsl - } - - boolean hasHttpPart() { - return groovyDsl.request - } -} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MessageNotMatchingException.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MessageNotMatchingException.groovy deleted file mode 100644 index 62368d75bf..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/MessageNotMatchingException.groovy +++ /dev/null @@ -1,12 +0,0 @@ -package io.codearte.accurest.stubrunner - -import groovy.transform.InheritConstructors - -/** - * Exception thrown when message is not matched - * - * @author Marcin Grzejszczak - */ -@InheritConstructors -class MessageNotMatchingException extends RuntimeException { -} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy deleted file mode 100644 index dbbe08c4c6..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubData.groovy +++ /dev/null @@ -1,15 +0,0 @@ -package io.codearte.accurest.stubrunner - -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode -import io.codearte.accurest.dsl.GroovyDsl - -/** - * @author Marcin Grzejszczak - */ -@CompileStatic -@EqualsAndHashCode -class StubData { - final Integer port - final List contracts -} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy deleted file mode 100644 index e3391a67ef..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubDownloader.groovy +++ /dev/null @@ -1,12 +0,0 @@ -package io.codearte.accurest.stubrunner - -interface StubDownloader { - - /** - * Returns a mapping of updated StubConfiguration (it will contain the resolved version) and the location of the downloaded JAR. - * If there was no artifact this method will return {@code null}. - */ - Map.Entry downloadAndUnpackStubJar(StubRunnerOptions options, StubConfiguration stubConfiguration) - - -} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy deleted file mode 100644 index f69f88044c..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubFinder.groovy +++ /dev/null @@ -1,33 +0,0 @@ -package io.codearte.accurest.stubrunner - -import io.codearte.accurest.dsl.GroovyDsl - -interface StubFinder extends StubTrigger { - /** - * For the given groupId and artifactId tries to find the matching - * URL of the running stub. - * - * @param groupId - might be null. In that case a search only via artifactId takes place - * @return URL of a running stub or null if not found - */ - URL findStubUrl(String groupId, String artifactId) - - /** - * For the given Ivy notation {@code groupId:artifactId} tries to find the matching - * URL of the running stub. You can also pass only {@code artifactId}. - * - * @param ivyNotation - Ivy representation of the Maven artifact - * @return URL of a running stub or null if not found - */ - URL findStubUrl(String ivyNotation) - - /** - * Returns all running stubs - */ - RunningStubs findAllRunningStubs() - - /** - * Returns the list of Accurest contracts - */ - Map> getAccurestContracts() -} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMessagingTrigger.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMessagingTrigger.groovy deleted file mode 100644 index 0fd2ef1c8a..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunnerMessagingTrigger.groovy +++ /dev/null @@ -1,18 +0,0 @@ -package io.codearte.accurest.stubrunner - -import groovy.transform.PackageScope -import io.codearte.accurest.messaging.AccurestMessaging -/** - * @author Marcin Grzejszczak - */ -@PackageScope -class StubRunnerMessagingTrigger { - - private final AccurestMessaging accurestMessaging - - StubRunnerMessagingTrigger(AccurestMessaging accurestMessaging) { - this.accurestMessaging = accurestMessaging - } - - void trigger -} diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunning.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunning.groovy deleted file mode 100644 index 15941448b4..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/StubRunning.groovy +++ /dev/null @@ -1,9 +0,0 @@ -package io.codearte.accurest.stubrunner - -interface StubRunning extends Closeable, StubFinder { - /** - * Runs the stubs and returns the {@link RunningStubs} - */ - RunningStubs runStubs() - -} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/WiremockMappingDescriptor.groovy b/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/WiremockMappingDescriptor.groovy deleted file mode 100644 index d8cb688f8c..0000000000 --- a/stub-runner/stub-runner/src/main/groovy/io/codearte/accurest/stubrunner/WiremockMappingDescriptor.groovy +++ /dev/null @@ -1,27 +0,0 @@ -package io.codearte.accurest.stubrunner - -import com.github.tomakehurst.wiremock.stubbing.StubMapping -import groovy.transform.CompileStatic -import groovy.transform.EqualsAndHashCode -import groovy.transform.PackageScope -import groovy.transform.ToString - -/** - * Represents a single JSON file that was found in the folder with - * potential WireMock stubs - */ -@CompileStatic -@EqualsAndHashCode -@ToString(includePackage = false) -@PackageScope -class WiremockMappingDescriptor { - final File descriptor - - WiremockMappingDescriptor(File mappingDescriptor) { - this.descriptor = mappingDescriptor - } - - StubMapping getMapping() { - return StubMapping.buildFrom(descriptor.getText('UTF-8')) - } -} diff --git a/stub-runner/stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml b/stub-runner/stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml deleted file mode 100644 index 2054715610..0000000000 --- a/stub-runner/stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy deleted file mode 100644 index 6e04a8beef..0000000000 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/MappingDescriptorSpec.groovy +++ /dev/null @@ -1,23 +0,0 @@ -package io.codearte.accurest.stubrunner - -import com.github.tomakehurst.wiremock.http.RequestMethod -import spock.lang.Specification - -class MappingDescriptorSpec extends Specification { - public static - final File MAPPING_DESCRIPTOR = new File('src/test/resources/repository/mappings/com/ofg/ping/ping.json') - - def 'should describe stub mapping'() { - given: - WiremockMappingDescriptor mappingDescriptor = new WiremockMappingDescriptor(MAPPING_DESCRIPTOR) - - expect: - with(mappingDescriptor.mapping) { - request.method == RequestMethod.GET - request.url == '/ping' - response.status == 200 - response.body == 'pong' - response.headers.contentTypeHeader.mimeTypePart() == 'text/plain' - } - } -} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubConfigurationSpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubConfigurationSpec.groovy deleted file mode 100644 index 87b346da94..0000000000 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/StubConfigurationSpec.groovy +++ /dev/null @@ -1,21 +0,0 @@ -package io.codearte.accurest.stubrunner - -import spock.lang.Specification - -/** - * @author Marcin Grzejszczak - */ -class StubConfigurationSpec extends Specification { - - def 'should parse ivy notation'() { - given: - String ivy = 'group:artifact:version:classifier' - when: - StubConfiguration stubConfiguration = new StubConfiguration(ivy) - then: - stubConfiguration.artifactId == 'artifact' - stubConfiguration.groupId == 'group' - stubConfiguration.classifier == 'classifier' - stubConfiguration.version == 'version' - } -} diff --git a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/util/ZipCategorySpec.groovy b/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/util/ZipCategorySpec.groovy deleted file mode 100644 index 2a3f5e16ef..0000000000 --- a/stub-runner/stub-runner/src/test/groovy/io/codearte/accurest/stubrunner/util/ZipCategorySpec.groovy +++ /dev/null @@ -1,24 +0,0 @@ -package io.codearte.accurest.stubrunner.util - -import groovy.util.logging.Slf4j -import spock.lang.Specification - -@Slf4j -class ZipCategorySpec extends Specification { - - def 'should unzip a file to the specified location'() { - given: - File zipFile = new File(ZipCategorySpec.classLoader.getResource('file.zip').toURI()) - File tempDir = File.createTempDir() - tempDir.deleteOnExit() - when: - use(ZipCategory) { - zipFile.unzipTo(tempDir) - } - then: - tempDir.listFiles().find { - it.name == 'file.txt' - }?.text?.trim() == 'test' - } - -} diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json deleted file mode 100644 index bfc64f392c..0000000000 --- a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "pl": [ - "com/ofg/bar" - ] -} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json deleted file mode 100644 index fe635a1b3a..0000000000 --- a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "pl": [ - "com/ofg/foo/bar" - ] -} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json b/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json deleted file mode 100644 index 7ecd1e1ed6..0000000000 --- a/stub-runner/stub-runner/src/test/resources/anotherRepository/projects/descriptor.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "pl": [ - "com/ofg/foo" - ] -} \ No newline at end of file diff --git a/stub-runner/stub-runner/src/test/resources/logback.xml b/stub-runner/stub-runner/src/test/resources/logback.xml deleted file mode 100644 index 0cfb35f4cd..0000000000 --- a/stub-runner/stub-runner/src/test/resources/logback.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - \ No newline at end of file From 933e8c0b22aada02abfc9306f342c15c304fac18 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sun, 19 Jun 2016 23:56:46 +0200 Subject: [PATCH 678/719] Updated test scripts --- scripts/runTests.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/runTests.sh b/scripts/runTests.sh index ccb87af81b..e951902a52 100755 --- a/scripts/runTests.sh +++ b/scripts/runTests.sh @@ -13,9 +13,6 @@ echo "Cloning samples" git clone https://github.com/Codearte/accurest-samples cd accurest-samples -echo "Using the rebranding branch" -git checkout rebranding - echo "Running Gradle tests" . ./runTests.sh From 05265547a5a01d5132bc0bc880dee8a4e8b9dad4 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 11:31:37 +0200 Subject: [PATCH 679/719] Updated test scripts --- scripts/runTests.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/runTests.sh b/scripts/runTests.sh index e951902a52..4eb0cf6494 100755 --- a/scripts/runTests.sh +++ b/scripts/runTests.sh @@ -2,6 +2,9 @@ set -o errexit +ROOT_FOLDER=`pwd` +echo "Current folder is $ROOT_FOLDER" + mkdir -p build CONTRACT_VERIFIER_VERSION=1.0.0.BUILD-SNAPSHOT export CONTRACT_VERIFIER_VERSION=${CONTRACT_VERIFIER_VERSION} @@ -18,3 +21,5 @@ echo "Running Gradle tests" echo "Running Maven tests" . ./runMavenTests.sh + +cd $ROOT_FOLDER \ No newline at end of file From 9efc577fc380e8174b58bb95c44bf7194181ce6d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 12:00:44 +0200 Subject: [PATCH 680/719] Added scripts and fixed upload archives of snapshots --- build.sh | 3 +++ deploy.sh | 3 +++ gradle/release.gradle | 4 +++- 3 files changed, 9 insertions(+), 1 deletion(-) create mode 100755 build.sh create mode 100755 deploy.sh diff --git a/build.sh b/build.sh new file mode 100755 index 0000000000..0a16b0b0e9 --- /dev/null +++ b/build.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./gradlew clean build --parallel \ No newline at end of file diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000000..8c061c8b65 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +./gradlew clean build install && ./scripts/runTests.sh && ./gradlew uploadArchives -x test \ No newline at end of file diff --git a/gradle/release.gradle b/gradle/release.gradle index 2258dcdfea..ae90a8c9d7 100644 --- a/gradle/release.gradle +++ b/gradle/release.gradle @@ -38,7 +38,9 @@ afterEvaluate { repositories { mavenDeployer { // POM signature - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + if (isReleaseVersion) { + beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } + } // Target repository repository(url: repoUrl) { authentication(userName: repoUser, password: repoPass) From d6ec0220f2308f38dbdc8071431aaf5ca5d4f98c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 12:03:29 +0200 Subject: [PATCH 681/719] Added docs, restructured project (#30) --- .gitignore | 1 + .travis.yml | 2 +- README.adoc | 60 ++ README.md | 11 - docs/pom.xml | 45 ++ docs/src/main/asciidoc/README.adoc | 15 + ...-cloud-contract-verifier-maven-plugin.adoc | 3 + docs/src/main/ruby/generate_readme.sh | 37 + pom.xml | 667 ++---------------- .../pom.xml | 456 ++++++++++++ .../src}/etc/header.txt | 0 .../verifier/maven/CopyContracts.groovy | 0 .../verifier/maven/ManifestCreator.groovy | 0 .../AetherStubDownloaderFactory.groovy | 0 .../maven/stubrunner/LocalStubRunner.groovy | 0 .../maven/stubrunner/RemoteStubRunner.groovy | 0 .../contract/verifier/maven/ConvertMojo.java | 0 .../verifier/maven/GenerateStubsMojo.java | 0 .../verifier/maven/GenerateTestsMojo.java | 0 .../contract/verifier/maven/RunMojo.java | 0 .../resources/META-INF/plexus/components.xml | 0 .../src/site/asciidoc/complex-content.adoc | 8 +- .../src/site/asciidoc/complex.adoc | 3 + .../src}/site/asciidoc/index.adoc | 0 .../src}/site/asciidoc/junit.adoc | 0 .../src}/site/asciidoc/spock.adoc | 0 .../src}/site/asciidoc/usage.adoc | 0 .../src}/site/site.xml | 0 .../contract/verifier/maven/PluginIT.java | 0 .../verifier/maven/PluginUnitTest.java | 0 .../src}/test/projects/basic/pom.xml | 0 .../test/resources/contracts/Messaging.groovy | 0 .../test/resources/contracts/Sample.groovy | 0 .../projects/complex-configuration/.gitignore | 0 .../projects/complex-configuration/pom.xml | 0 .../frauddetection/Application.java | 0 .../FraudDetectionController.java | 0 .../frauddetection/model/FraudCheck.java | 0 .../model/FraudCheckResult.java | 0 .../model/FraudCheckStatus.java | 0 .../src/test/contracts/brokenContract.groovy | 0 .../contracts/shouldMarkClientAsFraud.groovy | 0 .../shouldMarkClientAsNotFraud.groovy | 0 .../frauddetection/BaseAccurest.java | 0 .../matchers/CustomMatchers.java | 0 .../src}/test/projects/generatedStubs/pom.xml | 0 .../target/stubs/contracts/Sample.groovy | 0 .../target/stubs/mappings/Sample.json | 0 .../test/projects/plugin-extension/pom.xml | 0 .../src/main/java/hello/Application.java | 0 .../src/main/java/hello/Greeting.java | 0 .../main/java/hello/GreetingController.java | 0 .../src/test/java/hello/BaseAccurest.java | 0 .../resources/contracts/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../src}/test/projects/pomless/Sample.groovy | 0 .../test/projects/spring-boot-groovy/pom.xml | 0 .../src/main/java/hello/Application.java | 0 .../src/main/java/hello/Greeting.java | 0 .../main/java/hello/GreetingController.java | 0 .../src/test/groovy/hello/BaseAccurest.groovy | 0 .../resources/contracts/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../test/projects/spring-boot-java/pom.xml | 0 .../src/main/java/hello/Application.java | 0 .../src/main/java/hello/Greeting.java | 0 .../main/java/hello/GreetingController.java | 0 .../src/test/java/hello/BaseAccurest.java | 0 .../resources/contracts/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../src}/test/projects/withStubs/pom.xml | 0 .../src/test/resources/stubs/Sample.groovy | 0 72 files changed, 688 insertions(+), 620 deletions(-) create mode 100644 README.adoc delete mode 100644 README.md create mode 100644 docs/pom.xml create mode 100644 docs/src/main/asciidoc/README.adoc create mode 100644 docs/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc create mode 100755 docs/src/main/ruby/generate_readme.sh create mode 100644 spring-cloud-contract-verifier-maven-plugin/pom.xml rename {src => spring-cloud-contract-verifier-maven-plugin/src}/etc/header.txt (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/main/resources/META-INF/plexus/components.xml (100%) rename src/site/asciidoc/complex.adoc => spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex-content.adoc (50%) create mode 100644 spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex.adoc rename {src => spring-cloud-contract-verifier-maven-plugin/src}/site/asciidoc/index.adoc (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/site/asciidoc/junit.adoc (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/site/asciidoc/spock.adoc (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/site/asciidoc/usage.adoc (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/site/site.xml (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/basic/pom.xml (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/basic/src/test/resources/contracts/Messaging.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/basic/src/test/resources/contracts/Sample.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/.gitignore (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/pom.xml (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/generatedStubs/pom.xml (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/generatedStubs/target/stubs/mappings/Sample.json (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/plugin-extension/pom.xml (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/plugin-extension/src/main/java/hello/Application.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/plugin-extension/src/main/java/hello/Greeting.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/plugin-extension/src/main/java/hello/GreetingController.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/pomless/Sample.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-groovy/pom.xml (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-groovy/src/main/java/hello/Application.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-java/pom.xml (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-java/src/main/java/hello/Application.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-java/src/main/java/hello/Greeting.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/withStubs/pom.xml (100%) rename {src => spring-cloud-contract-verifier-maven-plugin/src}/test/projects/withStubs/src/test/resources/stubs/Sample.groovy (100%) diff --git a/.gitignore b/.gitignore index 6c515d9c17..2c95b068c5 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ dependency-reduced-pom.xml buildNumber.properties .mvn/timing.properties +target \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 2765fbe53f..7d7bc617b2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,4 +2,4 @@ language: java jdk: - oraclejdk8 script: -- ./mvnw clean test jacoco:report coveralls:report \ No newline at end of file +- ./mvnw clean test jacoco:report coveralls:report -pl spring-cloud-contract-verifier-maven-plugin \ No newline at end of file diff --git a/README.adoc b/README.adoc new file mode 100644 index 0000000000..ccd77f7328 --- /dev/null +++ b/README.adoc @@ -0,0 +1,60 @@ +// Do not edit this file (e.g. go instead to src/main/asciidoc) + +image::https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master[Build Status, link=https://travis-ci.org/Codearte/accurest-maven-plugin] +image::https://img.shields.io/github/issues/Codearte/accurest/maven.svg[Github Issues, link=https://github.com/Codearte/accurest/labels/maven] + +//[![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) + += Spring Cloud Contract Verifier Maven Plugin + +== Documentation + +* http://codearte.github.io/accurest/[Spring Cloud Contract Verifier Documentation] +* http://codearte.github.io/accurest-maven-plugin/plugin-info.html[Spring Cloud Contract Verifier Maven Plugin Documentation Site] + +== Contributing + +Spring Cloud is released under the non-restrictive Apache 2.0 license, +and follows a very standard Github development process, using Github +tracker for issues and merging pull requests into master. If you want +to contribute even something trivial please do not hesitate, but +follow the guidelines below. + +=== Sign the Contributor License Agreement +Before we accept a non-trivial patch or pull request we will need you to sign the +https://support.springsource.com/spring_committer_signup[contributor's agreement]. +Signing the contributor's agreement does not grant anyone commit rights to the main +repository, but it does mean that we can accept your contributions, and you will get an +author credit if we do. Active contributors might be asked to join the core team, and +given the ability to merge pull requests. + +=== Code of Conduct +This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of +conduct]. By participating, you are expected to uphold this code. Please report +unacceptable behavior to spring-code-of-conduct@pivotal.io. + +=== Code Conventions and Housekeeping +None of these is essential for a pull request, but they will all help. They can also be +added after the original pull request but before a merge. + +* Use the Spring Framework code format conventions. If you use Eclipse + you can import formatter settings using the + `eclipse-code-formatter.xml` file from the + https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring + Cloud Build] project. If using IntelliJ, you can use the + http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter + Plugin] to import the same file. +* Make sure all new `.java` files to have a simple Javadoc class comment with at least an + `@author` tag identifying you, and preferably at least a paragraph on what the class is + for. +* Add the ASF license header comment to all new `.java` files (copy from existing files + in the project) +* Add yourself as an `@author` to the .java files that you modify substantially (more + than cosmetic changes). +* Add some Javadocs and, if you change the namespace, some XSD doc elements. +* A few unit tests would help a lot as well -- someone has to do it. +* If no-one else is using your branch, please rebase it against the current master (or + other target branch in the main project). +* When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions], + if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit + message (where XXXX is the issue number). \ No newline at end of file diff --git a/README.md b/README.md deleted file mode 100644 index 5beb0e4d6a..0000000000 --- a/README.md +++ /dev/null @@ -1,11 +0,0 @@ -[![Build Status](https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master)](https://travis-ci.org/Codearte/accurest-maven-plugin) [![GitHub issues](https://img.shields.io/github/issues/Codearte/accurest/maven.svg)](https://github.com/Codearte/accurest/labels/maven) [![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) - -Spring Cloud Contract Verifier Maven Plugin -=========================================== - -Documentation ---- - -* [Spring Cloud Contract Verifier Documentation](http://codearte.github.io/accurest/) -* [Spring Cloud Contract Verifier Maven Plugin Documentation Site](http://codearte.github.io/accurest-maven-plugin/plugin-info.html) - diff --git a/docs/pom.xml b/docs/pom.xml new file mode 100644 index 0000000000..19fbf72425 --- /dev/null +++ b/docs/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-build + 1.1.1.RELEASE + + + + spring-cloud-contract-verifier-docs + pom + Spring Cloud Contract Verifier Docs + Spring Contract Verifier Docs + + spring-cloud-contract-verifier-maven-plugin + ${basedir}/.. + + + + docs + + + + org.asciidoctor + asciidoctor-maven-plugin + 1.5.3 + false + + + org.apache.maven.plugins + maven-antrun-plugin + false + + + org.codehaus.mojo + build-helper-maven-plugin + false + + + + + + diff --git a/docs/src/main/asciidoc/README.adoc b/docs/src/main/asciidoc/README.adoc new file mode 100644 index 0000000000..ac49eb468b --- /dev/null +++ b/docs/src/main/asciidoc/README.adoc @@ -0,0 +1,15 @@ +image::https://travis-ci.org/Codearte/accurest-maven-plugin.svg?branch=master[Build Status, link=https://travis-ci.org/Codearte/accurest-maven-plugin] +image::https://img.shields.io/github/issues/Codearte/accurest/maven.svg[Github Issues, link=https://github.com/Codearte/accurest/labels/maven] + +//[![Maven Central](https://img.shields.io/maven-central/v/io.codearte.accurest/accurest-maven-plugin.svg)](https://maven-badges.herokuapp.com/maven-central/io.codearte.accurest/accurest-maven-plugin) + += Spring Cloud Contract Verifier Maven Plugin + +== Documentation + +* http://codearte.github.io/accurest/[Spring Cloud Contract Verifier Documentation] +* http://codearte.github.io/accurest-maven-plugin/plugin-info.html[Spring Cloud Contract Verifier Maven Plugin Documentation Site] + +== Contributing + +include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[] \ No newline at end of file diff --git a/docs/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc b/docs/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc new file mode 100644 index 0000000000..b2fd89ebfd --- /dev/null +++ b/docs/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc @@ -0,0 +1,3 @@ +:root_folder: ../../../../spring-cloud-contract-verifier-maven-plugin + +include::{root_folder}/src/site/asciidoc/complex-content.adoc[] \ No newline at end of file diff --git a/docs/src/main/ruby/generate_readme.sh b/docs/src/main/ruby/generate_readme.sh new file mode 100755 index 0000000000..6d0ce9dc54 --- /dev/null +++ b/docs/src/main/ruby/generate_readme.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env ruby + +base_dir = File.join(File.dirname(__FILE__),'../../..') +src_dir = File.join(base_dir, "/src/main/asciidoc") +require 'asciidoctor' +require 'optparse' + +options = {} +file = "#{src_dir}/README.adoc" + +OptionParser.new do |o| + o.on('-o OUTPUT_FILE', 'Output file (default is stdout)') { |file| options[:to_file] = file unless file=='-' } + o.on('-h', '--help') { puts o; exit } + o.parse! +end + +file = ARGV[0] if ARGV.length>0 + +# Copied from https://github.com/asciidoctor/asciidoctor-extensions-lab/blob/master/scripts/asciidoc-coalescer.rb +doc = Asciidoctor.load_file file, safe: :unsafe, header_only: true, attributes: options[:attributes] +header_attr_names = (doc.instance_variable_get :@attributes_modified).to_a +header_attr_names.each {|k| doc.attributes[%(#{k}!)] = '' unless doc.attr? k } +attrs = doc.attributes +attrs['allow-uri-read'] = true +puts attrs + +out = "// Do not edit this file (e.g. go instead to src/main/asciidoc)\n\n" +doc = Asciidoctor.load_file file, safe: :unsafe, parse: false, attributes: attrs +out << doc.reader.read + +unless options[:to_file] + puts out +else + File.open(options[:to_file],'w+') do |file| + file.write(out) + end +end diff --git a/pom.xml b/pom.xml index 3101ec6a40..0c779af437 100644 --- a/pom.xml +++ b/pom.xml @@ -4,16 +4,21 @@ 4.0.0 org.springframework.cloud.contract - spring-cloud-contract-verifier-maven-plugin - maven-plugin + spring-cloud-contract-verifier-maven-plugin-parent + pom 1.0.0.BUILD-SNAPSHOT - Spring Cloud Contract Verifier Maven Plugin - Spring Cloud Contract Verifier Maven Plugin + Spring Cloud Contract Verifier Maven Plugin + Spring Cloud Contract Verifier Maven Plugin Parent https://github.com/Codearte/accurest-maven-plugin 2016 + + docs + spring-cloud-contract-verifier-maven-plugin + + [3.2.1,) @@ -36,20 +41,6 @@ - - 3.2.5 - 3.4 - - UTF-8 - UTF-8 - - 1.0.0.BUILD-SNAPSHOT - 1.1.0 - - 1.7 - 1.7 - - Apache 2 @@ -94,200 +85,62 @@ - - - org.codehaus.gmavenplus - gmavenplus-plugin - 1.5 - - - - addSources - generateStubs - compile - removeStubs - - - - - - org.codehaus.plexus - plexus-component-metadata - 1.6 - - - - generate-metadata - generate-test-metadata - - - - - - maven-plugin-plugin - ${maven.plugin.plugin.version} - - true - - - - generated-helpmojo - - helpmojo - - - - generate-descriptor - - descriptor - - - - - - io.takari.maven.plugins - takari-lifecycle-plugin - 1.12.0 - true - - - testProperties - process-test-resources - - testProperties - - - - - - org.apache.maven.plugins - maven-failsafe-plugin - 2.19.1 - - - - integration-test - verify - - - - - - com.mycila - license-maven-plugin - 3.0.rc1 - -
src/etc/header.txt
- - src/** - - - **/.idea/** - **/*.adoc - - true - true - - ${project.inceptionYear} - Codearte - - UTF-8 -
- - - - check - - - -
- - org.jacoco - jacoco-maven-plugin - 0.7.6.201602180812 - - - **/HelpMojo.class - - - - - prepare-agent - - prepare-agent - - - - - - org.eluder.coveralls - coveralls-maven-plugin - 4.1.0 - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - false - true - v@{project.version} - - - - org.apache.maven.plugins - maven-scm-publish-plugin - 1.1 - - ${project.scm.developerConnection} - gh-pages - ${project.reporting.outputDirectory} - - - - scm-publish - site-deploy - - publish-scm - - - - - - org.apache.maven.plugins - maven-site-plugin - 3.4 - - true - - true - true - false - en - UTF-8 - UTF-8 - - - - font - coderay - style - 2 - - - - - - org.asciidoctor - asciidoctor-maven-plugin - 1.5.3 - - - -
- + + org.codehaus.gmavenplus + gmavenplus-plugin + 1.5 + + + org.codehaus.plexus + plexus-component-metadata + 1.6 + + + maven-plugin-plugin + ${maven.plugin.plugin.version} + + + io.takari.maven.plugins + takari-lifecycle-plugin + 1.12.0 + + + org.apache.maven.plugins + maven-failsafe-plugin + 2.19.1 + + + com.mycila + license-maven-plugin + 3.0.rc1 + + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + org.eluder.coveralls + coveralls-maven-plugin + 4.1.0 + + + org.apache.maven.plugins + maven-release-plugin + 2.5.3 + + + org.apache.maven.plugins + maven-scm-publish-plugin + 1.1 + + + org.apache.maven.plugins + maven-site-plugin + 3.4 + maven-install-plugin 2.5.2 @@ -303,398 +156,4 @@
- - - - org.springframework.cloud.contract - spring-cloud-contract-verifier-core - ${spring.cloud.contract.verifier.version} - - - org.springframework.cloud.contract - spring-cloud-contract-verifier-converters - ${spring.cloud.contract.verifier.version} - - - org.springframework.cloud.contract - spring-cloud-contract-stub-runner - ${spring.cloud.contract.verifier.version} - - - - org.eclipse.aether - aether-api - ${aether.version} - provided - - - - org.apache.maven.shared - maven-filtering - 3.1.0 - - - - ch.qos.logback - logback-core - 1.1.3 - - - org.slf4j - slf4j-simple - 1.7.12 - test - - - - javax.inject - javax.inject - 1 - provided - - - org.apache.maven - maven-core - ${maven.version} - provided - - - - org.apache.maven - maven-plugin-api - ${maven.version} - provided - - - org.apache.maven - maven-model - - - org.apache.maven - maven-artifact - - - org.eclipse.sisu - org.eclipse.sisu.plexus - - - - - org.apache.maven.plugin-tools - maven-plugin-annotations - ${maven.plugin.plugin.version} - provided - - - - org.apache.maven - maven-archiver - 3.0.0 - - - org.codehaus.plexus - plexus-archiver - 3.1 - - - - io.takari.maven.plugins - takari-plugin-testing - 2.9.0 - test - - - io.takari.maven.plugins - takari-plugin-integration-testing - 2.9.0 - pom - test - - - org.apache.maven - maven-compat - ${maven.version} - test - - - junit - junit - 4.12 - test - - - org.assertj - assertj-core - 2.4.0 - test - - - - - - - - maven-plugin-plugin - ${maven.plugin.plugin.version} - - - org.apache.maven.plugins - maven-jxr-plugin - - - org.apache.maven.plugins - maven-project-info-reports-plugin - - false - false - - - - org.apache.maven.plugins - maven-javadoc-plugin - - true - - - - org.apache.maven.plugins - maven-surefire-report-plugin - - - - - - - release - - - - org.apache.maven.plugins - maven-gpg-plugin - 1.6 - - - sign-artifacts - verify - - sign - - - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.0 - - - attach-sources - - jar-no-fork - - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.3 - - - attach-javadocs - - jar - - - - - - org.sonatype.plugins - nexus-staging-maven-plugin - 1.6.7 - true - - oss - https://oss.sonatype.org/ - true - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.10 - - - parse-version - deploy - - parse-version - - - - - - org.codehaus.mojo - versions-maven-plugin - 2.2 - - - switch-to-snapshot-version - deploy - - set - - - - - ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT - - - - - - - org.apache.maven.plugins - maven-scm-plugin - 1.9.4 - false - - - tag-new-release - deploy - - tag - - - v${project.version} - - - - save-changes - deploy - - checkin - - - connection - pom.xml - Sets project version to ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.nextIncrementalVersion}-SNAPSHOT - -[ci skip] - - - - - - - - - - - version - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.10 - - - parse-version - initialize - - parse-version - - - - - - org.codehaus.mojo - versions-maven-plugin - 2.2 - - - set-release-version - initialize - - set - - - - ${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion} - - - - - - - - - - spring - - true - - - - spring-snapshots - Spring Snapshots - http://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - http://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - http://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - http://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - http://repo.spring.io/libs-milestone-local - - false - - - - spring-plugin-snapshots - Spring Snapshots - http://repo.spring.io/plugins-snapshot-local - - true - - - - spring-plugin-milestones - Spring Milestones - http://repo.spring.io/plugins-milestone-local - - false - - - - -
diff --git a/spring-cloud-contract-verifier-maven-plugin/pom.xml b/spring-cloud-contract-verifier-maven-plugin/pom.xml new file mode 100644 index 0000000000..761b92c484 --- /dev/null +++ b/spring-cloud-contract-verifier-maven-plugin/pom.xml @@ -0,0 +1,456 @@ + + + 4.0.0 + + org.springframework.cloud.contract + spring-cloud-contract-verifier-maven-plugin + maven-plugin + 1.0.0.BUILD-SNAPSHOT + + Spring Cloud Contract Verifier Maven Plugin + Spring Cloud Contract Verifier Maven Plugin + https://github.com/Codearte/accurest-maven-plugin + + + 3.2.5 + 3.4 + + UTF-8 + UTF-8 + + 1.0.0.BUILD-SNAPSHOT + 1.1.0 + + 1.7 + 1.7 + + + 2016 + + + + + org.codehaus.gmavenplus + gmavenplus-plugin + + + + addSources + generateStubs + compile + removeStubs + + + + + + org.codehaus.plexus + plexus-component-metadata + + + + generate-metadata + generate-test-metadata + + + + + + maven-plugin-plugin + + true + + + + generated-helpmojo + + helpmojo + + + + generate-descriptor + + descriptor + + + + + + io.takari.maven.plugins + takari-lifecycle-plugin + true + + + testProperties + process-test-resources + + testProperties + + + + + + org.apache.maven.plugins + maven-failsafe-plugin + + + + integration-test + verify + + + + + + com.mycila + license-maven-plugin + +
src/etc/header.txt
+ + src/** + + + **/.idea/** + **/*.adoc + + true + true + + ${project.inceptionYear} + Codearte + + UTF-8 +
+ + + + check + + + +
+ + org.jacoco + jacoco-maven-plugin + + + **/HelpMojo.class + + + + + prepare-agent + + prepare-agent + + + + + + org.eluder.coveralls + coveralls-maven-plugin + + + org.apache.maven.plugins + maven-release-plugin + + false + true + v@{project.version} + + + + org.apache.maven.plugins + maven-scm-publish-plugin + + ${project.scm.developerConnection} + gh-pages + ${project.reporting.outputDirectory} + + + + scm-publish + site-deploy + + publish-scm + + + + + + org.apache.maven.plugins + maven-site-plugin + + true + + true + true + false + en + UTF-8 + UTF-8 + + + + font + coderay + style + 2 + + + + + + org.asciidoctor + asciidoctor-maven-plugin + 1.5.3 + + + +
+
+ + + + org.springframework.cloud.contract + spring-cloud-contract-verifier-core + ${spring.cloud.contract.verifier.version} + + + org.springframework.cloud.contract + spring-cloud-contract-verifier-converters + ${spring.cloud.contract.verifier.version} + + + org.springframework.cloud.contract + spring-cloud-contract-stub-runner + ${spring.cloud.contract.verifier.version} + + + + org.eclipse.aether + aether-api + ${aether.version} + provided + + + + org.apache.maven.shared + maven-filtering + 3.1.0 + + + + ch.qos.logback + logback-core + 1.1.3 + + + org.slf4j + slf4j-simple + 1.7.12 + test + + + + javax.inject + javax.inject + 1 + provided + + + org.apache.maven + maven-core + ${maven.version} + provided + + + + org.apache.maven + maven-plugin-api + ${maven.version} + provided + + + org.apache.maven + maven-model + + + org.apache.maven + maven-artifact + + + org.eclipse.sisu + org.eclipse.sisu.plexus + + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${maven.plugin.plugin.version} + provided + + + + org.apache.maven + maven-archiver + 3.0.0 + + + org.codehaus.plexus + plexus-archiver + 3.1 + + + + io.takari.maven.plugins + takari-plugin-testing + 2.9.0 + test + + + io.takari.maven.plugins + takari-plugin-integration-testing + 2.9.0 + pom + test + + + org.apache.maven + maven-compat + ${maven.version} + test + + + junit + junit + 4.12 + test + + + org.assertj + assertj-core + 2.4.0 + test + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.6 + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.0 + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.3 + + + attach-javadocs + + jar + + + + + + + + + spring + + true + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/libs-milestone-local + + false + + + + spring-releases + Spring Releases + http://repo.spring.io/release + + false + + + + + + spring-snapshots + Spring Snapshots + http://repo.spring.io/libs-snapshot-local + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/libs-milestone-local + + false + + + + spring-plugin-snapshots + Spring Snapshots + http://repo.spring.io/plugins-snapshot-local + + true + + + + spring-plugin-milestones + Spring Milestones + http://repo.spring.io/plugins-milestone-local + + false + + + + + +
diff --git a/src/etc/header.txt b/spring-cloud-contract-verifier-maven-plugin/src/etc/header.txt similarity index 100% rename from src/etc/header.txt rename to spring-cloud-contract-verifier-maven-plugin/src/etc/header.txt diff --git a/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy b/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy similarity index 100% rename from src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy diff --git a/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy b/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy similarity index 100% rename from src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy diff --git a/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy b/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy similarity index 100% rename from src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy diff --git a/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy b/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy similarity index 100% rename from src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy diff --git a/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy b/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy similarity index 100% rename from src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy diff --git a/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java b/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java similarity index 100% rename from src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java rename to spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java diff --git a/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java b/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java similarity index 100% rename from src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java rename to spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java diff --git a/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java b/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java similarity index 100% rename from src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java rename to spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java diff --git a/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java b/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java similarity index 100% rename from src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java rename to spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java diff --git a/src/main/resources/META-INF/plexus/components.xml b/spring-cloud-contract-verifier-maven-plugin/src/main/resources/META-INF/plexus/components.xml similarity index 100% rename from src/main/resources/META-INF/plexus/components.xml rename to spring-cloud-contract-verifier-maven-plugin/src/main/resources/META-INF/plexus/components.xml diff --git a/src/site/asciidoc/complex.adoc b/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex-content.adoc similarity index 50% rename from src/site/asciidoc/complex.adoc rename to spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex-content.adoc index cb90a65901..fad117ee37 100644 --- a/src/site/asciidoc/complex.adoc +++ b/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex-content.adoc @@ -7,14 +7,14 @@ Sample more complex configuration for Java Project with JUnit tests. [source,xml] ---- -include::../../../src/test/projects/complex-configuration/pom.xml[tags=plugin] +include::{root_folder}/src/test/projects/complex-configuration/pom.xml[tags=plugin] ---- === Base Test class [source,java] ---- -include::../../../src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java[] +include::{root_folder}/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java[] ---- @@ -22,14 +22,14 @@ include::../../../src/test/projects/complex-configuration/src/test/java/com/blog [source,java] ---- -include::../../../src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java[] +include::{root_folder}/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java[] ---- === Sample contract using matcher [source,java] ---- -include::../../../src/test/projects/complex-configuration/src/test/accurest/shouldMarkClientAsNotFraud.groovy[] +include::{root_folder}/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy[] ---- diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex.adoc b/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex.adoc new file mode 100644 index 0000000000..e29ea2b549 --- /dev/null +++ b/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex.adoc @@ -0,0 +1,3 @@ +:root_folder: ../../.. + +include::complex.adoc[] \ No newline at end of file diff --git a/src/site/asciidoc/index.adoc b/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/index.adoc similarity index 100% rename from src/site/asciidoc/index.adoc rename to spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/index.adoc diff --git a/src/site/asciidoc/junit.adoc b/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/junit.adoc similarity index 100% rename from src/site/asciidoc/junit.adoc rename to spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/junit.adoc diff --git a/src/site/asciidoc/spock.adoc b/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/spock.adoc similarity index 100% rename from src/site/asciidoc/spock.adoc rename to spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/spock.adoc diff --git a/src/site/asciidoc/usage.adoc b/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/usage.adoc similarity index 100% rename from src/site/asciidoc/usage.adoc rename to spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/usage.adoc diff --git a/src/site/site.xml b/spring-cloud-contract-verifier-maven-plugin/src/site/site.xml similarity index 100% rename from src/site/site.xml rename to spring-cloud-contract-verifier-maven-plugin/src/site/site.xml diff --git a/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java b/spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java similarity index 100% rename from src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java diff --git a/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java b/spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java similarity index 100% rename from src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java diff --git a/src/test/projects/basic/pom.xml b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/pom.xml similarity index 100% rename from src/test/projects/basic/pom.xml rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/pom.xml diff --git a/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy similarity index 100% rename from src/test/projects/basic/src/test/resources/contracts/Messaging.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy diff --git a/src/test/projects/basic/src/test/resources/contracts/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy similarity index 100% rename from src/test/projects/basic/src/test/resources/contracts/Sample.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy diff --git a/src/test/projects/complex-configuration/.gitignore b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/.gitignore similarity index 100% rename from src/test/projects/complex-configuration/.gitignore rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/.gitignore diff --git a/src/test/projects/complex-configuration/pom.xml b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/pom.xml similarity index 100% rename from src/test/projects/complex-configuration/pom.xml rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/pom.xml diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java similarity index 100% rename from src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java similarity index 100% rename from src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java similarity index 100% rename from src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java similarity index 100% rename from src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java diff --git a/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java diff --git a/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy similarity index 100% rename from src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy diff --git a/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy similarity index 100% rename from src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy diff --git a/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy similarity index 100% rename from src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy diff --git a/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java similarity index 100% rename from src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java diff --git a/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java similarity index 100% rename from src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java diff --git a/src/test/projects/generatedStubs/pom.xml b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/pom.xml similarity index 100% rename from src/test/projects/generatedStubs/pom.xml rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/pom.xml diff --git a/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy similarity index 100% rename from src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy diff --git a/src/test/projects/generatedStubs/target/stubs/mappings/Sample.json b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/mappings/Sample.json similarity index 100% rename from src/test/projects/generatedStubs/target/stubs/mappings/Sample.json rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/mappings/Sample.json diff --git a/src/test/projects/plugin-extension/pom.xml b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/pom.xml similarity index 100% rename from src/test/projects/plugin-extension/pom.xml rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/pom.xml diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Application.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Application.java similarity index 100% rename from src/test/projects/plugin-extension/src/main/java/hello/Application.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Application.java diff --git a/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java similarity index 100% rename from src/test/projects/plugin-extension/src/main/java/hello/Greeting.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java diff --git a/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java similarity index 100% rename from src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java diff --git a/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java similarity index 100% rename from src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java diff --git a/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy similarity index 100% rename from src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy diff --git a/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy similarity index 100% rename from src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy diff --git a/src/test/projects/pomless/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy similarity index 100% rename from src/test/projects/pomless/Sample.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy diff --git a/src/test/projects/spring-boot-groovy/pom.xml b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml similarity index 100% rename from src/test/projects/spring-boot-groovy/pom.xml rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java similarity index 100% rename from src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java similarity index 100% rename from src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java diff --git a/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java similarity index 100% rename from src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java diff --git a/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy similarity index 100% rename from src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy similarity index 100% rename from src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy diff --git a/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy similarity index 100% rename from src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy diff --git a/src/test/projects/spring-boot-java/pom.xml b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/pom.xml similarity index 100% rename from src/test/projects/spring-boot-java/pom.xml rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/pom.xml diff --git a/src/test/projects/spring-boot-java/src/main/java/hello/Application.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java similarity index 100% rename from src/test/projects/spring-boot-java/src/main/java/hello/Application.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java diff --git a/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java similarity index 100% rename from src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java diff --git a/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java similarity index 100% rename from src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java diff --git a/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java similarity index 100% rename from src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java diff --git a/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy similarity index 100% rename from src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy diff --git a/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy similarity index 100% rename from src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy diff --git a/src/test/projects/withStubs/pom.xml b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/pom.xml similarity index 100% rename from src/test/projects/withStubs/pom.xml rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/pom.xml diff --git a/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy similarity index 100% rename from src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy rename to spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy From 60cc9f9007f8541d8b71f166385cda56b9dc55a3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 12:24:30 +0200 Subject: [PATCH 682/719] Allowing to pass username and password via envs --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index a59ec6dd9b..82570396cb 100644 --- a/build.gradle +++ b/build.gradle @@ -13,8 +13,8 @@ buildscript { } ext { - repoUser = project.findProperty('REPO_USERNAME') ?: '' - repoPass = project.findProperty('REPO_PASSWORD') ?: '' + repoUser = System.getenv('REPO_USERNAME') ?: project.findProperty('REPO_USERNAME') ?: '' + repoPass = System.getenv('REPO_PASSWORD') ?: project.findProperty('REPO_PASSWORD') ?: '' projectsToSkipPublication = ['parent', 'samples', 'docs', 'root'] } From 6c76bafeccb013c9cd9fecaa5b718dfbda7c72f1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 12:27:24 +0200 Subject: [PATCH 683/719] Updated the README with the old docs --- README.adoc | 2 ++ docs/src/main/asciidoc/introduction.adoc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/README.adoc b/README.adoc index 98061ed476..2e6334dfd2 100644 --- a/README.adoc +++ b/README.adoc @@ -10,6 +10,8 @@ == Introduction +IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here] + Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: diff --git a/docs/src/main/asciidoc/introduction.adoc b/docs/src/main/asciidoc/introduction.adoc index 95c9b1f58f..26b5e2bd9a 100644 --- a/docs/src/main/asciidoc/introduction.adoc +++ b/docs/src/main/asciidoc/introduction.adoc @@ -1,5 +1,7 @@ == Introduction +IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here] + Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: From fbecf2629035701d2a71ba15c6aae081c53eac09 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:00:23 +0200 Subject: [PATCH 684/719] Updated docs and added the deprecated docs --- docs/build.gradle | 1 - docs/src/main/asciidoc/contract.adoc | 6 +- .../main/asciidoc/deprecated/contract.html | 1232 ++++++ .../main/asciidoc/deprecated/images/Deps.png | Bin 0 -> 37192 bytes .../asciidoc/deprecated/images/Stubs1.png | Bin 0 -> 35170 bytes .../asciidoc/deprecated/images/Stubs2.png | Bin 0 -> 18143 bytes docs/src/main/asciidoc/deprecated/index.html | 3914 +++++++++++++++++ .../asciidoc/deprecated/introduction.html | 797 ++++ .../main/asciidoc/deprecated/messaging.html | 914 ++++ .../main/asciidoc/deprecated/migration.html | 594 +++ docs/src/main/asciidoc/deprecated/rest.html | 1032 +++++ .../main/asciidoc/deprecated/stubrunner.html | 1258 ++++++ .../asciidoc/deprecated/stubrunner_msg.html | 1247 ++++++ docs/src/main/asciidoc/rest.adoc | 2 +- 14 files changed, 10992 insertions(+), 5 deletions(-) create mode 100644 docs/src/main/asciidoc/deprecated/contract.html create mode 100644 docs/src/main/asciidoc/deprecated/images/Deps.png create mode 100644 docs/src/main/asciidoc/deprecated/images/Stubs1.png create mode 100644 docs/src/main/asciidoc/deprecated/images/Stubs2.png create mode 100644 docs/src/main/asciidoc/deprecated/index.html create mode 100644 docs/src/main/asciidoc/deprecated/introduction.html create mode 100644 docs/src/main/asciidoc/deprecated/messaging.html create mode 100644 docs/src/main/asciidoc/deprecated/migration.html create mode 100644 docs/src/main/asciidoc/deprecated/rest.html create mode 100644 docs/src/main/asciidoc/deprecated/stubrunner.html create mode 100644 docs/src/main/asciidoc/deprecated/stubrunner_msg.html diff --git a/docs/build.gradle b/docs/build.gradle index 36a6fbf2b8..b705c68551 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -46,7 +46,6 @@ asciidoctor { dependsOn jrubyPrepare sourceDir 'src/main/asciidoc' - setSourceDocumentName file('spring-cloud-contract-verifier.adoc') backends 'html' attributes 'build-gradle': file('build.gradle'), 'endpoint-url': 'https://Codearte.github.io/accurest', diff --git a/docs/src/main/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc index 19e6be35f3..a8b4d64053 100644 --- a/docs/src/main/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -147,7 +147,7 @@ include::{verifier_core_path}/src/test/groovy/org/springframework/cloud/contract [source,groovy,indent=0] ---- -include::{verifier_root_path}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] +include::{verifier_root_path}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] ---- === JAX-RS support @@ -179,7 +179,7 @@ The output message can be triggered by calling a method (e.g. a Scheduler was st [source,groovy] ---- -include::../../../../samples/messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=method_trigger,indent=0] +include::../../../../samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=method_trigger,indent=0] ---- In this case the output message will be sent to `output` if a method called `bookReturnedTriggered` will be executed. In the message *publisher's* side @@ -191,7 +191,7 @@ The output message can be triggered by receiving a message. [source,groovy] ---- -include::../../../../samples/messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=message_trigger,indent=0] +include::../../../../samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy[tags=message_trigger,indent=0] ---- In this case the output message will be sent to `output` if a proper message will be received on the `input` destination. In the message *publisher's* side diff --git a/docs/src/main/asciidoc/deprecated/contract.html b/docs/src/main/asciidoc/deprecated/contract.html new file mode 100644 index 0000000000..a210b8ade0 --- /dev/null +++ b/docs/src/main/asciidoc/deprecated/contract.html @@ -0,0 +1,1232 @@ + + + + + + + +Contract DSL + + + + + + + +
+
+

Contract DSL

+
+
+

Contract DSL in Accurest is written in Groovy, but don’t be alarmed if you didn’t use Groovy before. Knowledge of the language is not really needed as our DSL uses only +a tiny subset of it (namely literals, method calls and closures). What’s more, Accurest’s DSL is designed to be programmer-readable without any knowledge of the DSL itself - + it’s statically typed.

+
+
+ + + + + +
+ + +Since {messaging_version} you can use the io.codearte.accurest.dsl.Accurest class in your DSL files. +
+
+
+

Let’s look at full example of a contract definition.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                method 'PUT'
+                url '/api/12'
+                headers {
+                        header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json'
+                }
+                body '''\
+                [{
+                        "created_at": "Sat Jul 26 09:38:57 +0000 2014",
+                        "id": 492967299297845248,
+                        "id_str": "492967299297845248",
+                        "text": "Gonna see you at Warsaw",
+                        "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"
+                        }
+                }]
+        '''
+        }
+        response {
+                status 200
+        }
+}
+
+
+
+

Not all features of the DSL are used in example above. If you didn’t find what you are looking for, please check next paragraphs on this page.

+
+
+
+
+

You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: mvn io.codearte.accurest:accurest-maven-plugin:convert.

+
+
+
+
+

Limitations

+
+ + + + + +
+ + +Accurest doesn’t support XML properly. Please use JSON or help us implement this feature. +
+
+
+ + + + + +
+ + +Accurest supports equality check on text response. Regular expressions are not yet available. +
+
+
+
+

HTTP Top-Level Elements

+
+

Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        // Definition of HTTP request part of the contract
+        // (this can be a valid request or invalid depending
+        // on type of contract being specified).
+        request {
+                //...
+        }
+
+        // Definition of HTTP response part of the contract
+        // (a service implementing this contract should respond
+        // with following response after receiving request
+        // specified in "request" part above).
+        response {
+                //...
+        }
+
+        // Contract priority, which can be used for overriding
+        // contracts (1 is highest). Priority is optional.
+        priority 1
+}
+
+
+
+
+

Request

+
+

HTTP protocol requires only method and address to be specified in a request. The same information is mandatory in request definition of Accurest contract.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                // HTTP request method (GET/POST/PUT/DELETE).
+                method 'GET'
+
+                // Path component of request URL is specified as follows.
+                urlPath('/users')
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

It is possible to specify whole url instead of just path, but urlPath is the recommended way as it makes the tests host-independent.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                method 'GET'
+
+                // Specifying `url` and `urlPath` in one contract is illegal.
+                url('http://localhost:8888/users')
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

Request may contain query parameters, which are specified in a closure nested in a call to urlPath or url.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+
+                urlPath('/users') {
+
+                        // Each parameter is specified in form
+                        // `'paramName' : paramValue` where parameter value
+                        // may be a simple literal or one of matcher functions,
+                        // all of which are used in this example.
+                        queryParameters {
+
+                                // If a simple literal is used as value
+                                // default matcher function is used (equalTo)
+                                parameter 'limit': 100
+
+                                // `equalTo` function simply compares passed value
+                                // using identity operator (==).
+                                parameter 'filter': equalTo("email")
+
+                                // `containing` function matches strings
+                                // that contains passed substring.
+                                parameter 'gender': value(stub(containing("[mf]")), server('mf'))
+
+                                // `matching` function tests parameter
+                                // against passed regular expression.
+                                parameter 'offset': value(stub(matching("[0-9]+")), server(123))
+
+                                // `notMatching` functions tests if parameter
+                                // does not match passed regular expression.
+                                parameter 'loginStartsWith': value(stub(notMatching(".{0,2}")), server(3))
+                        }
+                }
+
+                //...
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

It may contain additional request headers…​

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+
+                // Each header is added in form `'Header-Name' : 'Header-Value'`.
+                headers {
+                        header 'Content-Type': 'application/json'
+                }
+
+                //...
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

…​and a request body.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+
+                // JSON and XML formats of request body are supported.
+                // Format will be determined from a header or body's content.
+                body '''{ "login" : "john", "name": "John The Contract" }'''
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

Body’s format can also be specified explicitly by invoking one of format functions.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+
+                // In this case body will be formatted as XML.
+                body equalToXml(
+                                '''<user><login>john</login><name>John The Contract</name></user>'''
+                )
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+
+

Response

+
+

Minimal response must contain HTTP status code.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+        }
+        response {
+                // Status code sent by the server
+                // in response to request specified above.
+                status 200
+        }
+}
+
+
+
+

Besides status response may contain headers and body, which are specified the same way as in the request (see previous paragraph).

+
+
+
+

Regular expressions

+
+

You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response +should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both +for your test and your server side tests.

+
+
+

Please see the example below:

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                method('GET')
+                url $(client(~/\/[0-9]{2}/), server('/12'))
+        }
+        response {
+                status 200
+                body(
+                                id: value(
+                                                client('123'),
+                                                server(regex('[0-9]+'))
+                                ),
+                                surname: $(
+                                                client('Kowalsky'),
+                                                server('Lewandowski')
+                                ),
+                                name: 'Jan',
+                                created: $(client('2014-02-02 12:23:43'), server(execute('currentDate(it)'))),
+                                correlationId: value(client('5d1f9fef-e0dc-4f3d-a7e4-72d2220dd827'),
+                                                server(regex('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}'))
+                                )
+                )
+                headers {
+                        header 'Content-Type': 'text/plain'
+                }
+        }
+}
+
+
+
+
+

Passing optional parameters

+
+

It is possible to provide optional parameters in your contract. It’s only possible to have optional parameter for the:

+
+
+
    +
  • +

    STUB side of the Request

    +
  • +
  • +

    TEST side of the Response

    +
  • +
+
+
+

Example:

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        priority 1
+        request {
+                method 'POST'
+                url '/users/password'
+                headers {
+                        header 'Content-Type': 'application/json'
+                }
+                body(
+                                email: $(stub(optional(regex(email()))), test('abc@abc.com')),
+                                callback_url: $(stub(regex(hostname())), test('http://partners.com'))
+                )
+        }
+        response {
+                status 404
+                headers {
+                        header 'Content-Type': 'application/json'
+                }
+                body(
+                                code: value(stub("123123"), test(optional("123123")))
+                )
+        }
+}
+
+
+
+

By wrapping a part of the body with the optional() method you are in fact creating a regular expression that should be present 0 or more times.

+
+
+

That way for the example above the following test would be generated if you pick Spock:

+
+
+
+
"""
+ given:
+  def request = given()
+    .header('Content-Type', 'application/json')
+    .body('''{"email":"abc@abc.com","callback_url":"http://partners.com"}''')
+
+ when:
+  def response = given().spec(request)
+    .post("/users/password")
+
+ then:
+  response.statusCode == 404
+  response.header('Content-Type')  == 'application/json'
+ and:
+  DocumentContext parsedJson = JsonPath.parse(response.body.asString())
+  assertThatJson(parsedJson).field("code").matches("(123123)?")
+"""
+
+
+
+

and the following stub:

+
+
+
+
'''
+{
+  "request" : {
+    "url" : "/users/password",
+    "method" : "POST",
+    "bodyPatterns" : [ {
+      "matchesJsonPath" : "$[?(@.email =~ /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4})?/)]"
+    }, {
+      "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]"
+    } ],
+    "headers" : {
+      "Content-Type" : {
+        "equalTo" : "application/json"
+      }
+    }
+  },
+  "response" : {
+    "status" : 404,
+    "body" : "{\\"code\\":\\"123123\\",\\"message\\":\\"User not found by email == [not.existing@user.com]\\"}",
+    "headers" : {
+      "Content-Type" : "application/json"
+    }
+  },
+  "priority" : 1
+}
+'''
+
+
+
+
+

Executing custom methods on server side

+
+

It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" +in the configuration. Please see the examples below:

+
+
+

Groovy DSL

+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                method 'PUT'
+                url $(client(regex('^/api/[0-9]{2}$')), server('/api/12'))
+                headers {
+                        header 'Content-Type': 'application/json'
+                }
+                body '''\
+                                [{
+                                        "text": "Gonna see you at Warsaw"
+                                }]
+                        '''
+        }
+        response {
+                body (
+                                path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))),
+                                correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)')))
+                )
+                status 200
+        }
+}
+
+
+
+
+

Base Mock Spec

+
+
+
abstract class BaseMockMvcSpec extends Specification {
+
+        def setup() {
+                RestAssuredMockMvc.standaloneSetup(new PairIdController())
+        }
+
+        void isProperCorrelationId(Integer correlationId) {
+                assert correlationId == 123456
+        }
+
+        void isEmpty(String value) {
+                assert value == null
+        }
+
+}
+
+
+
+
+
+

JAX-RS support

+
+

Starting with release 0.8.0 we support JAX-RS 2 Client API. Base class needs to define protected WebTarget webTarget and server initialization, right now the only option how to test JAX-RS API is to start a web server.

+
+
+

Request with a body needs to have a content type set otherwise application/octet-stream is going to be used.

+
+
+

In order to use JAX-RS mode, use the following settings:

+
+
+
+
testMode == 'JAXRSCLIENT'
+
+
+
+

Example of a test API generated:

+
+
+
+
'''
+ // when:
+  Response response = webTarget
+    .path("/users")
+    .queryParam("limit", "10")
+    .queryParam("offset", "20")
+    .queryParam("filter", "email")
+    .queryParam("sort", "name")
+    .queryParam("search", "55")
+    .queryParam("age", "99")
+    .queryParam("name", "Denis.Stepanov")
+    .queryParam("email", "bob@email.com")
+    .request()
+    .method("GET");
+
+  String responseAsString = response.readEntity(String.class);
+
+ // then:
+  assertThat(response.getStatus()).isEqualTo(200);
+ // and:
+  DocumentContext parsedJson = JsonPath.parse(responseAsString);
+  assertThatJson(parsedJson).field("property1").isEqualTo("a");
+'''
+
+
+
+
+

Messaging Top-Level Elements

+
+ + + + + +
+ + +Feature available since {messaging_version} +
+
+
+

The DSL for messaging looks a little bit different than the one that focuses on HTTP.

+
+
+

Output triggered by a method

+
+

The output message can be triggered by calling a method (e.g. a Scheduler was started and a message was sent)

+
+
+
+
def dsl = GroovyDsl.make {
+        // Human readable description
+        description 'Some description'
+        // Label by means of which the output message can be triggered
+        label 'some_label'
+        // input to the contract
+        input {
+                // the contract will be triggered by a method
+                triggeredBy('bookReturnedTriggered()')
+        }
+        // output message of the contract
+        outputMessage {
+                // destination to which the output message will be sent
+                sentTo('output')
+                // the body of the output message
+                body('''{ "bookName" : "foo" }''')
+                // the headers of the output message
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

In this case the output message will be sent to output if a method called bookReturnedTriggered will be executed. In the message publisher’s side +we will generate a test that will call that method to trigger the message. On the consumer side you can use the some_label to trigger the message.

+
+
+
+

Output triggered by a message

+
+

The output message can be triggered by receiving a message.

+
+
+
+
def dsl = GroovyDsl.make {
+        description 'Some Description'
+        label 'some_label'
+        // input is a message
+        input {
+                // the message was received from this destination
+                messageFrom('input')
+                // has the following body
+                messageBody([
+                        bookName: 'foo'
+                ])
+                // and the following headers
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo('output')
+                body([
+                        bookName: 'foo'
+                ])
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

In this case the output message will be sent to output if a proper message will be received on the input destination. In the message publisher’s side +we will generate a test that will send the input message to the defined destination. On the consumer side you can either send a message to the input +destination or use the some_label to trigger the message.

+
+
+
+

Consumer / Producer

+
+

In HTTP you have a notion of client/stub and `server/test notation. You can use them also in messaging but we’re providing also the consumer and produer methods +as presented below (note you can use either $ or value methods to provide consumer and producer parts)

+
+
+
+
Accurest.make {
+        label 'some_label'
+        input {
+                messageFrom value(consumer('jms:output'), producer('jms:input'))
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo $(consumer('jms:input'), producer('jms:output'))
+                body([
+                                bookName: 'foo'
+                ])
+        }
+}
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/src/main/asciidoc/deprecated/images/Deps.png b/docs/src/main/asciidoc/deprecated/images/Deps.png new file mode 100644 index 0000000000000000000000000000000000000000..1426814308101b8ccf6ef95fd195e37c0a180392 GIT binary patch literal 37192 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 A(f|Me literal 0 HcmV?d00001 diff --git a/docs/src/main/asciidoc/deprecated/images/Stubs1.png b/docs/src/main/asciidoc/deprecated/images/Stubs1.png new file mode 100644 index 0000000000000000000000000000000000000000..ebadfdb91014284b917367e3d9c9c8a137da3993 GIT binary patch literal 35170 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 literal 0 HcmV?d00001 diff --git a/docs/src/main/asciidoc/deprecated/index.html b/docs/src/main/asciidoc/deprecated/index.html new file mode 100644 index 0000000000..a0ed7a1410 --- /dev/null +++ b/docs/src/main/asciidoc/deprecated/index.html @@ -0,0 +1,3914 @@ + + + + + + + +Accurest + + + + + + + +
+
+
+
+

Adam Dudczak, Marcin Grzejszczak, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła

+
+
+
+
+

Introduction

+
+
+

Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped +with Contract Definition Language (DSL). Contract definitions are used by Accurest to produce following resources:

+
+
+
    +
  • +

    JSON stub definitions to be used by Wiremock when doing integration testing on the client code (client tests). +Test code must still be written by hand, test data is produced by Accurest.

    +
  • +
  • +

    Messaging routes if you’re using one. We’re integrating with Spring Integration, Spring Cloud Stream and Apache Camel. You can however set your own integrations if you want to

    +
  • +
  • +

    Acceptance tests (in JUnit or Spock) used to verify if server-side implementation of the API is compliant with the contract (server tests). Full test is generated by Accurest.

    +
  • +
+
+
+

Accurest moves TDD to the level of software architecture.

+
+
+

Why?

+
+

Let us assume that we have a system comprising of multiple microservices:

+
+
+
+Microservices Architecture +
+
+
+

Testing issues

+
+

If we wanted to test the application in top left corner if it can communicate with other services then we could do one of two things:

+
+
+
    +
  • +

    deploy all microservices and perform end to end tests

    +
  • +
  • +

    mock other microservices in unit / integration tests

    +
  • +
+
+
+

Both have their advantages but also a lot of disadvantages. Let’s focus on the latter.

+
+
+

Deploy all microservices and perform end to end tests

+
+
+

Advantages:

+
+
+
    +
  • +

    simulates production

    +
  • +
  • +

    tests real communication between services

    +
  • +
+
+
+

Disadvantages:

+
+
+
    +
  • +

    to test one microservice we would have to deploy 6 microservices, a couple of databases etc.

    +
  • +
  • +

    the environment where the tests would be conducted would be locked for a single suite of tests (i.e. nobody else would be able to run the tests in the meantime).

    +
  • +
  • +

    long to run

    +
  • +
  • +

    very late feedback

    +
  • +
  • +

    extremely hard to debug

    +
  • +
+
+
+

Mock other microservices in unit / integration tests

+
+
+

Advantages:

+
+
+
    +
  • +

    very fast feedback

    +
  • +
  • +

    no infrastructure requirements

    +
  • +
+
+
+

Disadvantages:

+
+
+
    +
  • +

    the implementor of the service creates stubs thus they might have nothing to do with the reality

    +
  • +
  • +

    you can go to production with passing tests and failing production

    +
  • +
+
+
+

To solve the aforementioned issues Accurest with Stub Runner were created. Their main idea is to give you very fast feedback, without the need +to set up the whole world of microservices.

+
+
+
+Stubbed Services +
+
+
+

If you work on stubs then the only applications you need are those that your application is using directly.

+
+
+
+Stubbed Services +
+
+
+

Accurest gives you the certainty that the stubs that you’re using were created by the service that you’re calling. Also if you can use them it means that they were +tested against the producer’s side. In other words - you can trust those stubs.

+
+
+
+
+

Purposes

+
+

The main purposes of Accurest with Stub Runner are:

+
+
+
    +
  • +

    to ensure that WireMock / Messaging stubs (used when developing the client) are doing exactly what actual server-side implementation will do,

    +
  • +
  • +

    to promote ATDD method and Microservices architectural style,

    +
  • +
  • +

    to provide a way to publish changes in contracts that are immediately visible on both sides,

    +
  • +
  • +

    to generate boilerplate test code used on the server side.

    +
  • +
+
+
+
+

Client Side

+
+

During the tests you want to have a Wiremock instance / Messaging route 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 and 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

+
+

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.

+
+
+
+

Dependencies

+
+

Accurest and Stub Runner are using the following libraries

+
+ +
+
+ +
+

Below you can find some resources related to Accurest and Stub Runner. Note that some can be outdated since the Accurest project +is under constant development.

+
+
+

Videos

+
+

Olga Maciaszek-Sharma talking about Accurest

+
+
+
+ +
+
+
+

Marcin Grzejszczak and Jakub Kubryński talking about Accurest

+
+
+
+ +
+
+
+ +
+
+

Samples

+
+

Here you can find some working samples. Check the readme of each project for more information.

+
+
+
+
+
+

Contract DSL

+
+
+

Contract DSL in Accurest is written in Groovy, but don’t be alarmed if you didn’t use Groovy before. Knowledge of the language is not really needed as our DSL uses only +a tiny subset of it (namely literals, method calls and closures). What’s more, Accurest’s DSL is designed to be programmer-readable without any knowledge of the DSL itself - + it’s statically typed.

+
+
+ + + + + +
+ + +Since 1.1.0 you can use the io.codearte.accurest.dsl.Accurest class in your DSL files. +
+
+
+

Let’s look at full example of a contract definition.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                method 'PUT'
+                url '/api/12'
+                headers {
+                        header 'Content-Type': 'application/vnd.com.ofg.twitter-places-analyzer.v1+json'
+                }
+                body '''\
+                [{
+                        "created_at": "Sat Jul 26 09:38:57 +0000 2014",
+                        "id": 492967299297845248,
+                        "id_str": "492967299297845248",
+                        "text": "Gonna see you at Warsaw",
+                        "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"
+                        }
+                }]
+        '''
+        }
+        response {
+                status 200
+        }
+}
+
+
+
+

Not all features of the DSL are used in example above. If you didn’t find what you are looking for, please check next paragraphs on this page.

+
+
+
+
+

You can easily compile Accurest Contracts to WireMock stubs mapping using standalone maven command: mvn io.codearte.accurest:accurest-maven-plugin:convert.

+
+
+
+
+

Limitations

+
+ + + + + +
+ + +Accurest doesn’t support XML properly. Please use JSON or help us implement this feature. +
+
+
+ + + + + +
+ + +Accurest supports equality check on text response. Regular expressions are not yet available. +
+
+
+
+

HTTP Top-Level Elements

+
+

Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        // Definition of HTTP request part of the contract
+        // (this can be a valid request or invalid depending
+        // on type of contract being specified).
+        request {
+                //...
+        }
+
+        // Definition of HTTP response part of the contract
+        // (a service implementing this contract should respond
+        // with following response after receiving request
+        // specified in "request" part above).
+        response {
+                //...
+        }
+
+        // Contract priority, which can be used for overriding
+        // contracts (1 is highest). Priority is optional.
+        priority 1
+}
+
+
+
+
+

Request

+
+

HTTP protocol requires only method and address to be specified in a request. The same information is mandatory in request definition of Accurest contract.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                // HTTP request method (GET/POST/PUT/DELETE).
+                method 'GET'
+
+                // Path component of request URL is specified as follows.
+                urlPath('/users')
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

It is possible to specify whole url instead of just path, but urlPath is the recommended way as it makes the tests host-independent.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                method 'GET'
+
+                // Specifying `url` and `urlPath` in one contract is illegal.
+                url('http://localhost:8888/users')
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

Request may contain query parameters, which are specified in a closure nested in a call to urlPath or url.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+
+                urlPath('/users') {
+
+                        // Each parameter is specified in form
+                        // `'paramName' : paramValue` where parameter value
+                        // may be a simple literal or one of matcher functions,
+                        // all of which are used in this example.
+                        queryParameters {
+
+                                // If a simple literal is used as value
+                                // default matcher function is used (equalTo)
+                                parameter 'limit': 100
+
+                                // `equalTo` function simply compares passed value
+                                // using identity operator (==).
+                                parameter 'filter': equalTo("email")
+
+                                // `containing` function matches strings
+                                // that contains passed substring.
+                                parameter 'gender': value(stub(containing("[mf]")), server('mf'))
+
+                                // `matching` function tests parameter
+                                // against passed regular expression.
+                                parameter 'offset': value(stub(matching("[0-9]+")), server(123))
+
+                                // `notMatching` functions tests if parameter
+                                // does not match passed regular expression.
+                                parameter 'loginStartsWith': value(stub(notMatching(".{0,2}")), server(3))
+                        }
+                }
+
+                //...
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

It may contain additional request headers…​

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+
+                // Each header is added in form `'Header-Name' : 'Header-Value'`.
+                headers {
+                        header 'Content-Type': 'application/json'
+                }
+
+                //...
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

…​and a request body.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+
+                // JSON and XML formats of request body are supported.
+                // Format will be determined from a header or body's content.
+                body '''{ "login" : "john", "name": "John The Contract" }'''
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+

Body’s format can also be specified explicitly by invoking one of format functions.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+
+                // In this case body will be formatted as XML.
+                body equalToXml(
+                                '''<user><login>john</login><name>John The Contract</name></user>'''
+                )
+        }
+
+        response {
+                //...
+        }
+}
+
+
+
+
+

Response

+
+

Minimal response must contain HTTP status code.

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                //...
+        }
+        response {
+                // Status code sent by the server
+                // in response to request specified above.
+                status 200
+        }
+}
+
+
+
+

Besides status response may contain headers and body, which are specified the same way as in the request (see previous paragraph).

+
+
+
+

Regular expressions

+
+

You can use regular expressions to write your requests in Contract DSL. It is particularly useful when you want to indicate that a given response +should be provided for requests that follow a given pattern. Also, you can use it when you need to use patterns and not exact values both +for your test and your server side tests.

+
+
+

Please see the example below:

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                method('GET')
+                url $(client(~/\/[0-9]{2}/), server('/12'))
+        }
+        response {
+                status 200
+                body(
+                                id: value(
+                                                client('123'),
+                                                server(regex('[0-9]+'))
+                                ),
+                                surname: $(
+                                                client('Kowalsky'),
+                                                server('Lewandowski')
+                                ),
+                                name: 'Jan',
+                                created: $(client('2014-02-02 12:23:43'), server(execute('currentDate(it)'))),
+                                correlationId: value(client('5d1f9fef-e0dc-4f3d-a7e4-72d2220dd827'),
+                                                server(regex('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}'))
+                                )
+                )
+                headers {
+                        header 'Content-Type': 'text/plain'
+                }
+        }
+}
+
+
+
+
+

Passing optional parameters

+
+

It is possible to provide optional parameters in your contract. It’s only possible to have optional parameter for the:

+
+
+
    +
  • +

    STUB side of the Request

    +
  • +
  • +

    TEST side of the Response

    +
  • +
+
+
+

Example:

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        priority 1
+        request {
+                method 'POST'
+                url '/users/password'
+                headers {
+                        header 'Content-Type': 'application/json'
+                }
+                body(
+                                email: $(stub(optional(regex(email()))), test('abc@abc.com')),
+                                callback_url: $(stub(regex(hostname())), test('http://partners.com'))
+                )
+        }
+        response {
+                status 404
+                headers {
+                        header 'Content-Type': 'application/json'
+                }
+                body(
+                                code: value(stub("123123"), test(optional("123123")))
+                )
+        }
+}
+
+
+
+

By wrapping a part of the body with the optional() method you are in fact creating a regular expression that should be present 0 or more times.

+
+
+

That way for the example above the following test would be generated if you pick Spock:

+
+
+
+
"""
+ given:
+  def request = given()
+    .header('Content-Type', 'application/json')
+    .body('''{"email":"abc@abc.com","callback_url":"http://partners.com"}''')
+
+ when:
+  def response = given().spec(request)
+    .post("/users/password")
+
+ then:
+  response.statusCode == 404
+  response.header('Content-Type')  == 'application/json'
+ and:
+  DocumentContext parsedJson = JsonPath.parse(response.body.asString())
+  assertThatJson(parsedJson).field("code").matches("(123123)?")
+"""
+
+
+
+

and the following stub:

+
+
+
+
'''
+{
+  "request" : {
+    "url" : "/users/password",
+    "method" : "POST",
+    "bodyPatterns" : [ {
+      "matchesJsonPath" : "$[?(@.email =~ /([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\\\.[a-zA-Z]{2,4})?/)]"
+    }, {
+      "matchesJsonPath" : "$[?(@.callback_url =~ /((http[s]?|ftp):\\\\/)\\\\/?([^:\\\\/\\\\s]+)(:[0-9]{1,5})?/)]"
+    } ],
+    "headers" : {
+      "Content-Type" : {
+        "equalTo" : "application/json"
+      }
+    }
+  },
+  "response" : {
+    "status" : 404,
+    "body" : "{\\"code\\":\\"123123\\",\\"message\\":\\"User not found by email == [not.existing@user.com]\\"}",
+    "headers" : {
+      "Content-Type" : "application/json"
+    }
+  },
+  "priority" : 1
+}
+'''
+
+
+
+
+

Executing custom methods on server side

+
+

It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" +in the configuration. Please see the examples below:

+
+
+

Groovy DSL

+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        request {
+                method 'PUT'
+                url $(client(regex('^/api/[0-9]{2}$')), server('/api/12'))
+                headers {
+                        header 'Content-Type': 'application/json'
+                }
+                body '''\
+                                [{
+                                        "text": "Gonna see you at Warsaw"
+                                }]
+                        '''
+        }
+        response {
+                body (
+                                path: $(client('/api/12'), server(regex('^/api/[0-9]{2}$'))),
+                                correlationId: $(client('1223456'), server(execute('isProperCorrelationId($it)')))
+                )
+                status 200
+        }
+}
+
+
+
+
+

Base Mock Spec

+
+
+
abstract class BaseMockMvcSpec extends Specification {
+
+        def setup() {
+                RestAssuredMockMvc.standaloneSetup(new PairIdController())
+        }
+
+        void isProperCorrelationId(Integer correlationId) {
+                assert correlationId == 123456
+        }
+
+        void isEmpty(String value) {
+                assert value == null
+        }
+
+}
+
+
+
+
+
+

JAX-RS support

+
+

Starting with release 0.8.0 we support JAX-RS 2 Client API. Base class needs to define protected WebTarget webTarget and server initialization, right now the only option how to test JAX-RS API is to start a web server.

+
+
+

Request with a body needs to have a content type set otherwise application/octet-stream is going to be used.

+
+
+

In order to use JAX-RS mode, use the following settings:

+
+
+
+
testMode == 'JAXRSCLIENT'
+
+
+
+

Example of a test API generated:

+
+
+
+
'''
+ // when:
+  Response response = webTarget
+    .path("/users")
+    .queryParam("limit", "10")
+    .queryParam("offset", "20")
+    .queryParam("filter", "email")
+    .queryParam("sort", "name")
+    .queryParam("search", "55")
+    .queryParam("age", "99")
+    .queryParam("name", "Denis.Stepanov")
+    .queryParam("email", "bob@email.com")
+    .request()
+    .method("GET");
+
+  String responseAsString = response.readEntity(String.class);
+
+ // then:
+  assertThat(response.getStatus()).isEqualTo(200);
+ // and:
+  DocumentContext parsedJson = JsonPath.parse(responseAsString);
+  assertThatJson(parsedJson).field("property1").isEqualTo("a");
+'''
+
+
+
+
+

Messaging Top-Level Elements

+
+ + + + + +
+ + +Feature available since 1.1.0 +
+
+
+

The DSL for messaging looks a little bit different than the one that focuses on HTTP.

+
+
+

Output triggered by a method

+
+

The output message can be triggered by calling a method (e.g. a Scheduler was started and a message was sent)

+
+
+
+
def dsl = GroovyDsl.make {
+        // Human readable description
+        description 'Some description'
+        // Label by means of which the output message can be triggered
+        label 'some_label'
+        // input to the contract
+        input {
+                // the contract will be triggered by a method
+                triggeredBy('bookReturnedTriggered()')
+        }
+        // output message of the contract
+        outputMessage {
+                // destination to which the output message will be sent
+                sentTo('output')
+                // the body of the output message
+                body('''{ "bookName" : "foo" }''')
+                // the headers of the output message
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

In this case the output message will be sent to output if a method called bookReturnedTriggered will be executed. In the message publisher’s side +we will generate a test that will call that method to trigger the message. On the consumer side you can use the some_label to trigger the message.

+
+
+
+

Output triggered by a message

+
+

The output message can be triggered by receiving a message.

+
+
+
+
def dsl = GroovyDsl.make {
+        description 'Some Description'
+        label 'some_label'
+        // input is a message
+        input {
+                // the message was received from this destination
+                messageFrom('input')
+                // has the following body
+                messageBody([
+                        bookName: 'foo'
+                ])
+                // and the following headers
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo('output')
+                body([
+                        bookName: 'foo'
+                ])
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

In this case the output message will be sent to output if a proper message will be received on the input destination. In the message publisher’s side +we will generate a test that will send the input message to the defined destination. On the consumer side you can either send a message to the input +destination or use the some_label to trigger the message.

+
+
+
+

Consumer / Producer

+
+

In HTTP you have a notion of client/stub and `server/test notation. You can use them also in messaging but we’re providing also the consumer and produer methods +as presented below (note you can use either $ or value methods to provide consumer and producer parts)

+
+
+
+
Accurest.make {
+        label 'some_label'
+        input {
+                messageFrom value(consumer('jms:output'), producer('jms:input'))
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo $(consumer('jms:input'), producer('jms:output'))
+                body([
+                                bookName: 'foo'
+                ])
+        }
+}
+
+
+
+
+
+
+
+

Accurest HTTP

+
+
+

Gradle Project

+
+

Prerequisites

+
+

In order to use Accurest with Wiremock you have to use gradle or maven plugin.

+
+
+
Add gradle plugin
+
+
+
buildscript {
+        repositories {
+                mavenCentral()
+        }
+        dependencies {
+                classpath 'io.codearte.accurest:accurest-gradle-plugin:${accurest_version}'
+        }
+}
+
+apply plugin: 'groovy'
+apply plugin: 'accurest'
+
+dependencies {
+        testCompile 'org.codehaus.groovy:groovy-all:2.4.6'
+        testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
+        testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' // needed if you're going to use Spring MockMvc
+}
+
+
+
+
+
Add maven plugin
+
+
+
<plugin>
+    <groupId>io.codearte.accurest</groupId>
+    <artifactId>accurest-maven-plugin</artifactId>
+    <executions>
+        <execution>
+            <goals>
+                <goal>convert</goal>
+                <goal>generateStubs</goal>
+                <goal>generateTests</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+
+
+
+

Read more: accurest-maven-plugin

+
+
+
+
Add stubs
+
+

By default Accurest is looking for stubs in src/test/resources/accurest 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/accurest/myservice/shouldCreateUser.groovy
+src/test/resources/accurest/myservice/shouldReturnUser.groovy
+
+
+
+

Accurest will create test class defaultBasePackage.MyService with two methods

+
+
+
    +
  • +

    shouldCreateUser()

    +
  • +
  • +

    shouldReturnUser()

    +
  • +
+
+
+
+
+

Run plugin

+
+

Plugin registers itself to be invoked before check 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 = project.file('src/accurest')
+}
+
+
+
+
Configuration options
+
+
    +
  • +

    testMode - defines mode for acceptance tests. By default MockMvc which is based on Spring’s MockMvc. It can also be changed to JaxRsClient or to Explicit for real HTTP calls.

    +
  • +
  • +

    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 []

    +
  • +
  • +

    basePackageForTests - specifies base package for all generated tests. By default set to io.codearte.accurest.tests

    +
  • +
  • +

    baseClassForTests - base class for generated tests. By default spock.lang.Specification if using Spock tests.

    +
  • +
  • +

    ruleClassForTests - specifies Rule which should be added to generated test classes.

    +
  • +
  • +

    ignoredFiles - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array []

    +
  • +
  • +

    contractsDslDir - directory containing contracts written using the GroovyDSL. By default $rootDir/src/test/resources/accurest

    +
  • +
  • +

    generatedTestSourcesDir - test source directory where tests generated from Groovy DSL should be placed. By default $buildDir/generated-test-sources/accurest

    +
  • +
  • +

    stubsOutputDir - dir where the generated Wiremock stubs from Groovy DSL should be placed

    +
  • +
  • +

    targetFramework - the target test framework to be used; currently Spock and JUnit are supported with JUnit being the default framework

    +
  • +
+
+
+
+
Base class for tests
+
+

When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified.

+
+
+
+
abstract class BaseMockMvcSpec extends Specification {
+
+        def setup() {
+                RestAssuredMockMvc.standaloneSetup(new PairIdController())
+        }
+
+        void isProperCorrelationId(Integer correlationId) {
+                assert correlationId == 123456
+        }
+
+        void isEmpty(String value) {
+                assert value == null
+        }
+
+}
+
+
+
+

In case of using Explicit mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of JAXRSCLIENT mode this base class +should also contain protected WebTarget webTarget field, right now the only option to test JAX-RS API is to start a web server.

+
+
+
+
+

Invoking generated tests

+
+

To ensure that provider side is complaint with defined contracts, you need to invoke:

+
+
+
+
./gradlew generateAccurest test
+
+
+
+
+

Accurest on consumer side

+
+

In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. If you don’t want to use Stub Runner then you need to copy contracts stored in +src/test/resources/accurest and generate WireMock json stubs using:

+
+
+
+
./gradlew generateWireMockClientStubs
+
+
+
+

Note that stubsOutputDir option has to be set for stub generation to work.

+
+
+

When present, json stubs can be used in consumer automated tests.

+
+
+
+
@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
+class LoanApplicationServiceSpec extends Specification {
+
+ @ClassRule
+ @Shared
+ WireMockClassRule wireMockRule == new WireMockClassRule()
+
+ @Autowired
+ LoanApplicationService sut
+
+ def 'should successfully apply for loan'() {
+   given:
+         LoanApplication application =
+                        new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123)
+   when:
+        LoanApplicationResult loanApplication == sut.loanApplication(application)
+   then:
+        loanApplication.loanApplicationStatus === LoanApplicationStatus.LOAN_APPLIED
+        loanApplication.rejectionReason === null
+ }
+}
+
+
+
+

Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest.

+
+
+
+
+

Using in your Maven project

+
+

Add maven plugin

+
+
+
<plugin>
+    <groupId>io.codearte.accurest</groupId>
+    <artifactId>accurest-maven-plugin</artifactId>
+    <executions>
+        <execution>
+            <goals>
+                <goal>convert</goal>
+                <goal>generateStubs</goal>
+                <goal>generateTests</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+
+
+
+

Read more: accurest-maven-plugin

+
+
+
+

Add stubs

+
+

By default Accurest is looking for stubs in src/test/resources/accurest 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/accurest/myservice/shouldCreateUser.groovy
+src/test/resources/accurest/myservice/shouldReturnUser.groovy
+
+
+
+

Accurest will create test class defaultBasePackage.MyService with two methods + - shouldCreateUser() + - shouldReturnUser()

+
+
+
+

Run plugin

+
+

Plugin goal generateTests is assigned to be invoked in phase generate-test-sources. 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 generateTests goal.

+
+
+
+

Configure plugin

+
+

To change default configuration just add configuration section to plugin definition or execution definition.

+
+
+
+
<plugin>
+    <groupId>io.codearte.accurest</groupId>
+    <artifactId>accurest-maven-plugin</artifactId>
+    <executions>
+        <execution>
+            <goals>
+                <goal>convert</goal>
+                <goal>generateStubs</goal>
+                <goal>generateTests</goal>
+            </goals>
+        </execution>
+    </executions>
+    <configuration>
+        <basePackageForTests>com.ofg.twitter.place</basePackageForTests>
+        <baseClassForTests>com.ofg.twitter.place.BaseMockMvcSpec</baseClassForTests>
+    </configuration>
+</plugin>
+
+
+
+
Important configuration options
+
+
    +
  • +

    testMode - defines mode for acceptance tests. By default MockMvc which is based on Spring’s MockMvc. It can also be changed to JaxRsClient or to Explicit for real HTTP calls.

    +
  • +
  • +

    basePackageForTests - specifies base package for all generated tests. By default set to io.codearte.accurest.tests.

    +
  • +
  • +

    ruleClassForTests - specifies Rule which should be added to generated test classes.

    +
  • +
  • +

    baseClassForTests - base class for generated tests. By default spock.lang.Specification if using Spock tests.

    +
  • +
  • +

    contractsDir - directory containing contracts written using the GroovyDSL. By default /src/test/resources/accurest.

    +
  • +
  • +

    testFramework - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework

    +
  • +
+
+
+

For complete information take a look at Plugin Documentation

+
+
+
+
Base class for tests
+
+
+
When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified.
+
+
+
+
+
package org.mycompany.tests
+
+import org.mycompany.ExampleSpringController
+import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc
+import spock.lang.Specification
+
+class  MvcSpec extends Specification {
+  def setup() {
+   RestAssuredMockMvc.standaloneSetup(new ExampleSpringController())
+  }
+}
+
+
+
+

In case of using Explicit mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of JAXRSCLIENT mode this base class should also contain protected WebTarget webTarget field, right now the only option to test JAX-RS API is to start a web server.

+
+
+
+
+

Invoking generated tests

+
+

Accurest Maven Plugins generates verification code into directory /generated-test-sources/accurest and attach this directory to testCompile goal.

+
+
+

For Groovy Spock code use:

+
+
+
+
<plugin>
+        <groupId>org.codehaus.gmavenplus</groupId>
+        <artifactId>gmavenplus-plugin</artifactId>
+        <version>1.5</version>
+        <executions>
+                <execution>
+                        <goals>
+                                <goal>testCompile</goal>
+                        </goals>
+                </execution>
+        </executions>
+        <configuration>
+                <testSources>
+                        <testSource>
+                                <directory>${project.basedir}/src/test/groovy</directory>
+                                <includes>
+                                        <include>**/*.groovy</include>
+                                </includes>
+                        </testSource>
+                        <testSource>
+                                <directory>${project.build.directory}/generated-test-sources/accurest</directory>
+                                <includes>
+                                        <include>**/*.groovy</include>
+                                </includes>
+                        </testSource>
+                </testSources>
+        </configuration>
+</plugin>
+
+
+
+

To ensure that provider side is complaint with defined contracts, you need to invoke mvn generateTest test

+
+
+
+

Accurest on consumer side

+
+

In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/accurest and generate Wiremock json stubs using: mvn generateStubs command. By default generated WireMock mapping is stored in directory target/mappings. Your project should create from this generated mappings additional artifact with classifier stubs for easy deploy to maven repository.

+
+
+

Sample configuration:

+
+
+
+
<plugin>
+    <groupId>io.codearte.accurest</groupId>
+    <artifactId>accurest-maven-plugin</artifactId>
+    <version>${accurest-plugin.version}</version>
+    <executions>
+        <execution>
+            <goals>
+                <goal>convert</goal>
+                <goal>generateStubs</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+
+
+
+

When present, json stubs can be used in consumer automated tests.

+
+
+
+
@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
+class LoanApplicationServiceSpec extends Specification {
+
+ @ClassRule
+ @Shared
+ WireMockClassRule wireMockRule == new WireMockClassRule()
+
+ @Autowired
+ LoanApplicationService sut
+
+ def 'should successfully apply for loan'() {
+   given:
+         LoanApplication application =
+                        new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123)
+   when:
+        LoanApplicationResult loanApplication == sut.loanApplication(application)
+   then:
+        loanApplication.loanApplicationStatus === LoanApplicationStatus.LOAN_APPLIED
+        loanApplication.rejectionReason === null
+ }
+}
+
+
+
+

Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest.

+
+
+
+
+

Scenarios

+
+

It’s possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore.

+
+
+
+
my_contracts_dir\
+  scenario1\
+    1_login.groovy
+    2_showCart.groovy
+    3_logout.groovy
+
+
+
+

Such tree will cause Accurest generating Wiremock’s scenario with name scenario1 and three steps: + - login marked as Started pointing to: + - showCart marked as Step1 pointing to: + - logout marked as Step2 which will close the scenario. +More details about Wiremock scenarios can be found under [http://wiremock.org/stateful-behaviour.html](http://wiremock.org/stateful-behaviour.html)

+
+
+

Accurest will also generate tests with guaranteed order of execution.

+
+
+
+
+
+

Accurest Messaging

+
+
+ + + + + +
+ + +Feature available since 1.1.0 +
+
+
+

Accurest allows you to verify your application that uses messaging as means of communication. +All of our integrations are working with Spring but you can also set one yourself.

+
+
+

Integrations

+
+

You can use one of the three integration configurations:

+
+
+
    +
  • +

    Apache Camel

    +
  • +
  • +

    Spring Integration

    +
  • +
  • +

    Spring Cloud Stream

    +
  • +
+
+
+

If you’re using Spring Boot, the aforementioned test configurations will be appended automatically.

+
+
+

You have to provide as a dependency one of the Accurest Messaging modules. Example for Gradle:

+
+
+
+
// for Apache Camel
+testCompile "io.codearte.accurest:accurest-messaging-camel:${accurestVersion}"
+// for Spring Integration
+testCompile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}"
+// for Spring Cloud Stream
+testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}"
+
+
+
+
+

Manual Integration

+
+

The accurest-messaging-core module contains 3 main interfaces:

+
+
+
    +
  • +

    AccurestMessage - describes a message received / sent to a channel / queue / topic etc.

    +
  • +
  • +

    AccurestMessageBuilder - describes how to build a message

    +
  • +
  • +

    AccurestMessaging - class that allows you to build, send and receive messages

    +
  • +
  • +

    AccurestFilter - interface to filter out the messages that do not follow the pattern from the DSL

    +
  • +
+
+
+

In the generated test the AccurestMessaging is injected via @Inject annotation thus you can use other injection +frameworks than Spring.

+
+
+

You have to provide as a dependency the accurest-messaging-core module. Example for Gradle:

+
+
+
+
testCompile "io.codearte.accurest:accurest-messaging-core:${accurestVersion}"
+
+
+
+
+

Publisher side test generation

+
+

Having the input or outputMessage sections in your DSL will result in creation of tests on the publisher’s side. By default +JUnit tests will be created, however there is also a possibility to create Spock tests.

+
+
+

There are 3 main scenarios that we should take into consideration:

+
+
+
    +
  • +

    Scenario 1: there is no input message that produces an output one. The output message is triggered by a component +inside the application (e.g. scheduler)

    +
  • +
  • +

    Scenario 2: the input message triggers an output message

    +
  • +
  • +

    Scenario 3: the input message is consumed and there is no output message

    +
  • +
+
+
+

Scenario 1 (no input message)

+
+

For the given contract:

+
+
+
+
def contractDsl = GroovyDsl.make {
+        label 'some_label'
+        input {
+                triggeredBy('bookReturnedTriggered()')
+        }
+        outputMessage {
+                sentTo('activemq:output')
+                body('''{ "bookName" : "foo" }''')
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

The following JUnit test will be created:

+
+
+
+
'''
+ // when:
+  bookReturnedTriggered();
+
+ // then:
+  AccurestMessage response = accurestMessaging.receiveMessage("activemq:output");
+  assertThat(response).isNotNull();
+  assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo");
+ // and:
+  DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload()));
+  assertThatJson(parsedJson).field("bookName").isEqualTo("foo");
+'''
+
+
+
+

And the following Spock test would be created:

+
+
+
+
'''
+ when:
+  bookReturnedTriggered()
+
+ then:
+  def response = accurestMessaging.receiveMessage('activemq:output')
+  assert response != null
+  response.getHeader('BOOK-NAME')  == 'foo'
+ and:
+  DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
+  assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
+
+'''
+
+
+
+
+

Scenario 2 (output triggered by input)

+
+

For the given contract:

+
+
+
+
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')
+                }
+        }
+}
+
+
+
+

The following JUnit test will be created:

+
+
+
+
'''
+// 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).isNotNull();
+ assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo");
+// and:
+ DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload()));
+ assertThatJson(parsedJson).field("bookName").isEqualTo("foo");
+'''
+
+
+
+

And the following Spock test would be created:

+
+
+
+
"""\
+given:
+   def inputMessage = accurestMessaging.create(
+    '''{"bookName":"foo"}''',
+    ['sample': 'header']
+  )
+
+when:
+   accurestMessaging.send(inputMessage, 'jms:input')
+
+then:
+   def response = accurestMessaging.receiveMessage('jms:output')
+   assert response !- null
+   response.getHeader('BOOK-NAME')  == 'foo'
+and:
+   DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
+   assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
+"""
+
+
+
+
+

Scenario 3 (no output message)

+
+

For the given contract:

+
+
+
+
def contractDsl = GroovyDsl.make {
+        label 'some_label'
+        input {
+                messageFrom('jms:delete')
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+                assertThat('bookWasDeleted()')
+        }
+}
+
+
+
+

The following JUnit test will be created:

+
+
+
+
'''
+// given:
+ AccurestMessage inputMessage = accurestMessaging.create(
+        "{\\"bookName\\":\\"foo\\"}"
+, headers()
+        .header("sample", "header"));
+
+// when:
+ accurestMessaging.send(inputMessage, "jms:delete");
+
+// then:
+ bookWasDeleted();
+'''
+
+
+
+

And the following Spock test would be created:

+
+
+
+
'''
+given:
+         def inputMessage = accurestMessaging.create(
+                \'\'\'{"bookName":"foo"}\'\'\',
+                ['sample': 'header']
+        )
+
+when:
+         accurestMessaging.send(inputMessage, 'jms:delete')
+
+then:
+         noExceptionThrown()
+         bookWasDeleted()
+'''
+
+
+
+
+
+

Consumer Stub Side generation

+
+

Unlike the HTTP part - in Messaging we need to publish the Groovy DSL inside the JAR with a stub. Then it’s parsed on the consumer side +and proper stubbed routes are created.

+
+
+

For more infromation please consult the Stub Runner Messaging sections.

+
+
+

Gradle Setup

+
+

Example of Accurest Gradle setup:

+
+
+
+
ext {
+        contractsDir = file("mappings")
+        stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/")
+        wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/'))
+        contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/'))
+}
+
+task copyContracts(type: Copy) {
+        from contractsDir
+        include '**/*.groovy'
+        into contractsOutputDir
+}
+
+task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) {
+        baseName = "${project.name}"
+        classifier = "stubs"
+        from stubsOutputDirRoot
+}
+
+artifacts {
+        archives stubsJar
+}
+
+publishing {
+        publications {
+                stubs(MavenPublication) {
+                        artifactId "${project.name}-stubs"
+                        artifact stubsJar
+                }
+        }
+}
+
+
+
+
+

Maven Setup

+
+

Example of Maven can be found in the Accurest Maven Plugin README

+
+
+
+
+
+
+

Stub Runner

+
+
+

One of the issues that you could have encountered while using Accurest was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). + The same takes place in terms of client side generation for messaging.

+
+
+

Copying the JSON files / setting the client side for messaging manually is out of the question.

+
+
+

Publishing stubs as JARs

+
+

The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository.

+
+
+

Gradle

+
+

Example of Accurest Gradle setup:

+
+
+
+
ext {
+        contractsDir = file("mappings")
+        stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/")
+        wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/'))
+        contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/'))
+}
+
+task copyContracts(type: Copy) {
+        from contractsDir
+        include '**/*.groovy'
+        into contractsOutputDir
+}
+
+task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) {
+        baseName = "${project.name}"
+        classifier = "stubs"
+        from stubsOutputDirRoot
+}
+
+artifacts {
+        archives stubsJar
+}
+
+publishing {
+        publications {
+                stubs(MavenPublication) {
+                        artifactId "${project.name}-stubs"
+                        artifact stubsJar
+                }
+        }
+}
+
+
+
+
+

Maven

+
+

Example of Maven can be found in the Accurest Maven Plugin README

+
+
+
+
+

Modules

+
+

Accurest comes with a new structure of modules

+
+
+
+
└── stub-runner
+    ├── stub-runner
+    ├── stub-runner-boot
+    ├── stub-runner-junit
+    ├── stub-runner-spring
+    └── stub-runner-spring-cloud
+
+
+
+
+

Stub Runner Core

+
+

Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of +Consumer Driven Contracts.

+
+
+

Stub Runner allows you to automatically download the stubs of the provided dependencies, start WireMock servers for them and feed them with proper stub definitions. +For messaging, special stub routes are defined.

+
+
+

Running stubs

+
+
Running using main app
+
+

You can set the following options to the main class:

+
+
+
+
-maxp (--maxPort) N            : Maximum port value to be assigned to the
+                                 Wiremock instance. Defaults to 15000
+                                 (default: 15000)
+-minp (--minPort) N            : Minimal port value to be assigned to the
+                                 Wiremock instance. Defaults to 10000
+                                 (default: 10000)
+-s (--stubs) VAL               : Comma separated list of Ivy representation of
+                                 jars with stubs. Eg. groupid:artifactid1,group
+                                 id2:artifactid2:version:classifier
+-sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you
+                                 keep your stubs (e.g. http://nexus.net/content
+                                 /repositories/repository)
+-ss (--stubsSuffix) VAL        : Suffix for the jar containing stubs (e.g.
+                                 'stubs' if the stub jar would have a 'stubs'
+                                 classifier for stubs: foobar-stubs ).
+                                 Defaults to 'stubs' (default: stubs)
+-wo (--workOffline)            : Switch to work offline. Defaults to 'false'
+                                 (default: false)
+
+
+
+
+
Building a Fat Jar
+
+

Just call the following command:

+
+
+
+
./gradlew stub-runner-root:stub-runner:shadowJar -PfatJar
+
+
+
+

and inside the build/lib there will be a Fat Jar with classifier fatJar waiting for you to execute. E.g.

+
+
+
+
java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h:i
+
+
+
+
+
+

Stub runner configuration

+
+

You can configure the stub runner by either passing the full arguments list with the -Pargs like this:

+
+
+
+
./gradlew stub-runner-root:stub-runner:run -Pargs="-c pl -minp 10000 -maxp 10005 -s a:b:c,d:e,f:g:h"
+
+
+
+

or each parameter separately with a -P prefix and without the hyphen - in the name of the param

+
+
+
+
./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h
+
+
+
+
HTTP Stubs
+
+

Stubs are defined in JSON documents, whose syntax is defined in WireMock documentation

+
+
+

Example:

+
+
+
+
{
+    "request": {
+        "method": "GET",
+        "url": "/ping"
+    },
+    "response": {
+        "status": 200,
+        "body": "pong",
+        "headers": {
+            "Content-Type": "text/plain"
+        }
+    }
+}
+
+
+
+
+
Viewing registered mappings
+
+

Every stubbed collaborator exposes list of defined mappings under __/admin/ endpoint.

+
+
+
+
Messaging Stubs
+
+

Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up.

+
+
+
+
+
+

Stub Runner Boot

+
+ + + + + +
+ + +Feature available since 1.1.0 +
+
+
+

Accurest Stub Runner Boot is a Spring Boot application that exposes REST endpoints to +trigger the messaging labels and to access started WireMock servers.

+
+
+

One of the usecases is to run some smoke (end to end) tests on a deployed application. You can read + more about this in the "Microservice Deployment" article at Too Much Coding blog.

+
+
+

How to use it?

+
+

Just add the

+
+
+
+
compile "io.codearte.accurest:stub-runner-boot:${accurestVersion}"
+
+
+
+

and a messaging implementation:

+
+
+
+
// for Apache Camel
+compile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}"
+// for Spring Integration
+compile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}"
+// for Spring Cloud Stream
+compile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}"
+
+
+
+

Build a fat-jar and you’re ready to go!

+
+
+

For the properties check the Stub Runner Spring section.

+
+
+
+

Endpoints

+
+
HTTP
+
+
    +
  • +

    GET /stubs - returns a list of all running stubs in ivy:integer notation

    +
  • +
  • +

    GET /stubs/{ivy} - returns a port for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    +
  • +
+
+
+
+
Messaging
+
+

For Messaging

+
+
+
    +
  • +

    GET /triggers - returns a list of all running labels in ivy : [ label1, label2 …​] notation

    +
  • +
  • +

    POST /triggers/{label} - executes a trigger with label

    +
  • +
  • +

    POST /triggers/{ivy}/{label} - executes a trigger with label for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    +
  • +
+
+
+
+
+

Example

+
+
+
@ContextConfiguration(classes = [StubRunnerBootSpec, StubRunnerBoot], loader = SpringApplicationContextLoader)
+@EnableBinding
+@Configuration
+class StubRunnerBootSpec extends Specification {
+
+        @Autowired StubRunning stubRunning
+
+        def setup() {
+                RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning),
+                                new TriggerController(stubRunning))
+        }
+
+        def 'should return a list of running stub servers in "full ivy:port" notation'() {
+                when:
+                        String response = RestAssuredMockMvc.get('/stubs').body.asString()
+                then:
+                        def root = new JsonSlurper().parseText(response)
+                        root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs' instanceof Integer
+        }
+
+        def 'should return a port on which a [#stubId] stub is running'() {
+                when:
+                        def response = RestAssuredMockMvc.get("/stubs/${stubId}")
+                then:
+                        response.statusCode == 200
+                        response.body.as(Integer) > 0
+                where:
+                        stubId << ['io.codearte.accurest.stubs:streamService:+:stubs',
+                                           'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs',
+                                           'io.codearte.accurest.stubs:streamService:+',
+                                           'io.codearte.accurest.stubs:streamService',
+                                           'streamService']
+        }
+
+        def 'should return 404 when missing stub was called'() {
+                when:
+                        def response = RestAssuredMockMvc.get("/stubs/a:b:c:d")
+                then:
+                        response.statusCode == 404
+        }
+
+        def 'should return a list of messaging labels that can be triggered when version and classifier are passed'() {
+                when:
+                        String response = RestAssuredMockMvc.get('/triggers').body.asString()
+                then:
+                        def root = new JsonSlurper().parseText(response)
+                        root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"])
+        }
+
+        def 'should trigger a messaging label'() {
+                given:
+                        StubRunning stubRunning = Mock()
+                        RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning), new TriggerController(stubRunning))
+                when:
+                        def response = RestAssuredMockMvc.post("/triggers/delete_book")
+                then:
+                        response.statusCode == 200
+                and:
+                        1 * stubRunning.trigger('delete_book')
+        }
+
+        def 'should trigger a messaging label for a stub with [#stubId] ivy notation'() {
+                given:
+                        StubRunning stubRunning = Mock()
+                        RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning), new TriggerController(stubRunning))
+                when:
+                        def response = RestAssuredMockMvc.post("/triggers/$stubId/delete_book")
+                then:
+                        response.statusCode == 200
+                and:
+                        1 * stubRunning.trigger(stubId, 'delete_book')
+                where:
+                        stubId << ['io.codearte.accurest.stubs:streamService:stubs', 'io.codearte.accurest.stubs:streamService', 'streamService']
+        }
+
+        def 'should return when trigger is missing'() {
+                when:
+                        def response = RestAssuredMockMvc.post("/triggers/missing_label")
+                then:
+                        response.statusCode == 404
+                        def root = new JsonSlurper().parseText(response.body.asString())
+                        root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"])
+        }
+
+}
+
+
+
+
+
+

Stub Runner JUnit Rule

+
+

Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id:

+
+
+
+
@ClassRule public static AccurestRule rule = new AccurestRule()
+                .repoRoot(repoRoot())
+                .downloadStub("io.codearte.accurest.stubs", "loanIssuance")
+                .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer");
+
+
+
+

After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to:

+
+
+
    +
  • +

    download them

    +
  • +
  • +

    cache them locally

    +
  • +
  • +

    unzip them to a temporary folder

    +
  • +
  • +

    start a WireMock server for each Maven dependency on a random port from the provided range of ports / provided port

    +
  • +
  • +

    feed the WireMock server with all JSON files that are valid WireMock definitions

    +
  • +
+
+
+

Stub Runner uses Eclipse Aether mechanism to download the Maven dependencies. +Check their docs for more information.

+
+
+

Since the AccurestRule implements the StubFinder it allows you to find the started stubs:

+
+
+
+
package io.codearte.accurest.stubrunner
+
+import io.codearte.accurest.dsl.GroovyDsl
+
+interface StubFinder extends StubTrigger {
+        /**
+         * For the given groupId and artifactId tries to find the matching
+         * URL of the running stub.
+         *
+         * @param groupId - might be null. In that case a search only via artifactId takes place
+         * @return URL of a running stub or null if not found
+         */
+        URL findStubUrl(String groupId, String artifactId)
+
+        /**
+         * For the given Ivy notation {@code groupId:artifactId} tries to find the matching
+         * URL of the running stub. You can also pass only {@code artifactId}.
+         *
+         * @param ivyNotation - Ivy representation of the Maven artifact
+         * @return URL of a running stub or null if not found
+         */
+        URL findStubUrl(String ivyNotation)
+
+        /**
+         * Returns all running stubs
+         */
+        RunningStubs findAllRunningStubs()
+
+        /**
+         * Returns the list of Accurest contracts
+         */
+        Map<StubConfiguration, Collection<GroovyDsl>> getAccurestContracts()
+}
+
+
+
+

Example of usage in Spock tests:

+
+
+
+
@ClassRule @Shared AccurestRule rule = new AccurestRule()
+                .repoRoot(AccurestRuleSpec.getResource("/m2repo").toURI().toString())
+                .downloadStub("io.codearte.accurest.stubs", "loanIssuance")
+                .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer")
+
+def 'should start WireMock servers'() {
+        expect: 'WireMocks are running'
+                rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null
+                rule.findStubUrl('loanIssuance') != null
+                rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance')
+                rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null
+        and:
+                rule.findAllRunningStubs().isPresent('loanIssuance')
+                rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer')
+                rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer')
+        and: 'Stubs were registered'
+                "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
+                "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
+}
+
+
+
+

Example of usage in JUnit tests:

+
+
+
+
@Test
+public void should_start_wiremock_servers() throws Exception {
+        // expect: 'WireMocks are running'
+                then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull();
+                then(rule.findStubUrl("loanIssuance")).isNotNull();
+                then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance"));
+                then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull();
+        // and:
+                then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue();
+                then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue();
+                then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue();
+        // and: 'Stubs were registered'
+                then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance");
+                then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer");
+}
+
+
+
+

Check the Common properties for JUnit and Spring for more information on how to apply global configuration of Stub Runner.

+
+
+

Providing fixed ports

+
+

You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of +JUnit rule.

+
+
+
+

Fluent API

+
+

When using the AccurestRule you can add a stub to download and then pass the port for the last downloaded stub.

+
+
+
+
@ClassRule public static AccurestRule rule = new AccurestRule()
+                .repoRoot(repoRoot())
+                .downloadStub("io.codearte.accurest.stubs", "loanIssuance")
+                .withPort(12345)
+                .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:12346");
+
+
+
+

You can see that for this example the following test is valid:

+
+
+
+
then(rule.findStubUrl("loanIssuance")).isEqualTo(URI.create("http://localhost:12345").toURL());
+then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL());
+
+
+
+
+
+

Stub Runner Spring

+
+

Sets up Spring configuration of the Stub Runner project.

+
+
+

By providing a list of stubs inside your configuration file the Stub Runner automatically downloads +and registers in WireMock the selected stubs.

+
+
+

If you want to find the URL of your stubbed dependency you can autowire the StubFinder interface and use +its methods as presented below:

+
+
+
+
@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader)
+class StubRunnerConfigurationSpec extends Specification {
+
+        @Autowired StubFinder stubFinder
+
+        def 'should start WireMock servers'() {
+                expect: 'WireMocks are running'
+                        stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null
+                        stubFinder.findStubUrl('loanIssuance') != null
+                        stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance')
+                        stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null
+                and:
+                        stubFinder.findAllRunningStubs().isPresent('loanIssuance')
+                        stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer')
+                        stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer')
+                and: 'Stubs were registered'
+                        "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
+                        "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
+        }
+
+        @Configuration
+        @Import(StubRunnerConfiguration)
+        @EnableAutoConfiguration
+        static class Config {}
+}
+
+
+
+

for the following configuration file:

+
+
+
+
stubrunner.stubs.repository.root: classpath:m2repo/repository/
+stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer
+
+
+
+
+

Stub Runner Spring Cloud

+
+

Registers the stubs in the provided Service Discovery. It’s enough to add the jar

+
+
+
+
io.codearte.accurest:stub-runner-spring-cloud
+
+
+
+

and the Stub Runner autoconfiguration should be picked up.

+
+
+

Stubbing Service Discovery

+
+

The most important feature of Stub Runner Spring Cloud is the fact that it’s stubbing

+
+
+
    +
  • +

    DiscoveryClient

    +
  • +
  • +

    Ribbon ServerList

    +
  • +
+
+
+

that means that regardles of the fact whether you’re using Zookeeper, Consul, Eureka or anything else, you don’t need that in your tests. +We’re starting WireMock instances of your dependencies and we’re telling your application whenever you’re using Feign, load balanced RestTemplate +or DiscoveryClient directly, to call those stubbed servers instead of calling the real Service Discovery tool.

+
+
+
+

Additional Configuration

+
+

You can match the artifactId of the stub with the name of your app by using the stubrunner.stubs.idsToServiceIds: map. +You can disable Stub Runner Ribbon support by providing: stubrunner.cloud.ribbon.enabled equal to false +You can disable Stub Runner support by providing: stubrunner.cloud.enabled equal to false

+
+
+
+
+

Common properties for JUnit and Spring

+
+

Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values:

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Property nameDefault valueDescription

stubrunner.port.range.min

10000

Minimal value of a port for a started WireMock with stubs

stubrunner.port.range.max

15000

Minimal value of a port for a started WireMock with stubs

stubrunner.stubs.repository.root

Comma separated list of Maven repo urls. If blank then will call the local maven repo

stubrunner.stubs.classifier

stubs

Default classifier for the stub artifacts

stubrunner.work-offline

false

If true then will not contact any remote repositories to download stubs

stubrunner.stubs.ids

Comma separated list of Ivy notation of stubs to download

+
+

Stub runner stubs ids

+
+

You can provide the stubs to download via the stubrunner.stubs.ids system property. They follow the following pattern:

+
+
+
+
groupId:artifactId:version:classifier:port
+
+
+
+

version, classifier and port are optional.

+
+
+
    +
  • +

    If you don’t provide the port then a random one will be picked

    +
  • +
  • +

    If you don’t provide the classifier then the default one will be taken.

    +
  • +
  • +

    If you don’t provide the version then the + will be passed and the latest one will be downloaded

    +
  • +
+
+
+

Where port means the port of the WireMock server.

+
+
+
+
+
+
+

Stub Runner for Messaging

+
+
+ + + + + +
+ + +Feature available since 1.1.0 +
+
+
+

Stub Runner has the functionality to run the published stubs in memory. It can integrate with the following frameworks out of the box

+
+
+
    +
  • +

    Spring Integration

    +
  • +
  • +

    Spring Cloud Stream

    +
  • +
  • +

    Apache Camel

    +
  • +
+
+
+

It also provides points of entry to integrate with any other solution on the market.

+
+
+

Stub triggering

+
+

To trigger a message it’s enough to use the StubTigger interface:

+
+
+
+
package io.codearte.accurest.stubrunner
+
+interface StubTrigger {
+
+        /**
+         * Triggers an event by a given label for a given {@code groupid:artifactid} notation. You can use only {@code artifactId} too.
+         *
+         * Feature related to messaging.
+         *
+         * @return true - if managed to run a trigger
+         */
+        boolean trigger(String ivyNotation, String labelName)
+
+        /**
+         * Triggers an event by a given label.
+         *
+         * Feature related to messaging.
+         *
+         * @return true - if managed to run a trigger
+         */
+        boolean trigger(String labelName)
+
+        /**
+         * Triggers all possible events.
+         *
+         * Feature related to messaging.
+         *
+         * @return true - if managed to run a trigger
+         */
+        boolean trigger()
+
+        /**
+         * Returns a mapping of ivy notation of a dependency to all the labels it has.
+         *
+         * Feature related to messaging.
+         */
+        Map<String, Collection<String>> labels()
+}
+
+
+
+

For convenience the StubFinder interface extends StubTrigger so it’s enough to use only one in your tests.

+
+
+

StubTrigger gives you the following options to trigger a message:

+
+
+

Trigger by label

+
+
+
stubFinder.trigger('return_book_1')
+
+
+
+
Trigger by group and artifact ids
+
+
+
stubFinder.trigger('io.codearte.accurest.stubs:camelService', 'return_book_1')
+
+
+
+
+
Trigger by artifact ids
+
+
+
stubFinder.trigger('camelService', 'return_book_1')
+
+
+
+
+
Trigger all messages
+
+
+
stubFinder.trigger()
+
+
+
+
+
+
+

Stub Runner Messaging Camel

+
+

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Apache Camel. +For the provided artifacts it will automatically download the stubs and register the required +routes.

+
+
+

Adding it to the project

+
+

To use it you have to add the following dependency to your project (example for Gradle):

+
+
+
+
testCompile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}"
+
+
+
+
+

Examples

+
+
Stubs structure
+
+

Let us assume that we have the following Maven repository with a deployed stubs for the +camelService application.

+
+
+
+
└── .m2
+    └── repository
+        └── io
+            └── codearte
+                └── accurest
+                    └── stubs
+                        └── camelService
+                            ├── 0.0.1-SNAPSHOT
+                            │   ├── camelService-0.0.1-SNAPSHOT.pom
+                            │   ├── camelService-0.0.1-SNAPSHOT-stubs.jar
+                            │   └── maven-metadata-local.xml
+                            └── maven-metadata-local.xml
+
+
+
+

And the stubs contain the following structure:

+
+
+
+
├── META-INF
+│   └── MANIFEST.MF
+└── repository
+    ├── accurest
+    │   ├── bookDeleted.groovy
+    │   ├── bookReturned1.groovy
+    │   └── bookReturned2.groovy
+    └── mappings
+
+
+
+

Let’s consider the following contracts (let' number it with 1):

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_1'
+        input {
+                triggeredBy('bookReturnedTriggered()')
+        }
+        outputMessage {
+                sentTo('jms:output')
+                body('''{ "bookName" : "foo" }''')
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and number 2

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_2'
+        input {
+                messageFrom('jms:input')
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo('jms:output')
+                body([
+                                bookName: 'foo'
+                ])
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+
+
Scenario 1 (no input message)
+
+

So as to trigger a message via the return_book_1 label we’ll use the StubTigger interface as follows

+
+
+
+
stubFinder.trigger('return_book_1')
+
+
+
+

Next we’ll want to listen to the output of the message sent to jms:output

+
+
+
+
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
+receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 2 (output triggered by input)
+
+

Since the route is set for you it’s enough to just send a message to the jms:output destination.

+
+
+
+
camelContext.createProducerTemplate().sendBodyAndHeaders('jms:input', new BookReturned('foo'), [sample: 'header'])
+
+
+
+

Next we’ll want to listen to the output of the message sent to jms:output

+
+
+
+
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
+receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 3 (input with no output)
+
+

Since the route is set for you it’s enough to just send a message to the jms:output destination.

+
+
+
+
camelContext.createProducerTemplate().sendBodyAndHeaders('jms:delete', new BookReturned('foo'), [sample: 'header'])
+
+
+
+
+
+
+

Stub Runner Messaging Integration

+
+

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Spring Integration. +For the provided artifacts it will automatically download the stubs and register the required +routes.

+
+
+

Adding it to the project

+
+

To use it you have to add the following dependency to your project (example for Gradle):

+
+
+
+
testCompile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}"
+
+
+
+
+

Examples

+
+
Stubs structure
+
+

Let us assume that we have the following Maven repository with a deployed stubs for the +integrationService application.

+
+
+
+
└── .m2
+    └── repository
+        └── io
+            └── codearte
+                └── accurest
+                    └── stubs
+                        └── integrationService
+                            ├── 0.0.1-SNAPSHOT
+                            │   ├── integrationService-0.0.1-SNAPSHOT.pom
+                            │   ├── integrationService-0.0.1-SNAPSHOT-stubs.jar
+                            │   └── maven-metadata-local.xml
+                            └── maven-metadata-local.xml
+
+
+
+

And the stubs contain the following structure:

+
+
+
+
├── META-INF
+│   └── MANIFEST.MF
+└── repository
+    ├── accurest
+    │   ├── bookDeleted.groovy
+    │   ├── bookReturned1.groovy
+    │   └── bookReturned2.groovy
+    └── mappings
+
+
+
+

Let’s consider the following contracts (let' number it with 1):

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_1'
+        input {
+                triggeredBy('bookReturnedTriggered()')
+        }
+        outputMessage {
+                sentTo('output')
+                body('''{ "bookName" : "foo" }''')
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and number 2

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_2'
+        input {
+                messageFrom('input')
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo('output')
+                body([
+                                bookName: 'foo'
+                ])
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and the following Spring Integration Route:

+
+
+
+
<?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">
+
+
+        <!-- REQUIRED FOR TESTING -->
+        <bridge input-channel="output"
+                        output-channel="outputTest"/>
+
+        <channel id="outputTest">
+                <queue/>
+        </channel>
+
+</beans:beans>
+
+
+
+
+
Scenario 1 (no input message)
+
+

So as to trigger a message via the return_book_1 label we’ll use the StubTigger interface as follows

+
+
+
+
stubFinder.trigger('return_book_1')
+
+
+
+

Next we’ll want to listen to the output of the message sent to output

+
+
+
+
AccurestMessage receivedMessage = messaging.receiveMessage('outputTest')
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertJsons(receivedMessage.payload)
+receivedMessage.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 2 (output triggered by input)
+
+

Since the route is set for you it’s enough to just send a message to the output destination.

+
+
+
+
messaging.send(new BookReturned('foo'), [sample: 'header'], 'input')
+
+
+
+

Next we’ll want to listen to the output of the message sent to output

+
+
+
+
AccurestMessage receivedMessage = messaging.receiveMessage('outputTest')
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertJsons(receivedMessage.payload)
+receivedMessage.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 3 (input with no output)
+
+

Since the route is set for you it’s enough to just send a message to the input destination.

+
+
+
+
messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')
+
+
+
+
+
+
+

Stub Runner Messaging Stream

+
+

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Spring Stream. +For the provided artifacts it will automatically download the stubs and register the required +routes.

+
+
+ + + + + +
+ + +In Stub Runner’s integration with Stream the messageFrom or sentTo Strings are resolved +first as a destination of a channel, and then if there is no such destination it’s resolved as a +channel name. +
+
+
+

Adding it to the project

+
+

To use it you have to add the following dependency to your project (example for Gradle):

+
+
+
+
testCompile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}"
+
+
+
+
+

Examples

+
+
Stubs structure
+
+

Let us assume that we have the following Maven repository with a deployed stubs for the +streamService application.

+
+
+
+
└── .m2
+    └── repository
+        └── io
+            └── codearte
+                └── accurest
+                    └── stubs
+                        └── streamService
+                            ├── 0.0.1-SNAPSHOT
+                            │   ├── streamService-0.0.1-SNAPSHOT.pom
+                            │   ├── streamService-0.0.1-SNAPSHOT-stubs.jar
+                            │   └── maven-metadata-local.xml
+                            └── maven-metadata-local.xml
+
+
+
+

And the stubs contain the following structure:

+
+
+
+
├── META-INF
+│   └── MANIFEST.MF
+└── repository
+    ├── accurest
+    │   ├── bookDeleted.groovy
+    │   ├── bookReturned1.groovy
+    │   └── bookReturned2.groovy
+    └── mappings
+
+
+
+

Let’s consider the following contracts (let' number it with 1):

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_1'
+        input {
+                triggeredBy('bookReturnedTriggered()')
+        }
+        outputMessage {
+                sentTo('returnBook')
+                body('''{ "bookName" : "foo" }''')
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and number 2

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_2'
+        input {
+                messageFrom('bookStorage')
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo('returnBook')
+                body([
+                                bookName: 'foo'
+                ])
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and the following Spring configuration:

+
+
+
+
stubrunner.stubs.repository.root: classpath:m2repo/repository/
+stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs
+
+spring:
+  cloud:
+    stream:
+      bindings:
+        output:
+          destination: returnBook
+        input:
+          destination: bookStorage
+
+
+
+
+
Scenario 1 (no input message)
+
+

So as to trigger a message via the return_book_1 label we’ll use the StubTrigger interface as follows

+
+
+
+
stubFinder.trigger('return_book_1')
+
+
+
+

Next we’ll want to listen to the output of the message sent to a channel whose destination is returnBook

+
+
+
+
AccurestMessage receivedMessage = messaging.receiveMessage('returnBook')
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertJsons(receivedMessage.payload)
+receivedMessage.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 2 (output triggered by input)
+
+

Since the route is set for you it’s enough to just send a message to the bookStorage destination.

+
+
+
+
messaging.send(new BookReturned('foo'), [sample: 'header'], 'bookStorage')
+
+
+
+

Next we’ll want to listen to the output of the message sent to returnBook

+
+
+
+
AccurestMessage receivedMessage = messaging.receiveMessage('returnBook')
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertJsons(receivedMessage.payload)
+receivedMessage.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 3 (input with no output)
+
+

Since the route is set for you it’s enough to just send a message to the output destination.

+
+
+
+
messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')
+
+
+
+
+
+
+
+
+

Migration Guide

+
+
+

Migration to 0.4.7

+
+
    +
  • +

    in 0.4.7 we’ve fixed package name (coderate to codearte) so you’ve to do the same in your projects. This means replacing io.coderate.accurest.dsl.GroovyDsl with io.codearte.accurest.dsl.GroovyDsl

    +
  • +
+
+
+
+

Migration to 1.0.0-RC1

+
+
    +
  • +

    from 1.0.0 we’re distinguish ignored contracts from excluded contracts:

    +
  • +
  • +

    excludedFiles pattern tells Accurest to skip processing those files at all

    +
  • +
  • +

    ignoredFiles pattern tells Accurest to generate contracts and tests, but tests will be marked as @Ignore

    +
  • +
  • +

    from 1.0.0 the basePackageForTests behaviour has changed

    +
  • +
  • +

    prior to the change all DSL files had to be under contractsDslDir/basePackageForTests/subpackage resulting in basePackageForTests.subpackage test package creation

    +
  • +
  • +

    now all DSL files have to be under contractsDslDir/subpackage resulting in basePackageForTests.subpackage test package creation

    +
  • +
  • +

    If you don’t migrate to the new approach you will have your tests under contractsDslDir.contractsDslDir.subpackage

    +
  • +
+
+
+
+

Migration to 1.1.0

+
+
    +
  • +

    from 1.1.0 we’re setting JUnit as a default testing utility. You have to pass the following option to keep Spock +as your first choice:

    +
  • +
+
+
+
+
targetFramework = 'Spock'
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/src/main/asciidoc/deprecated/introduction.html b/docs/src/main/asciidoc/deprecated/introduction.html new file mode 100644 index 0000000000..5f173f30de --- /dev/null +++ b/docs/src/main/asciidoc/deprecated/introduction.html @@ -0,0 +1,797 @@ + + + + + + + +Introduction + + + + + + + +
+
+

Introduction

+
+
+

Just to make long story short - Accurest is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped +with Contract Definition Language (DSL). Contract definitions are used by Accurest to produce following resources:

+
+
+
    +
  • +

    JSON stub definitions to be used by Wiremock when doing integration testing on the client code (client tests). +Test code must still be written by hand, test data is produced by Accurest.

    +
  • +
  • +

    Messaging routes if you’re using one. We’re integrating with Spring Integration, Spring Cloud Stream and Apache Camel. You can however set your own integrations if you want to

    +
  • +
  • +

    Acceptance tests (in JUnit or Spock) used to verify if server-side implementation of the API is compliant with the contract (server tests). Full test is generated by Accurest.

    +
  • +
+
+
+

Accurest moves TDD to the level of software architecture.

+
+
+

Why?

+
+

Let us assume that we have a system comprising of multiple microservices:

+
+
+
+Microservices Architecture +
+
+
+

Testing issues

+
+

If we wanted to test the application in top left corner if it can communicate with other services then we could do one of two things:

+
+
+
    +
  • +

    deploy all microservices and perform end to end tests

    +
  • +
  • +

    mock other microservices in unit / integration tests

    +
  • +
+
+
+

Both have their advantages but also a lot of disadvantages. Let’s focus on the latter.

+
+
+

Deploy all microservices and perform end to end tests

+
+
+

Advantages:

+
+
+
    +
  • +

    simulates production

    +
  • +
  • +

    tests real communication between services

    +
  • +
+
+
+

Disadvantages:

+
+
+
    +
  • +

    to test one microservice we would have to deploy 6 microservices, a couple of databases etc.

    +
  • +
  • +

    the environment where the tests would be conducted would be locked for a single suite of tests (i.e. nobody else would be able to run the tests in the meantime).

    +
  • +
  • +

    long to run

    +
  • +
  • +

    very late feedback

    +
  • +
  • +

    extremely hard to debug

    +
  • +
+
+
+

Mock other microservices in unit / integration tests

+
+
+

Advantages:

+
+
+
    +
  • +

    very fast feedback

    +
  • +
  • +

    no infrastructure requirements

    +
  • +
+
+
+

Disadvantages:

+
+
+
    +
  • +

    the implementor of the service creates stubs thus they might have nothing to do with the reality

    +
  • +
  • +

    you can go to production with passing tests and failing production

    +
  • +
+
+
+

To solve the aforementioned issues Accurest with Stub Runner were created. Their main idea is to give you very fast feedback, without the need +to set up the whole world of microservices.

+
+
+
+Stubbed Services +
+
+
+

If you work on stubs then the only applications you need are those that your application is using directly.

+
+
+
+Stubbed Services +
+
+
+

Accurest gives you the certainty that the stubs that you’re using were created by the service that you’re calling. Also if you can use them it means that they were +tested against the producer’s side. In other words - you can trust those stubs.

+
+
+
+
+

Purposes

+
+

The main purposes of Accurest with Stub Runner are:

+
+
+
    +
  • +

    to ensure that WireMock / Messaging stubs (used when developing the client) are doing exactly what actual server-side implementation will do,

    +
  • +
  • +

    to promote ATDD method and Microservices architectural style,

    +
  • +
  • +

    to provide a way to publish changes in contracts that are immediately visible on both sides,

    +
  • +
  • +

    to generate boilerplate test code used on the server side.

    +
  • +
+
+
+
+

Client Side

+
+

During the tests you want to have a Wiremock instance / Messaging route 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 and 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

+
+

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.

+
+
+
+

Dependencies

+
+

Accurest and Stub Runner are using the following libraries

+
+ +
+
+ +
+

Below you can find some resources related to Accurest and Stub Runner. Note that some can be outdated since the Accurest project +is under constant development.

+
+
+

Videos

+
+

Olga Maciaszek-Sharma talking about Accurest

+
+
+
+ +
+
+
+

Marcin Grzejszczak and Jakub Kubryński talking about Accurest

+
+
+
+ +
+
+
+ +
+
+

Samples

+
+

Here you can find some working samples. Check the readme of each project for more information.

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/src/main/asciidoc/deprecated/messaging.html b/docs/src/main/asciidoc/deprecated/messaging.html new file mode 100644 index 0000000000..623d82b4b3 --- /dev/null +++ b/docs/src/main/asciidoc/deprecated/messaging.html @@ -0,0 +1,914 @@ + + + + + + + +Accurest Messaging + + + + + + + +
+
+

Accurest Messaging

+
+
+ + + + + +
+ + +Feature available since {messaging_version} +
+
+
+

Accurest allows you to verify your application that uses messaging as means of communication. +All of our integrations are working with Spring but you can also set one yourself.

+
+
+

Integrations

+
+

You can use one of the three integration configurations:

+
+
+
    +
  • +

    Apache Camel

    +
  • +
  • +

    Spring Integration

    +
  • +
  • +

    Spring Cloud Stream

    +
  • +
+
+
+

If you’re using Spring Boot, the aforementioned test configurations will be appended automatically.

+
+
+

You have to provide as a dependency one of the Accurest Messaging modules. Example for Gradle:

+
+
+
+
// for Apache Camel
+testCompile "io.codearte.accurest:accurest-messaging-camel:${accurestVersion}"
+// for Spring Integration
+testCompile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}"
+// for Spring Cloud Stream
+testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}"
+
+
+
+
+

Manual Integration

+
+

The accurest-messaging-core module contains 3 main interfaces:

+
+
+
    +
  • +

    AccurestMessage - describes a message received / sent to a channel / queue / topic etc.

    +
  • +
  • +

    AccurestMessageBuilder - describes how to build a message

    +
  • +
  • +

    AccurestMessaging - class that allows you to build, send and receive messages

    +
  • +
  • +

    AccurestFilter - interface to filter out the messages that do not follow the pattern from the DSL

    +
  • +
+
+
+

In the generated test the AccurestMessaging is injected via @Inject annotation thus you can use other injection +frameworks than Spring.

+
+
+

You have to provide as a dependency the accurest-messaging-core module. Example for Gradle:

+
+
+
+
testCompile "io.codearte.accurest:accurest-messaging-core:${accurestVersion}"
+
+
+
+
+

Publisher side test generation

+
+

Having the input or outputMessage sections in your DSL will result in creation of tests on the publisher’s side. By default +JUnit tests will be created, however there is also a possibility to create Spock tests.

+
+
+

There are 3 main scenarios that we should take into consideration:

+
+
+
    +
  • +

    Scenario 1: there is no input message that produces an output one. The output message is triggered by a component +inside the application (e.g. scheduler)

    +
  • +
  • +

    Scenario 2: the input message triggers an output message

    +
  • +
  • +

    Scenario 3: the input message is consumed and there is no output message

    +
  • +
+
+
+

Scenario 1 (no input message)

+
+

For the given contract:

+
+
+
+
def contractDsl = GroovyDsl.make {
+        label 'some_label'
+        input {
+                triggeredBy('bookReturnedTriggered()')
+        }
+        outputMessage {
+                sentTo('activemq:output')
+                body('''{ "bookName" : "foo" }''')
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

The following JUnit test will be created:

+
+
+
+
'''
+ // when:
+  bookReturnedTriggered();
+
+ // then:
+  AccurestMessage response = accurestMessaging.receiveMessage("activemq:output");
+  assertThat(response).isNotNull();
+  assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo");
+ // and:
+  DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload()));
+  assertThatJson(parsedJson).field("bookName").isEqualTo("foo");
+'''
+
+
+
+

And the following Spock test would be created:

+
+
+
+
'''
+ when:
+  bookReturnedTriggered()
+
+ then:
+  def response = accurestMessaging.receiveMessage('activemq:output')
+  assert response != null
+  response.getHeader('BOOK-NAME')  == 'foo'
+ and:
+  DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
+  assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
+
+'''
+
+
+
+
+

Scenario 2 (output triggered by input)

+
+

For the given contract:

+
+
+
+
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')
+                }
+        }
+}
+
+
+
+

The following JUnit test will be created:

+
+
+
+
'''
+// 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).isNotNull();
+ assertThat(response.getHeader("BOOK-NAME")).isEqualTo("foo");
+// and:
+ DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.getPayload()));
+ assertThatJson(parsedJson).field("bookName").isEqualTo("foo");
+'''
+
+
+
+

And the following Spock test would be created:

+
+
+
+
"""\
+given:
+   def inputMessage = accurestMessaging.create(
+    '''{"bookName":"foo"}''',
+    ['sample': 'header']
+  )
+
+when:
+   accurestMessaging.send(inputMessage, 'jms:input')
+
+then:
+   def response = accurestMessaging.receiveMessage('jms:output')
+   assert response !- null
+   response.getHeader('BOOK-NAME')  == 'foo'
+and:
+   DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper.writeValueAsString(response.payload))
+   assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
+"""
+
+
+
+
+

Scenario 3 (no output message)

+
+

For the given contract:

+
+
+
+
def contractDsl = GroovyDsl.make {
+        label 'some_label'
+        input {
+                messageFrom('jms:delete')
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+                assertThat('bookWasDeleted()')
+        }
+}
+
+
+
+

The following JUnit test will be created:

+
+
+
+
'''
+// given:
+ AccurestMessage inputMessage = accurestMessaging.create(
+        "{\\"bookName\\":\\"foo\\"}"
+, headers()
+        .header("sample", "header"));
+
+// when:
+ accurestMessaging.send(inputMessage, "jms:delete");
+
+// then:
+ bookWasDeleted();
+'''
+
+
+
+

And the following Spock test would be created:

+
+
+
+
'''
+given:
+         def inputMessage = accurestMessaging.create(
+                \'\'\'{"bookName":"foo"}\'\'\',
+                ['sample': 'header']
+        )
+
+when:
+         accurestMessaging.send(inputMessage, 'jms:delete')
+
+then:
+         noExceptionThrown()
+         bookWasDeleted()
+'''
+
+
+
+
+
+

Consumer Stub Side generation

+
+

Unlike the HTTP part - in Messaging we need to publish the Groovy DSL inside the JAR with a stub. Then it’s parsed on the consumer side +and proper stubbed routes are created.

+
+
+

For more infromation please consult the Stub Runner Messaging sections.

+
+
+

Gradle Setup

+
+

Example of Accurest Gradle setup:

+
+
+
+
ext {
+        contractsDir = file("mappings")
+        stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/")
+        wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/'))
+        contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/'))
+}
+
+task copyContracts(type: Copy) {
+        from contractsDir
+        include '**/*.groovy'
+        into contractsOutputDir
+}
+
+task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) {
+        baseName = "${project.name}"
+        classifier = "stubs"
+        from stubsOutputDirRoot
+}
+
+artifacts {
+        archives stubsJar
+}
+
+publishing {
+        publications {
+                stubs(MavenPublication) {
+                        artifactId "${project.name}-stubs"
+                        artifact stubsJar
+                }
+        }
+}
+
+
+
+
+

Maven Setup

+
+

Example of Maven can be found in the Accurest Maven Plugin README

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/src/main/asciidoc/deprecated/migration.html b/docs/src/main/asciidoc/deprecated/migration.html new file mode 100644 index 0000000000..351572a2e3 --- /dev/null +++ b/docs/src/main/asciidoc/deprecated/migration.html @@ -0,0 +1,594 @@ + + + + + + + +Migration Guide + + + + + + + +
+
+

Migration Guide

+
+
+

Migration to 0.4.7

+
+
    +
  • +

    in 0.4.7 we’ve fixed package name (coderate to codearte) so you’ve to do the same in your projects. This means replacing io.coderate.accurest.dsl.GroovyDsl with io.codearte.accurest.dsl.GroovyDsl

    +
  • +
+
+
+
+

Migration to 1.0.0-RC1

+
+
    +
  • +

    from 1.0.0 we’re distinguish ignored contracts from excluded contracts:

    +
  • +
  • +

    excludedFiles pattern tells Accurest to skip processing those files at all

    +
  • +
  • +

    ignoredFiles pattern tells Accurest to generate contracts and tests, but tests will be marked as @Ignore

    +
  • +
  • +

    from 1.0.0 the basePackageForTests behaviour has changed

    +
  • +
  • +

    prior to the change all DSL files had to be under contractsDslDir/basePackageForTests/subpackage resulting in basePackageForTests.subpackage test package creation

    +
  • +
  • +

    now all DSL files have to be under contractsDslDir/subpackage resulting in basePackageForTests.subpackage test package creation

    +
  • +
  • +

    If you don’t migrate to the new approach you will have your tests under contractsDslDir.contractsDslDir.subpackage

    +
  • +
+
+
+
+

Migration to {messaging_version}

+
+
    +
  • +

    from {messaging_version} we’re setting JUnit as a default testing utility. You have to pass the following option to keep Spock +as your first choice:

    +
  • +
+
+
+
+
targetFramework = 'Spock'
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/src/main/asciidoc/deprecated/rest.html b/docs/src/main/asciidoc/deprecated/rest.html new file mode 100644 index 0000000000..bab2a70944 --- /dev/null +++ b/docs/src/main/asciidoc/deprecated/rest.html @@ -0,0 +1,1032 @@ + + + + + + + +Accurest HTTP + + + + + + + +
+
+

Accurest HTTP

+
+
+

Gradle Project

+
+

Prerequisites

+
+

In order to use Accurest with Wiremock you have to use gradle or maven plugin.

+
+
+
Add gradle plugin
+
+
+
buildscript {
+        repositories {
+                mavenCentral()
+        }
+        dependencies {
+                classpath 'io.codearte.accurest:accurest-gradle-plugin:${accurest_version}'
+        }
+}
+
+apply plugin: 'groovy'
+apply plugin: 'accurest'
+
+dependencies {
+        testCompile 'org.codehaus.groovy:groovy-all:2.4.6'
+        testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
+        testCompile 'com.jayway.restassured:spring-mock-mvc:2.9.0' // needed if you're going to use Spring MockMvc
+}
+
+
+
+
+
Add maven plugin
+
+
+
<plugin>
+    <groupId>io.codearte.accurest</groupId>
+    <artifactId>accurest-maven-plugin</artifactId>
+    <executions>
+        <execution>
+            <goals>
+                <goal>convert</goal>
+                <goal>generateStubs</goal>
+                <goal>generateTests</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+
+
+
+

Read more: accurest-maven-plugin

+
+
+
+
Add stubs
+
+

By default Accurest is looking for stubs in src/test/resources/accurest 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/accurest/myservice/shouldCreateUser.groovy
+src/test/resources/accurest/myservice/shouldReturnUser.groovy
+
+
+
+

Accurest will create test class defaultBasePackage.MyService with two methods

+
+
+
    +
  • +

    shouldCreateUser()

    +
  • +
  • +

    shouldReturnUser()

    +
  • +
+
+
+
+
+

Run plugin

+
+

Plugin registers itself to be invoked before check 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 = project.file('src/accurest')
+}
+
+
+
+
Configuration options
+
+
    +
  • +

    testMode - defines mode for acceptance tests. By default MockMvc which is based on Spring’s MockMvc. It can also be changed to JaxRsClient or to Explicit for real HTTP calls.

    +
  • +
  • +

    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 []

    +
  • +
  • +

    basePackageForTests - specifies base package for all generated tests. By default set to io.codearte.accurest.tests

    +
  • +
  • +

    baseClassForTests - base class for generated tests. By default spock.lang.Specification if using Spock tests.

    +
  • +
  • +

    ruleClassForTests - specifies Rule which should be added to generated test classes.

    +
  • +
  • +

    ignoredFiles - Ant matcher allowing defining stub files for which processing should be skipped. By default empty array []

    +
  • +
  • +

    contractsDslDir - directory containing contracts written using the GroovyDSL. By default $rootDir/src/test/resources/accurest

    +
  • +
  • +

    generatedTestSourcesDir - test source directory where tests generated from Groovy DSL should be placed. By default $buildDir/generated-test-sources/accurest

    +
  • +
  • +

    stubsOutputDir - dir where the generated Wiremock stubs from Groovy DSL should be placed

    +
  • +
  • +

    targetFramework - the target test framework to be used; currently Spock and JUnit are supported with JUnit being the default framework

    +
  • +
+
+
+
+
Base class for tests
+
+

When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified.

+
+
+
+
abstract class BaseMockMvcSpec extends Specification {
+
+        def setup() {
+                RestAssuredMockMvc.standaloneSetup(new PairIdController())
+        }
+
+        void isProperCorrelationId(Integer correlationId) {
+                assert correlationId == 123456
+        }
+
+        void isEmpty(String value) {
+                assert value == null
+        }
+
+}
+
+
+
+

In case of using Explicit mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of JAXRSCLIENT mode this base class +should also contain protected WebTarget webTarget field, right now the only option to test JAX-RS API is to start a web server.

+
+
+
+
+

Invoking generated tests

+
+

To ensure that provider side is complaint with defined contracts, you need to invoke:

+
+
+
+
./gradlew generateAccurest test
+
+
+
+
+

Accurest on consumer side

+
+

In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. If you don’t want to use Stub Runner then you need to copy contracts stored in +src/test/resources/accurest and generate WireMock json stubs using:

+
+
+
+
./gradlew generateWireMockClientStubs
+
+
+
+

Note that stubsOutputDir option has to be set for stub generation to work.

+
+
+

When present, json stubs can be used in consumer automated tests.

+
+
+
+
@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
+class LoanApplicationServiceSpec extends Specification {
+
+ @ClassRule
+ @Shared
+ WireMockClassRule wireMockRule == new WireMockClassRule()
+
+ @Autowired
+ LoanApplicationService sut
+
+ def 'should successfully apply for loan'() {
+   given:
+         LoanApplication application =
+                        new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123)
+   when:
+        LoanApplicationResult loanApplication == sut.loanApplication(application)
+   then:
+        loanApplication.loanApplicationStatus === LoanApplicationStatus.LOAN_APPLIED
+        loanApplication.rejectionReason === null
+ }
+}
+
+
+
+

Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest.

+
+
+
+
+

Using in your Maven project

+
+

Add maven plugin

+
+
+
<plugin>
+    <groupId>io.codearte.accurest</groupId>
+    <artifactId>accurest-maven-plugin</artifactId>
+    <executions>
+        <execution>
+            <goals>
+                <goal>convert</goal>
+                <goal>generateStubs</goal>
+                <goal>generateTests</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+
+
+
+

Read more: accurest-maven-plugin

+
+
+
+

Add stubs

+
+

By default Accurest is looking for stubs in src/test/resources/accurest 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/accurest/myservice/shouldCreateUser.groovy
+src/test/resources/accurest/myservice/shouldReturnUser.groovy
+
+
+
+

Accurest will create test class defaultBasePackage.MyService with two methods + - shouldCreateUser() + - shouldReturnUser()

+
+
+
+

Run plugin

+
+

Plugin goal generateTests is assigned to be invoked in phase generate-test-sources. 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 generateTests goal.

+
+
+
+

Configure plugin

+
+

To change default configuration just add configuration section to plugin definition or execution definition.

+
+
+
+
<plugin>
+    <groupId>io.codearte.accurest</groupId>
+    <artifactId>accurest-maven-plugin</artifactId>
+    <executions>
+        <execution>
+            <goals>
+                <goal>convert</goal>
+                <goal>generateStubs</goal>
+                <goal>generateTests</goal>
+            </goals>
+        </execution>
+    </executions>
+    <configuration>
+        <basePackageForTests>com.ofg.twitter.place</basePackageForTests>
+        <baseClassForTests>com.ofg.twitter.place.BaseMockMvcSpec</baseClassForTests>
+    </configuration>
+</plugin>
+
+
+
+
Important configuration options
+
+
    +
  • +

    testMode - defines mode for acceptance tests. By default MockMvc which is based on Spring’s MockMvc. It can also be changed to JaxRsClient or to Explicit for real HTTP calls.

    +
  • +
  • +

    basePackageForTests - specifies base package for all generated tests. By default set to io.codearte.accurest.tests.

    +
  • +
  • +

    ruleClassForTests - specifies Rule which should be added to generated test classes.

    +
  • +
  • +

    baseClassForTests - base class for generated tests. By default spock.lang.Specification if using Spock tests.

    +
  • +
  • +

    contractsDir - directory containing contracts written using the GroovyDSL. By default /src/test/resources/accurest.

    +
  • +
  • +

    testFramework - the target test framework to be used; currently Spock and JUnit are supported with Spock being the default framework

    +
  • +
+
+
+

For complete information take a look at Plugin Documentation

+
+
+
+
Base class for tests
+
+
+
When using Accurest in default MockMvc you need to create a base specification for all generated acceptance tests. In this class you need to point to endpoint which should be verified.
+
+
+
+
+
package org.mycompany.tests
+
+import org.mycompany.ExampleSpringController
+import com.jayway.restassured.module.mockmvc.RestAssuredMockMvc
+import spock.lang.Specification
+
+class  MvcSpec extends Specification {
+  def setup() {
+   RestAssuredMockMvc.standaloneSetup(new ExampleSpringController())
+  }
+}
+
+
+
+

In case of using Explicit mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of JAXRSCLIENT mode this base class should also contain protected WebTarget webTarget field, right now the only option to test JAX-RS API is to start a web server.

+
+
+
+
+

Invoking generated tests

+
+

Accurest Maven Plugins generates verification code into directory /generated-test-sources/accurest and attach this directory to testCompile goal.

+
+
+

For Groovy Spock code use:

+
+
+
+
<plugin>
+        <groupId>org.codehaus.gmavenplus</groupId>
+        <artifactId>gmavenplus-plugin</artifactId>
+        <version>1.5</version>
+        <executions>
+                <execution>
+                        <goals>
+                                <goal>testCompile</goal>
+                        </goals>
+                </execution>
+        </executions>
+        <configuration>
+                <testSources>
+                        <testSource>
+                                <directory>${project.basedir}/src/test/groovy</directory>
+                                <includes>
+                                        <include>**/*.groovy</include>
+                                </includes>
+                        </testSource>
+                        <testSource>
+                                <directory>${project.build.directory}/generated-test-sources/accurest</directory>
+                                <includes>
+                                        <include>**/*.groovy</include>
+                                </includes>
+                        </testSource>
+                </testSources>
+        </configuration>
+</plugin>
+
+
+
+

To ensure that provider side is complaint with defined contracts, you need to invoke mvn generateTest test

+
+
+
+

Accurest on consumer side

+
+

In consumer service you need to configure Accurest plugin in exactly the same way as in case of provider. You need to copy contracts stored in src/test/resources/accurest and generate Wiremock json stubs using: mvn generateStubs command. By default generated WireMock mapping is stored in directory target/mappings. Your project should create from this generated mappings additional artifact with classifier stubs for easy deploy to maven repository.

+
+
+

Sample configuration:

+
+
+
+
<plugin>
+    <groupId>io.codearte.accurest</groupId>
+    <artifactId>accurest-maven-plugin</artifactId>
+    <version>${accurest-plugin.version}</version>
+    <executions>
+        <execution>
+            <goals>
+                <goal>convert</goal>
+                <goal>generateStubs</goal>
+            </goals>
+        </execution>
+    </executions>
+</plugin>
+
+
+
+

When present, json stubs can be used in consumer automated tests.

+
+
+
+
@ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
+class LoanApplicationServiceSpec extends Specification {
+
+ @ClassRule
+ @Shared
+ WireMockClassRule wireMockRule == new WireMockClassRule()
+
+ @Autowired
+ LoanApplicationService sut
+
+ def 'should successfully apply for loan'() {
+   given:
+         LoanApplication application =
+                        new LoanApplication(client: new Client(pesel: '12345678901'), amount: 123.123)
+   when:
+        LoanApplicationResult loanApplication == sut.loanApplication(application)
+   then:
+        loanApplication.loanApplicationStatus === LoanApplicationStatus.LOAN_APPLIED
+        loanApplication.rejectionReason === null
+ }
+}
+
+
+
+

Underneath LoanApplication makes a call to FraudDetection service. This request is handled by Wiremock server configured using stubs generated by Accurest.

+
+
+
+
+

Scenarios

+
+

It’s possible to handle scenarios with Accurest. All you need to do is to stick to proper naming convention while creating your contracts. The convention requires to include order number followed by the underscore.

+
+
+
+
my_contracts_dir\
+  scenario1\
+    1_login.groovy
+    2_showCart.groovy
+    3_logout.groovy
+
+
+
+

Such tree will cause Accurest generating Wiremock’s scenario with name scenario1 and three steps: + - login marked as Started pointing to: + - showCart marked as Step1 pointing to: + - logout marked as Step2 which will close the scenario. +More details about Wiremock scenarios can be found under [http://wiremock.org/stateful-behaviour.html](http://wiremock.org/stateful-behaviour.html)

+
+
+

Accurest will also generate tests with guaranteed order of execution.

+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/src/main/asciidoc/deprecated/stubrunner.html b/docs/src/main/asciidoc/deprecated/stubrunner.html new file mode 100644 index 0000000000..901a8fd60f --- /dev/null +++ b/docs/src/main/asciidoc/deprecated/stubrunner.html @@ -0,0 +1,1258 @@ + + + + + + + +Stub Runner + + + + + + + +
+
+

Stub Runner

+
+
+

One of the issues that you could have encountered while using Accurest was to pass the generated WireMock JSON stubs from the server side to the client side (or various clients). + The same takes place in terms of client side generation for messaging.

+
+
+

Copying the JSON files / setting the client side for messaging manually is out of the question.

+
+
+

Publishing stubs as JARs

+
+

The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository.

+
+
+

Gradle

+
+

Example of Accurest Gradle setup:

+
+
+
+
ext {
+        contractsDir = file("mappings")
+        stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/")
+        wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/'))
+        contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/accurest/'))
+}
+
+task copyContracts(type: Copy) {
+        from contractsDir
+        include '**/*.groovy'
+        into contractsOutputDir
+}
+
+task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) {
+        baseName = "${project.name}"
+        classifier = "stubs"
+        from stubsOutputDirRoot
+}
+
+artifacts {
+        archives stubsJar
+}
+
+publishing {
+        publications {
+                stubs(MavenPublication) {
+                        artifactId "${project.name}-stubs"
+                        artifact stubsJar
+                }
+        }
+}
+
+
+
+
+

Maven

+
+

Example of Maven can be found in the Accurest Maven Plugin README

+
+
+
+
+

Modules

+
+

Accurest comes with a new structure of modules

+
+
+
+
└── stub-runner
+    ├── stub-runner
+    ├── stub-runner-boot
+    ├── stub-runner-junit
+    ├── stub-runner-spring
+    └── stub-runner-spring-cloud
+
+
+
+
+

Stub Runner Core

+
+

Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of +Consumer Driven Contracts.

+
+
+

Stub Runner allows you to automatically download the stubs of the provided dependencies, start WireMock servers for them and feed them with proper stub definitions. +For messaging, special stub routes are defined.

+
+
+

Running stubs

+
+
Running using main app
+
+

You can set the following options to the main class:

+
+
+
+
-maxp (--maxPort) N            : Maximum port value to be assigned to the
+                                 Wiremock instance. Defaults to 15000
+                                 (default: 15000)
+-minp (--minPort) N            : Minimal port value to be assigned to the
+                                 Wiremock instance. Defaults to 10000
+                                 (default: 10000)
+-s (--stubs) VAL               : Comma separated list of Ivy representation of
+                                 jars with stubs. Eg. groupid:artifactid1,group
+                                 id2:artifactid2:version:classifier
+-sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where you
+                                 keep your stubs (e.g. http://nexus.net/content
+                                 /repositories/repository)
+-ss (--stubsSuffix) VAL        : Suffix for the jar containing stubs (e.g.
+                                 'stubs' if the stub jar would have a 'stubs'
+                                 classifier for stubs: foobar-stubs ).
+                                 Defaults to 'stubs' (default: stubs)
+-wo (--workOffline)            : Switch to work offline. Defaults to 'false'
+                                 (default: false)
+
+
+
+
+
Building a Fat Jar
+
+

Just call the following command:

+
+
+
+
./gradlew stub-runner-root:stub-runner:shadowJar -PfatJar
+
+
+
+

and inside the build/lib there will be a Fat Jar with classifier fatJar waiting for you to execute. E.g.

+
+
+
+
java -jar stub-runner/stub-runner/build/libs/stub-runner-1.0.1-SNAPSHOT-fatJar.jar -sr http://a.b.com -s a:b:c,d:e,f:g:h:i
+
+
+
+
+
+

Stub runner configuration

+
+

You can configure the stub runner by either passing the full arguments list with the -Pargs like this:

+
+
+
+
./gradlew stub-runner-root:stub-runner:run -Pargs="-c pl -minp 10000 -maxp 10005 -s a:b:c,d:e,f:g:h"
+
+
+
+

or each parameter separately with a -P prefix and without the hyphen - in the name of the param

+
+
+
+
./gradlew stub-runner-root:stub-runner:run -Pc=pl -Pminp=10000 -Pmaxp=10005 -Ps=a:b:c,d:e,f:g:h
+
+
+
+
HTTP Stubs
+
+

Stubs are defined in JSON documents, whose syntax is defined in WireMock documentation

+
+
+

Example:

+
+
+
+
{
+    "request": {
+        "method": "GET",
+        "url": "/ping"
+    },
+    "response": {
+        "status": 200,
+        "body": "pong",
+        "headers": {
+            "Content-Type": "text/plain"
+        }
+    }
+}
+
+
+
+
+
Viewing registered mappings
+
+

Every stubbed collaborator exposes list of defined mappings under __/admin/ endpoint.

+
+
+
+
Messaging Stubs
+
+

Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up.

+
+
+
+
+
+

Stub Runner Boot

+
+ + + + + +
+ + +Feature available since {messaging_version} +
+
+
+

Accurest Stub Runner Boot is a Spring Boot application that exposes REST endpoints to +trigger the messaging labels and to access started WireMock servers.

+
+
+

One of the usecases is to run some smoke (end to end) tests on a deployed application. You can read + more about this in the "Microservice Deployment" article at Too Much Coding blog.

+
+
+

How to use it?

+
+

Just add the

+
+
+
+
compile "io.codearte.accurest:stub-runner-boot:${accurestVersion}"
+
+
+
+

and a messaging implementation:

+
+
+
+
// for Apache Camel
+compile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}"
+// for Spring Integration
+compile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}"
+// for Spring Cloud Stream
+compile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}"
+
+
+
+

Build a fat-jar and you’re ready to go!

+
+
+

For the properties check the Stub Runner Spring section.

+
+
+
+

Endpoints

+
+
HTTP
+
+
    +
  • +

    GET /stubs - returns a list of all running stubs in ivy:integer notation

    +
  • +
  • +

    GET /stubs/{ivy} - returns a port for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    +
  • +
+
+
+
+
Messaging
+
+

For Messaging

+
+
+
    +
  • +

    GET /triggers - returns a list of all running labels in ivy : [ label1, label2 …​] notation

    +
  • +
  • +

    POST /triggers/{label} - executes a trigger with label

    +
  • +
  • +

    POST /triggers/{ivy}/{label} - executes a trigger with label for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    +
  • +
+
+
+
+
+

Example

+
+
+
@ContextConfiguration(classes = [StubRunnerBootSpec, StubRunnerBoot], loader = SpringApplicationContextLoader)
+@EnableBinding
+@Configuration
+class StubRunnerBootSpec extends Specification {
+
+        @Autowired StubRunning stubRunning
+
+        def setup() {
+                RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning),
+                                new TriggerController(stubRunning))
+        }
+
+        def 'should return a list of running stub servers in "full ivy:port" notation'() {
+                when:
+                        String response = RestAssuredMockMvc.get('/stubs').body.asString()
+                then:
+                        def root = new JsonSlurper().parseText(response)
+                        root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs' instanceof Integer
+        }
+
+        def 'should return a port on which a [#stubId] stub is running'() {
+                when:
+                        def response = RestAssuredMockMvc.get("/stubs/${stubId}")
+                then:
+                        response.statusCode == 200
+                        response.body.as(Integer) > 0
+                where:
+                        stubId << ['io.codearte.accurest.stubs:streamService:+:stubs',
+                                           'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs',
+                                           'io.codearte.accurest.stubs:streamService:+',
+                                           'io.codearte.accurest.stubs:streamService',
+                                           'streamService']
+        }
+
+        def 'should return 404 when missing stub was called'() {
+                when:
+                        def response = RestAssuredMockMvc.get("/stubs/a:b:c:d")
+                then:
+                        response.statusCode == 404
+        }
+
+        def 'should return a list of messaging labels that can be triggered when version and classifier are passed'() {
+                when:
+                        String response = RestAssuredMockMvc.get('/triggers').body.asString()
+                then:
+                        def root = new JsonSlurper().parseText(response)
+                        root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"])
+        }
+
+        def 'should trigger a messaging label'() {
+                given:
+                        StubRunning stubRunning = Mock()
+                        RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning), new TriggerController(stubRunning))
+                when:
+                        def response = RestAssuredMockMvc.post("/triggers/delete_book")
+                then:
+                        response.statusCode == 200
+                and:
+                        1 * stubRunning.trigger('delete_book')
+        }
+
+        def 'should trigger a messaging label for a stub with [#stubId] ivy notation'() {
+                given:
+                        StubRunning stubRunning = Mock()
+                        RestAssuredMockMvc.standaloneSetup(new HttpStubsController(stubRunning), new TriggerController(stubRunning))
+                when:
+                        def response = RestAssuredMockMvc.post("/triggers/$stubId/delete_book")
+                then:
+                        response.statusCode == 200
+                and:
+                        1 * stubRunning.trigger(stubId, 'delete_book')
+                where:
+                        stubId << ['io.codearte.accurest.stubs:streamService:stubs', 'io.codearte.accurest.stubs:streamService', 'streamService']
+        }
+
+        def 'should return when trigger is missing'() {
+                when:
+                        def response = RestAssuredMockMvc.post("/triggers/missing_label")
+                then:
+                        response.statusCode == 404
+                        def root = new JsonSlurper().parseText(response.body.asString())
+                        root.'io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs'?.containsAll(["delete_book","return_book_1","return_book_2"])
+        }
+
+}
+
+
+
+
+
+

Stub Runner JUnit Rule

+
+

Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id:

+
+
+
+
@ClassRule public static AccurestRule rule = new AccurestRule()
+                .repoRoot(repoRoot())
+                .downloadStub("io.codearte.accurest.stubs", "loanIssuance")
+                .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer");
+
+
+
+

After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to:

+
+
+
    +
  • +

    download them

    +
  • +
  • +

    cache them locally

    +
  • +
  • +

    unzip them to a temporary folder

    +
  • +
  • +

    start a WireMock server for each Maven dependency on a random port from the provided range of ports / provided port

    +
  • +
  • +

    feed the WireMock server with all JSON files that are valid WireMock definitions

    +
  • +
+
+
+

Stub Runner uses Eclipse Aether mechanism to download the Maven dependencies. +Check their docs for more information.

+
+
+

Since the AccurestRule implements the StubFinder it allows you to find the started stubs:

+
+
+
+
package io.codearte.accurest.stubrunner
+
+import io.codearte.accurest.dsl.GroovyDsl
+
+interface StubFinder extends StubTrigger {
+        /**
+         * For the given groupId and artifactId tries to find the matching
+         * URL of the running stub.
+         *
+         * @param groupId - might be null. In that case a search only via artifactId takes place
+         * @return URL of a running stub or null if not found
+         */
+        URL findStubUrl(String groupId, String artifactId)
+
+        /**
+         * For the given Ivy notation {@code groupId:artifactId} tries to find the matching
+         * URL of the running stub. You can also pass only {@code artifactId}.
+         *
+         * @param ivyNotation - Ivy representation of the Maven artifact
+         * @return URL of a running stub or null if not found
+         */
+        URL findStubUrl(String ivyNotation)
+
+        /**
+         * Returns all running stubs
+         */
+        RunningStubs findAllRunningStubs()
+
+        /**
+         * Returns the list of Accurest contracts
+         */
+        Map<StubConfiguration, Collection<GroovyDsl>> getAccurestContracts()
+}
+
+
+
+

Example of usage in Spock tests:

+
+
+
+
@ClassRule @Shared AccurestRule rule = new AccurestRule()
+                .repoRoot(AccurestRuleSpec.getResource("/m2repo").toURI().toString())
+                .downloadStub("io.codearte.accurest.stubs", "loanIssuance")
+                .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer")
+
+def 'should start WireMock servers'() {
+        expect: 'WireMocks are running'
+                rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null
+                rule.findStubUrl('loanIssuance') != null
+                rule.findStubUrl('loanIssuance') == rule.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance')
+                rule.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null
+        and:
+                rule.findAllRunningStubs().isPresent('loanIssuance')
+                rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer')
+                rule.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer')
+        and: 'Stubs were registered'
+                "${rule.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
+                "${rule.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
+}
+
+
+
+

Example of usage in JUnit tests:

+
+
+
+
@Test
+public void should_start_wiremock_servers() throws Exception {
+        // expect: 'WireMocks are running'
+                then(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance")).isNotNull();
+                then(rule.findStubUrl("loanIssuance")).isNotNull();
+                then(rule.findStubUrl("loanIssuance")).isEqualTo(rule.findStubUrl("io.codearte.accurest.stubs", "loanIssuance"));
+                then(rule.findStubUrl("io.codearte.accurest.stubs:fraudDetectionServer")).isNotNull();
+        // and:
+                then(rule.findAllRunningStubs().isPresent("loanIssuance")).isTrue();
+                then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs", "fraudDetectionServer")).isTrue();
+                then(rule.findAllRunningStubs().isPresent("io.codearte.accurest.stubs:fraudDetectionServer")).isTrue();
+        // and: 'Stubs were registered'
+                then(httpGet(rule.findStubUrl("loanIssuance").toString() + "/name")).isEqualTo("loanIssuance");
+                then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer");
+}
+
+
+
+

Check the Common properties for JUnit and Spring for more information on how to apply global configuration of Stub Runner.

+
+
+

Providing fixed ports

+
+

You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of +JUnit rule.

+
+
+
+

Fluent API

+
+

When using the AccurestRule you can add a stub to download and then pass the port for the last downloaded stub.

+
+
+
+
@ClassRule public static AccurestRule rule = new AccurestRule()
+                .repoRoot(repoRoot())
+                .downloadStub("io.codearte.accurest.stubs", "loanIssuance")
+                .withPort(12345)
+                .downloadStub("io.codearte.accurest.stubs:fraudDetectionServer:12346");
+
+
+
+

You can see that for this example the following test is valid:

+
+
+
+
then(rule.findStubUrl("loanIssuance")).isEqualTo(URI.create("http://localhost:12345").toURL());
+then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL());
+
+
+
+
+
+

Stub Runner Spring

+
+

Sets up Spring configuration of the Stub Runner project.

+
+
+

By providing a list of stubs inside your configuration file the Stub Runner automatically downloads +and registers in WireMock the selected stubs.

+
+
+

If you want to find the URL of your stubbed dependency you can autowire the StubFinder interface and use +its methods as presented below:

+
+
+
+
@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader)
+class StubRunnerConfigurationSpec extends Specification {
+
+        @Autowired StubFinder stubFinder
+
+        def 'should start WireMock servers'() {
+                expect: 'WireMocks are running'
+                        stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance') != null
+                        stubFinder.findStubUrl('loanIssuance') != null
+                        stubFinder.findStubUrl('loanIssuance') == stubFinder.findStubUrl('io.codearte.accurest.stubs', 'loanIssuance')
+                        stubFinder.findStubUrl('io.codearte.accurest.stubs:fraudDetectionServer') != null
+                and:
+                        stubFinder.findAllRunningStubs().isPresent('loanIssuance')
+                        stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs', 'fraudDetectionServer')
+                        stubFinder.findAllRunningStubs().isPresent('io.codearte.accurest.stubs:fraudDetectionServer')
+                and: 'Stubs were registered'
+                        "${stubFinder.findStubUrl('loanIssuance').toString()}/name".toURL().text == 'loanIssuance'
+                        "${stubFinder.findStubUrl('fraudDetectionServer').toString()}/name".toURL().text == 'fraudDetectionServer'
+        }
+
+        @Configuration
+        @Import(StubRunnerConfiguration)
+        @EnableAutoConfiguration
+        static class Config {}
+}
+
+
+
+

for the following configuration file:

+
+
+
+
stubrunner.stubs.repository.root: classpath:m2repo/repository/
+stubrunner.stubs.ids: io.codearte.accurest.stubs:loanIssuance,io.codearte.accurest.stubs:fraudDetectionServer
+
+
+
+
+

Stub Runner Spring Cloud

+
+

Registers the stubs in the provided Service Discovery. It’s enough to add the jar

+
+
+
+
io.codearte.accurest:stub-runner-spring-cloud
+
+
+
+

and the Stub Runner autoconfiguration should be picked up.

+
+
+

Stubbing Service Discovery

+
+

The most important feature of Stub Runner Spring Cloud is the fact that it’s stubbing

+
+
+
    +
  • +

    DiscoveryClient

    +
  • +
  • +

    Ribbon ServerList

    +
  • +
+
+
+

that means that regardles of the fact whether you’re using Zookeeper, Consul, Eureka or anything else, you don’t need that in your tests. +We’re starting WireMock instances of your dependencies and we’re telling your application whenever you’re using Feign, load balanced RestTemplate +or DiscoveryClient directly, to call those stubbed servers instead of calling the real Service Discovery tool.

+
+
+
+

Additional Configuration

+
+

You can match the artifactId of the stub with the name of your app by using the stubrunner.stubs.idsToServiceIds: map. +You can disable Stub Runner Ribbon support by providing: stubrunner.cloud.ribbon.enabled equal to false +You can disable Stub Runner support by providing: stubrunner.cloud.enabled equal to false

+
+
+
+
+

Common properties for JUnit and Spring

+
+

Some of the properties that are repetitive can be set using system properties or property sources (for Spring). Here are their names with their default values:

+
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Property nameDefault valueDescription

stubrunner.port.range.min

10000

Minimal value of a port for a started WireMock with stubs

stubrunner.port.range.max

15000

Minimal value of a port for a started WireMock with stubs

stubrunner.stubs.repository.root

Comma separated list of Maven repo urls. If blank then will call the local maven repo

stubrunner.stubs.classifier

stubs

Default classifier for the stub artifacts

stubrunner.work-offline

false

If true then will not contact any remote repositories to download stubs

stubrunner.stubs.ids

Comma separated list of Ivy notation of stubs to download

+
+

Stub runner stubs ids

+
+

You can provide the stubs to download via the stubrunner.stubs.ids system property. They follow the following pattern:

+
+
+
+
groupId:artifactId:version:classifier:port
+
+
+
+

version, classifier and port are optional.

+
+
+
    +
  • +

    If you don’t provide the port then a random one will be picked

    +
  • +
  • +

    If you don’t provide the classifier then the default one will be taken.

    +
  • +
  • +

    If you don’t provide the version then the + will be passed and the latest one will be downloaded

    +
  • +
+
+
+

Where port means the port of the WireMock server.

+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/src/main/asciidoc/deprecated/stubrunner_msg.html b/docs/src/main/asciidoc/deprecated/stubrunner_msg.html new file mode 100644 index 0000000000..ae7b656eea --- /dev/null +++ b/docs/src/main/asciidoc/deprecated/stubrunner_msg.html @@ -0,0 +1,1247 @@ + + + + + + + +Stub Runner for Messaging + + + + + + + +
+
+

Stub Runner for Messaging

+
+
+ + + + + +
+ + +Feature available since {messaging_version} +
+
+
+

Stub Runner has the functionality to run the published stubs in memory. It can integrate with the following frameworks out of the box

+
+
+
    +
  • +

    Spring Integration

    +
  • +
  • +

    Spring Cloud Stream

    +
  • +
  • +

    Apache Camel

    +
  • +
+
+
+

It also provides points of entry to integrate with any other solution on the market.

+
+
+

Stub triggering

+
+

To trigger a message it’s enough to use the StubTigger interface:

+
+
+
+
package io.codearte.accurest.stubrunner
+
+interface StubTrigger {
+
+        /**
+         * Triggers an event by a given label for a given {@code groupid:artifactid} notation. You can use only {@code artifactId} too.
+         *
+         * Feature related to messaging.
+         *
+         * @return true - if managed to run a trigger
+         */
+        boolean trigger(String ivyNotation, String labelName)
+
+        /**
+         * Triggers an event by a given label.
+         *
+         * Feature related to messaging.
+         *
+         * @return true - if managed to run a trigger
+         */
+        boolean trigger(String labelName)
+
+        /**
+         * Triggers all possible events.
+         *
+         * Feature related to messaging.
+         *
+         * @return true - if managed to run a trigger
+         */
+        boolean trigger()
+
+        /**
+         * Returns a mapping of ivy notation of a dependency to all the labels it has.
+         *
+         * Feature related to messaging.
+         */
+        Map<String, Collection<String>> labels()
+}
+
+
+
+

For convenience the StubFinder interface extends StubTrigger so it’s enough to use only one in your tests.

+
+
+

StubTrigger gives you the following options to trigger a message:

+
+
+

Trigger by label

+
+
+
stubFinder.trigger('return_book_1')
+
+
+
+
Trigger by group and artifact ids
+
+
+
stubFinder.trigger('io.codearte.accurest.stubs:camelService', 'return_book_1')
+
+
+
+
+
Trigger by artifact ids
+
+
+
stubFinder.trigger('camelService', 'return_book_1')
+
+
+
+
+
Trigger all messages
+
+
+
stubFinder.trigger()
+
+
+
+
+
+
+

Stub Runner Messaging Camel

+
+

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Apache Camel. +For the provided artifacts it will automatically download the stubs and register the required +routes.

+
+
+

Adding it to the project

+
+

To use it you have to add the following dependency to your project (example for Gradle):

+
+
+
+
testCompile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}"
+
+
+
+
+

Examples

+
+
Stubs structure
+
+

Let us assume that we have the following Maven repository with a deployed stubs for the +camelService application.

+
+
+
+
└── .m2
+    └── repository
+        └── io
+            └── codearte
+                └── accurest
+                    └── stubs
+                        └── camelService
+                            ├── 0.0.1-SNAPSHOT
+                            │   ├── camelService-0.0.1-SNAPSHOT.pom
+                            │   ├── camelService-0.0.1-SNAPSHOT-stubs.jar
+                            │   └── maven-metadata-local.xml
+                            └── maven-metadata-local.xml
+
+
+
+

And the stubs contain the following structure:

+
+
+
+
├── META-INF
+│   └── MANIFEST.MF
+└── repository
+    ├── accurest
+    │   ├── bookDeleted.groovy
+    │   ├── bookReturned1.groovy
+    │   └── bookReturned2.groovy
+    └── mappings
+
+
+
+

Let’s consider the following contracts (let' number it with 1):

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_1'
+        input {
+                triggeredBy('bookReturnedTriggered()')
+        }
+        outputMessage {
+                sentTo('jms:output')
+                body('''{ "bookName" : "foo" }''')
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and number 2

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_2'
+        input {
+                messageFrom('jms:input')
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo('jms:output')
+                body([
+                                bookName: 'foo'
+                ])
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+
+
Scenario 1 (no input message)
+
+

So as to trigger a message via the return_book_1 label we’ll use the StubTigger interface as follows

+
+
+
+
stubFinder.trigger('return_book_1')
+
+
+
+

Next we’ll want to listen to the output of the message sent to jms:output

+
+
+
+
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
+receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 2 (output triggered by input)
+
+

Since the route is set for you it’s enough to just send a message to the jms:output destination.

+
+
+
+
camelContext.createProducerTemplate().sendBodyAndHeaders('jms:input', new BookReturned('foo'), [sample: 'header'])
+
+
+
+

Next we’ll want to listen to the output of the message sent to jms:output

+
+
+
+
Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
+receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 3 (input with no output)
+
+

Since the route is set for you it’s enough to just send a message to the jms:output destination.

+
+
+
+
camelContext.createProducerTemplate().sendBodyAndHeaders('jms:delete', new BookReturned('foo'), [sample: 'header'])
+
+
+
+
+
+
+

Stub Runner Messaging Integration

+
+

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Spring Integration. +For the provided artifacts it will automatically download the stubs and register the required +routes.

+
+
+

Adding it to the project

+
+

To use it you have to add the following dependency to your project (example for Gradle):

+
+
+
+
testCompile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}"
+
+
+
+
+

Examples

+
+
Stubs structure
+
+

Let us assume that we have the following Maven repository with a deployed stubs for the +integrationService application.

+
+
+
+
└── .m2
+    └── repository
+        └── io
+            └── codearte
+                └── accurest
+                    └── stubs
+                        └── integrationService
+                            ├── 0.0.1-SNAPSHOT
+                            │   ├── integrationService-0.0.1-SNAPSHOT.pom
+                            │   ├── integrationService-0.0.1-SNAPSHOT-stubs.jar
+                            │   └── maven-metadata-local.xml
+                            └── maven-metadata-local.xml
+
+
+
+

And the stubs contain the following structure:

+
+
+
+
├── META-INF
+│   └── MANIFEST.MF
+└── repository
+    ├── accurest
+    │   ├── bookDeleted.groovy
+    │   ├── bookReturned1.groovy
+    │   └── bookReturned2.groovy
+    └── mappings
+
+
+
+

Let’s consider the following contracts (let' number it with 1):

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_1'
+        input {
+                triggeredBy('bookReturnedTriggered()')
+        }
+        outputMessage {
+                sentTo('output')
+                body('''{ "bookName" : "foo" }''')
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and number 2

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_2'
+        input {
+                messageFrom('input')
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo('output')
+                body([
+                                bookName: 'foo'
+                ])
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and the following Spring Integration Route:

+
+
+
+
<?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">
+
+
+        <!-- REQUIRED FOR TESTING -->
+        <bridge input-channel="output"
+                        output-channel="outputTest"/>
+
+        <channel id="outputTest">
+                <queue/>
+        </channel>
+
+</beans:beans>
+
+
+
+
+
Scenario 1 (no input message)
+
+

So as to trigger a message via the return_book_1 label we’ll use the StubTigger interface as follows

+
+
+
+
stubFinder.trigger('return_book_1')
+
+
+
+

Next we’ll want to listen to the output of the message sent to output

+
+
+
+
AccurestMessage receivedMessage = messaging.receiveMessage('outputTest')
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertJsons(receivedMessage.payload)
+receivedMessage.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 2 (output triggered by input)
+
+

Since the route is set for you it’s enough to just send a message to the output destination.

+
+
+
+
messaging.send(new BookReturned('foo'), [sample: 'header'], 'input')
+
+
+
+

Next we’ll want to listen to the output of the message sent to output

+
+
+
+
AccurestMessage receivedMessage = messaging.receiveMessage('outputTest')
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertJsons(receivedMessage.payload)
+receivedMessage.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 3 (input with no output)
+
+

Since the route is set for you it’s enough to just send a message to the input destination.

+
+
+
+
messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')
+
+
+
+
+
+
+

Stub Runner Messaging Stream

+
+

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Spring Stream. +For the provided artifacts it will automatically download the stubs and register the required +routes.

+
+
+ + + + + +
+ + +In Stub Runner’s integration with Stream the messageFrom or sentTo Strings are resolved +first as a destination of a channel, and then if there is no such destination it’s resolved as a +channel name. +
+
+
+

Adding it to the project

+
+

To use it you have to add the following dependency to your project (example for Gradle):

+
+
+
+
testCompile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}"
+
+
+
+
+

Examples

+
+
Stubs structure
+
+

Let us assume that we have the following Maven repository with a deployed stubs for the +streamService application.

+
+
+
+
└── .m2
+    └── repository
+        └── io
+            └── codearte
+                └── accurest
+                    └── stubs
+                        └── streamService
+                            ├── 0.0.1-SNAPSHOT
+                            │   ├── streamService-0.0.1-SNAPSHOT.pom
+                            │   ├── streamService-0.0.1-SNAPSHOT-stubs.jar
+                            │   └── maven-metadata-local.xml
+                            └── maven-metadata-local.xml
+
+
+
+

And the stubs contain the following structure:

+
+
+
+
├── META-INF
+│   └── MANIFEST.MF
+└── repository
+    ├── accurest
+    │   ├── bookDeleted.groovy
+    │   ├── bookReturned1.groovy
+    │   └── bookReturned2.groovy
+    └── mappings
+
+
+
+

Let’s consider the following contracts (let' number it with 1):

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_1'
+        input {
+                triggeredBy('bookReturnedTriggered()')
+        }
+        outputMessage {
+                sentTo('returnBook')
+                body('''{ "bookName" : "foo" }''')
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and number 2

+
+
+
+
io.codearte.accurest.dsl.GroovyDsl.make {
+        label 'return_book_2'
+        input {
+                messageFrom('bookStorage')
+                messageBody([
+                                bookName: 'foo'
+                ])
+                messageHeaders {
+                        header('sample', 'header')
+                }
+        }
+        outputMessage {
+                sentTo('returnBook')
+                body([
+                                bookName: 'foo'
+                ])
+                headers {
+                        header('BOOK-NAME', 'foo')
+                }
+        }
+}
+
+
+
+

and the following Spring configuration:

+
+
+
+
stubrunner.stubs.repository.root: classpath:m2repo/repository/
+stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs
+
+spring:
+  cloud:
+    stream:
+      bindings:
+        output:
+          destination: returnBook
+        input:
+          destination: bookStorage
+
+
+
+
+
Scenario 1 (no input message)
+
+

So as to trigger a message via the return_book_1 label we’ll use the StubTrigger interface as follows

+
+
+
+
stubFinder.trigger('return_book_1')
+
+
+
+

Next we’ll want to listen to the output of the message sent to a channel whose destination is returnBook

+
+
+
+
AccurestMessage receivedMessage = messaging.receiveMessage('returnBook')
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertJsons(receivedMessage.payload)
+receivedMessage.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 2 (output triggered by input)
+
+

Since the route is set for you it’s enough to just send a message to the bookStorage destination.

+
+
+
+
messaging.send(new BookReturned('foo'), [sample: 'header'], 'bookStorage')
+
+
+
+

Next we’ll want to listen to the output of the message sent to returnBook

+
+
+
+
AccurestMessage receivedMessage = messaging.receiveMessage('returnBook')
+
+
+
+

And the received message would pass the following assertions

+
+
+
+
receivedMessage != null
+assertJsons(receivedMessage.payload)
+receivedMessage.headers.get('BOOK-NAME') == 'foo'
+
+
+
+
+
Scenario 3 (input with no output)
+
+

Since the route is set for you it’s enough to just send a message to the output destination.

+
+
+
+
messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')
+
+
+
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/src/main/asciidoc/rest.adoc b/docs/src/main/asciidoc/rest.adoc index 6e7b614eb4..0e842f8445 100644 --- a/docs/src/main/asciidoc/rest.adoc +++ b/docs/src/main/asciidoc/rest.adoc @@ -124,7 +124,7 @@ When using Spring Cloud Contract Verifier in default MockMvc you need to create [source,groovy,indent=0] ---- -include::{verifier_root_path}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] +include::{verifier_root_path}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy[tags=base_class,indent=0] ---- In case of using `Explicit` mode, you can use base class to initialize the whole tested app similarly as in regular integration tests. In case of `JAXRSCLIENT` mode this base class From 51997003d46bff7676a6d5475fc2bf8f1bc41a20 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:02:48 +0200 Subject: [PATCH 685/719] Updated the githubpages plugin settings --- docs/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/build.gradle b/docs/build.gradle index b705c68551..b84d6cb43d 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -73,6 +73,6 @@ githubPages { } pages { - from 'build/asciidoc/html5' + from 'build/asciidoc/html' } } \ No newline at end of file From f9d71ccaedea2650c0d6017623356cb4c4d1e234 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:06:31 +0200 Subject: [PATCH 686/719] Added additional deprecated forlder for github pages --- docs/build.gradle | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docs/build.gradle b/docs/build.gradle index b84d6cb43d..f3b600f828 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -45,6 +45,13 @@ task generateReadme(type: com.github.jrubygradle.JRubyExec) { asciidoctor { dependsOn jrubyPrepare + resources { + from("src/main/asciidoc/deprecated") { + include '*/**' + } + into './deprecated' + } + sourceDir 'src/main/asciidoc' backends 'html' attributes 'build-gradle': file('build.gradle'), @@ -73,6 +80,8 @@ githubPages { } pages { - from 'build/asciidoc/html' + from('build/asciidoc/html') { + include '**/' + } } } \ No newline at end of file From ee402d43573fe03bab9ea9f08f1567bc5a212593 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:16:43 +0200 Subject: [PATCH 687/719] Adding missing images --- docs/build.gradle | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/build.gradle b/docs/build.gradle index f3b600f828..2a79e0ef8f 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -43,17 +43,20 @@ task generateReadme(type: com.github.jrubygradle.JRubyExec) { } asciidoctor { + String backend = 'html' dependsOn jrubyPrepare resources { - from("src/main/asciidoc/deprecated") { - include '*/**' + from("src/main/asciidoc/") { + include '**/*.png' + include '**/*.jpg' + include '**/*.html' } - into './deprecated' + into './' } sourceDir 'src/main/asciidoc' - backends 'html' + backends backend attributes 'build-gradle': file('build.gradle'), 'endpoint-url': 'https://Codearte.github.io/accurest', 'source-highlighter': 'coderay', From 7b8e0785786daa18638ceb7d31f9fe8f9403556b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:34:34 +0200 Subject: [PATCH 688/719] Fixed deploying of artifacts --- docs/pom.xml | 12 +++++++++ pom.xml | 26 +++++++------------ .../pom.xml | 17 ++++++++++++ 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/docs/pom.xml b/docs/pom.xml index 19fbf72425..1c02de1ddb 100644 --- a/docs/pom.xml +++ b/docs/pom.xml @@ -13,6 +13,7 @@ pom Spring Cloud Contract Verifier Docs Spring Contract Verifier Docs + 1.0.0.BUILD-SNAPSHOT spring-cloud-contract-verifier-maven-plugin ${basedir}/.. @@ -42,4 +43,15 @@ + + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + + diff --git a/pom.xml b/pom.xml index 0c779af437..2139d3fc35 100644 --- a/pom.xml +++ b/pom.xml @@ -57,23 +57,6 @@ HEAD - - - repo.spring.io - Spring Release Repository - https://repo.spring.io/plugins-release-local - - - repo.spring.io - Spring Snapshot Repository - https://repo.spring.io/plugins-snapshot-local - - - github - scm:git:ssh://git@github.com:Codearte/accurest-maven-plugin.git - - - GitHub Issues https://github.com/Codearte/accurest/labels/maven @@ -155,5 +138,14 @@ + + + org.apache.maven.plugins + maven-deploy-plugin + + true + + + diff --git a/spring-cloud-contract-verifier-maven-plugin/pom.xml b/spring-cloud-contract-verifier-maven-plugin/pom.xml index 761b92c484..17d3dfe4d6 100644 --- a/spring-cloud-contract-verifier-maven-plugin/pom.xml +++ b/spring-cloud-contract-verifier-maven-plugin/pom.xml @@ -28,6 +28,23 @@ 2016 + + + repo.spring.io + Spring Release Repository + https://repo.spring.io/plugins-release-local + + + repo.spring.io + Spring Snapshot Repository + https://repo.spring.io/plugins-snapshot-local + + + github + scm:git:ssh://git@github.com:Codearte/accurest-maven-plugin.git + + + From 26130232dcf1aff80daf749387f9339bf1baca02 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:43:05 +0200 Subject: [PATCH 689/719] Updated the docs --- docs/src/main/asciidoc/contract.adoc | 5 +- .../builder/ContractHttpDocsSpec.groovy | 46 +++++++++---------- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/docs/src/main/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc index a8b4d64053..a5c0545ca6 100644 --- a/docs/src/main/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -4,6 +4,9 @@ == Contract DSL +IMPORTANT: Remember that inside the contract file you have to provide the fully qualified name to +the `Contract` class and the `make` static import i.e. `org.springframework.cloud.contract.verifier.dsl.Contract.make { ... }` + Contract DSL is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more the DSL is designed to be programmer-readable without any knowledge of the DSL itself - it's statically typed. @@ -136,7 +139,7 @@ include::{verifier_root_path}/spring-cloud-contract-verifier-converters/src/test It is also possible to define a method call to be executed on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. Please see the examples below: -==== Groovy DSL +==== Contract DSL [source,groovy,indent=0] ---- diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy index 462c623cc4..27b417a9e7 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy @@ -16,8 +16,8 @@ package org.springframework.cloud.contract.verifier.builder -import org.springframework.cloud.contract.verifier.dsl.Contract import spock.lang.Specification + /** * Tests used for the documentation * @@ -25,9 +25,9 @@ import spock.lang.Specification */ class ContractHttpDocsSpec extends Specification { - Contract httpDsl = + org.springframework.cloud.contract.verifier.dsl.Contract httpDsl = // tag::http_dsl[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { // Definition of HTTP request part of the contract // (this can be a valid request or invalid depending // on type of contract being specified). @@ -49,9 +49,9 @@ class ContractHttpDocsSpec extends Specification { } // end::http_dsl[] - Contract request = + org.springframework.cloud.contract.verifier.dsl.Contract request = // tag::request[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { // HTTP request method (GET/POST/PUT/DELETE). method 'GET' @@ -66,9 +66,9 @@ class ContractHttpDocsSpec extends Specification { } // end::request[] - Contract url = + org.springframework.cloud.contract.verifier.dsl.Contract url = // tag::url[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'GET' @@ -82,9 +82,9 @@ class ContractHttpDocsSpec extends Specification { } // end::url[] - Contract urlPaths = + org.springframework.cloud.contract.verifier.dsl.Contract urlPaths = // tag::urlpath[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { //... @@ -127,9 +127,9 @@ class ContractHttpDocsSpec extends Specification { } // end::urlpath[] - Contract headers = + org.springframework.cloud.contract.verifier.dsl.Contract headers = // tag::headers[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { //... @@ -147,9 +147,9 @@ class ContractHttpDocsSpec extends Specification { } // end::headers[] - Contract body = + org.springframework.cloud.contract.verifier.dsl.Contract body = // tag::body[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { //... @@ -164,9 +164,9 @@ class ContractHttpDocsSpec extends Specification { } // end::body[] - Contract bodyAsXml = + org.springframework.cloud.contract.verifier.dsl.Contract bodyAsXml = // tag::bodyAsXml[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { //... @@ -182,9 +182,9 @@ class ContractHttpDocsSpec extends Specification { } // end::bodyAsXml[] - Contract response = + org.springframework.cloud.contract.verifier.dsl.Contract response = // tag::response[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { //... } @@ -196,9 +196,9 @@ class ContractHttpDocsSpec extends Specification { } // end::response[] - Contract regex = + org.springframework.cloud.contract.verifier.dsl.Contract regex = // tag::regex[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -227,9 +227,9 @@ class ContractHttpDocsSpec extends Specification { } // end::regex[] - Contract optionals = + org.springframework.cloud.contract.verifier.dsl.Contract optionals = // tag::optionals[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { priority 1 request { method 'POST' @@ -282,9 +282,9 @@ class ContractHttpDocsSpec extends Specification { stripped(blockBuilder.toString()) == stripped(expectedTest) } - Contract method = + org.springframework.cloud.contract.verifier.dsl.Contract method = // tag::method[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'PUT' url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) From 76edee5019838aca57268c8736850d65e807d5d6 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:45:52 +0200 Subject: [PATCH 690/719] Updated the docs --- docs/src/main/asciidoc/contract.adoc | 4 +++- .../verifier/builder/MockMvcMethodBodyBuilderSpec.groovy | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc index a5c0545ca6..a7216e3bd0 100644 --- a/docs/src/main/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -5,7 +5,9 @@ == Contract DSL IMPORTANT: Remember that inside the contract file you have to provide the fully qualified name to -the `Contract` class and the `make` static import i.e. `org.springframework.cloud.contract.verifier.dsl.Contract.make { ... }` +the `Contract` class and the `make` static import i.e. `org.springframework.cloud.contract.verifier.dsl.Contract.make { ... }`. +You can also provide an import to the `Contract` class `import org.springframework.cloud.contract.verifier.dsl.Contract` and then call + `Contract.make { ... }` Contract DSL is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more the DSL is designed to be programmer-readable without any knowledge of the DSL itself - diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy index 3b2e77c4b5..42a9c7db8c 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -1398,7 +1398,7 @@ World.'''""" Contract dslForDocs = // tag::dsl_example[] - Contract.make { + org.springframework.cloud.contract.verifier.dsl.Contract.make { request { method 'PUT' url '/api/12' From 3b60f6121ad270bccf7f1b7b4b2fcc5b6c0f58fb Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:54:21 +0200 Subject: [PATCH 691/719] Fixed links in the docs --- docs/src/main/asciidoc/rest.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/rest.adoc b/docs/src/main/asciidoc/rest.adoc index 0e842f8445..6bf3c847dd 100644 --- a/docs/src/main/asciidoc/rest.adoc +++ b/docs/src/main/asciidoc/rest.adoc @@ -66,7 +66,7 @@ repositories { ---- -Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugin] +Read more: http://codearte.github.io/accurest-maven-plugin/[spring-cloud-contract-verifier-maven-plugin] ===== Add stubs @@ -201,7 +201,7 @@ Underneath LoanApplication makes a call to FraudDetection service. This request ---- -Read more: http://codearte.github.io/accurest-maven-plugin/[accurest-maven-plugin] +Read more: http://codearte.github.io/accurest-maven-plugin/[spring-cloud-contract-verifier-maven-plugin] ==== Add stubs From b24547872ab2b575326c3635772cec3ba0939b34 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:57:11 +0200 Subject: [PATCH 692/719] Updated the docs with stub runner artifact ids --- .../spring-cloud-contract-stub-runner-boot/README.adoc | 6 +++--- .../spring-cloud-contract-stub-runner-camel/README.adoc | 2 +- .../README.adoc | 2 +- .../spring-cloud-contract-stub-runner-stream/README.adoc | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc index 24f7712612..99ed7baee7 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc @@ -20,11 +20,11 @@ and a messaging implementation: [source,groovy,indent=0] ---- // for Apache Camel -compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-messaging-camel:${verifierVersion}" +compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-camel:${verifierVersion}" // for Spring Integration -compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-messaging-integration:${verifierVersion}" +compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-integration:${verifierVersion}" // for Spring Cloud Stream -compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-messaging-stream:${verifierVersion}" +compile "org.springframework.cloud.contract:spring-cloud-contract-stub-runner-stream:${verifierVersion}" ---- Build a fat-jar and you're ready to go! diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc index 84eb4ac140..b5fc5ea13d 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc @@ -13,7 +13,7 @@ To use it you have to add the following dependency to your project (example for [source,groovy,indent=0] ---- -testCompile "org.springframework.cloud.contract:stub-runner-messaging-camel:${verifierVersion}" +testCompile "org.springframework.cloud.contract:stub-runner-camel:${verifierVersion}" ---- ==== Examples diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc index 2d2664bba1..84fb0bae7d 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc @@ -13,7 +13,7 @@ To use it you have to add the following dependency to your project (example for [source,groovy,indent=0] ---- -testCompile "org.springframework.cloud.contract:stub-runner-messaging-integration:${verifierVersion}" +testCompile "org.springframework.cloud.contract:stub-runner-integration:${verifierVersion}" ---- ==== Examples diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc index 670ea5201a..f6c062a5a0 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc @@ -14,7 +14,7 @@ To use it you have to add the following dependency to your project (example for [source,groovy,indent=0] ---- -testCompile "org.springframework.cloud.contract:stub-runner-messaging-stream:${verifierVersion}" +testCompile "org.springframework.cloud.contract:stub-runner-stream:${verifierVersion}" ---- ==== Examples From 81f43296b8ed9644839669cd8036deabb1bb007b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Mon, 20 Jun 2016 13:59:50 +0200 Subject: [PATCH 693/719] The more I commit, the more I earn --- .../spring-cloud-contract-stub-runner-camel/README.adoc | 2 +- .../spring-cloud-contract-stub-runner-integration/README.adoc | 2 +- .../spring-cloud-contract-stub-runner-stream/README.adoc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc index b5fc5ea13d..3fbd56f5dd 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc @@ -1,7 +1,7 @@ :input_name: jms:input :output_name: jms:output -=== Stub Runner Messaging Camel +=== Stub Runner Camel Spring Cloud Contract Verifier Stub Runner's messaging module gives you an easy way to integrate with Apache Camel. For the provided artifacts it will automatically download the stubs and register the required diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc index 84fb0bae7d..89f5a0a180 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc @@ -1,7 +1,7 @@ :input_name: input :output_name: output -=== Stub Runner Messaging Integration +=== Stub Runner Integration Spring Cloud Contract Verifier Stub Runner's messaging module gives you an easy way to integrate with Spring Integration. For the provided artifacts it will automatically download the stubs and register the required diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc index f6c062a5a0..e93eaeb43b 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc @@ -1,4 +1,4 @@ -=== Stub Runner Messaging Stream +=== Stub Runner Stream Spring Cloud Contract Verifier Stub Runner's messaging module gives you an easy way to integrate with Spring Stream. For the provided artifacts it will automatically download the stubs and register the required From ce2ffcfc295bd46bf998f694d83598c78727a027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcin=20Zaj=C4=85czkowski?= Date: Mon, 20 Jun 2016 23:13:22 +0200 Subject: [PATCH 694/719] Fix image link in README (#288) --- README.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.adoc b/README.adoc index 2e6334dfd2..bfc9812b6b 100644 --- a/README.adoc +++ b/README.adoc @@ -27,7 +27,7 @@ Spring Cloud Contract Verifier moves TDD to the level of software architecture. Let us assume that we have a system comprising of multiple microservices: -image::Deps.png[Microservices Architecture] +image::docs/src/main/asciidoc/images/Deps.png[Microservices Architecture] ==== Testing issues @@ -189,4 +189,4 @@ added after the original pull request but before a merge. other target branch in the main project). * When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions], if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit - message (where XXXX is the issue number). \ No newline at end of file + message (where XXXX is the issue number). From 86605065821685e219cf165002aeeb7c8f2dfe8b Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 21 Jun 2016 08:42:16 +0200 Subject: [PATCH 695/719] Updaed docs --- README.adoc | 13 ++++++++----- docs/src/main/asciidoc/introduction.adoc | 11 +++++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/README.adoc b/README.adoc index bfc9812b6b..aa162bf946 100644 --- a/README.adoc +++ b/README.adoc @@ -8,9 +8,12 @@ = Spring Cloud Contract Verifier +:images_url: https://raw.githubusercontent.com/Codearte/accurest/master/docs/src/main/asciidoc/images + == Introduction -IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here] +IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here.]. +The Accurest project was initially started in cooperation with the http://codearte.io[Codearte Company] Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: @@ -27,7 +30,7 @@ Spring Cloud Contract Verifier moves TDD to the level of software architecture. Let us assume that we have a system comprising of multiple microservices: -image::docs/src/main/asciidoc/images/Deps.png[Microservices Architecture] +image::{images_url}/Deps.png[Microservices Architecture] ==== Testing issues @@ -68,11 +71,11 @@ Disadvantages: To solve the aforementioned issues Spring Cloud Contract Verifier with Stub Runner were created. Their main idea is to give you very fast feedback, without the need to set up the whole world of microservices. -image::Stubs1.png[Stubbed Services] +image::{images_url}/Stubs1.png[Stubbed Services] If you work on stubs then the only applications you need are those that your application is using directly. -image::Stubs2.png[Stubbed Services] +image::{images_url}/Stubs2.png[Stubbed Services] Spring Cloud Contract Verifier gives you the certainty that the stubs that you're using were created by the service that you're calling. Also if you can use them it means that they were tested against the producer's side. In other words - you can trust those stubs. @@ -189,4 +192,4 @@ added after the original pull request but before a merge. other target branch in the main project). * When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions], if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit - message (where XXXX is the issue number). + message (where XXXX is the issue number). \ No newline at end of file diff --git a/docs/src/main/asciidoc/introduction.adoc b/docs/src/main/asciidoc/introduction.adoc index 26b5e2bd9a..2e31be2989 100644 --- a/docs/src/main/asciidoc/introduction.adoc +++ b/docs/src/main/asciidoc/introduction.adoc @@ -1,6 +1,9 @@ +:images_url: https://raw.githubusercontent.com/Codearte/accurest/master/docs/src/main/asciidoc/images + == Introduction -IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here] +IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here.]. +The Accurest project was initially started in cooperation with the http://codearte.io[Codearte Company] Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: @@ -17,7 +20,7 @@ Spring Cloud Contract Verifier moves TDD to the level of software architecture. Let us assume that we have a system comprising of multiple microservices: -image::Deps.png[Microservices Architecture] +image::{images_url}/Deps.png[Microservices Architecture] ==== Testing issues @@ -58,11 +61,11 @@ Disadvantages: To solve the aforementioned issues Spring Cloud Contract Verifier with Stub Runner were created. Their main idea is to give you very fast feedback, without the need to set up the whole world of microservices. -image::Stubs1.png[Stubbed Services] +image::{images_url}/Stubs1.png[Stubbed Services] If you work on stubs then the only applications you need are those that your application is using directly. -image::Stubs2.png[Stubbed Services] +image::{images_url}/Stubs2.png[Stubbed Services] Spring Cloud Contract Verifier gives you the certainty that the stubs that you're using were created by the service that you're calling. Also if you can use them it means that they were tested against the producer's side. In other words - you can trust those stubs. From db1ae1c93b6f19afe14357f2975f980154a47f21 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 21 Jun 2016 09:12:29 +0200 Subject: [PATCH 696/719] Updaed docs --- docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc b/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc index 8dc733a041..859cd12fc2 100644 --- a/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc +++ b/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc @@ -5,7 +5,7 @@ = Spring Cloud Contract Verifier -_Adam Dudczak, Marcin Grzejszczak, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła_ +_Documentation Authors: Adam Dudczak, Marcin Grzejszczak, Jakub Kubryński, Karol Lassak, Olga Maciaszek-Sharma, Mariusz Smykuła_ include::introduction.adoc[] From 33a57dd147f33ffa905a07482932ab9dd5432405 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 21 Jun 2016 10:37:15 +0200 Subject: [PATCH 697/719] Added tests for messaging --- .../camel/StubRunnerCamelProcessor.groovy | 9 ++- .../camel/StubRunnerCamelProcessorSpec.groovy | 67 +++++++++++++++++++ .../StubRunnerIntegrationTransformer.groovy | 2 +- ...tubRunnerIntegrationTransformerSpec.groovy | 64 ++++++++++++++++++ .../stream/StubRunnerStreamTransformer.groovy | 2 +- .../StubRunnerStreamTransformerSpec.groovy | 64 ++++++++++++++++++ .../verifier/util/BodyAsStringUtil.groovy | 4 +- 7 files changed, 205 insertions(+), 7 deletions(-) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy index 7bf6113f9b..b081115b52 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy @@ -41,11 +41,14 @@ class StubRunnerCamelProcessor implements Processor { @Override void process(Exchange exchange) throws Exception { Message input = exchange.in - input.body = BodyAsStringUtil.extractClientValueFrom(groovyDsl.outputMessage.body) - groovyDsl.input.messageHeaders.entries.each { + groovyDsl.input.messageHeaders?.entries?.each { input.removeHeader(it.name) } - groovyDsl.outputMessage.headers.entries.each { + if (!groovyDsl.outputMessage) { + return + } + input.body = BodyAsStringUtil.extractStubValueFrom(groovyDsl.outputMessage.body) + groovyDsl.outputMessage.headers?.entries?.each { input.setHeader(it.name, it.clientValue) } } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy new file mode 100644 index 0000000000..4ef4464ae9 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy @@ -0,0 +1,67 @@ +package org.springframework.cloud.contract.stubrunner.messaging.camel + +import org.apache.camel.CamelContext +import org.apache.camel.Exchange +import org.apache.camel.builder.ExchangeBuilder +import org.apache.camel.spring.SpringCamelContext +import org.springframework.cloud.contract.verifier.dsl.Contract +import spock.lang.Specification + +class StubRunnerCamelProcessorSpec extends Specification { + + CamelContext camelContext = new SpringCamelContext() + Exchange message = ExchangeBuilder.anExchange(camelContext).build() + + def noOutputMessageContract = Contract.make { + label 'return_book_2' + input { + messageFrom('bookStorage') + messageBody([ + bookId: $(consumer(regex('[0-9]+')), producer('123')) + ]) + messageHeaders { + header('sample', 'header') + } + } + } + + def 'should not process the message if there is no output message'() { + given: + StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor(noOutputMessageContract) + when: + processor.process(message) + then: + noExceptionThrown() + } + + def dsl = Contract.make { + label 'return_book_2' + input { + messageFrom('bookStorage') + messageBody([ + bookId: $(consumer(regex('[0-9]+')), producer('123')) + ]) + messageHeaders { + header('sample', 'header') + } + } + outputMessage { + sentTo('returnBook') + body([ + responseId: $(producer(regex('[0-9]+')), consumer('123')) + ]) + headers { + header('BOOK-NAME', 'foo') + } + } + } + + def 'should process message when it has an output message section'() { + given: + StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor(dsl) + when: + processor.process(message) + then: + message.getIn().getBody(String) == '{"responseId":"123"}' + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy index d45dafcc81..3a88865e72 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy @@ -41,7 +41,7 @@ class StubRunnerIntegrationTransformer implements GenericTransformer, if (!groovyDsl.outputMessage) { return source } - String payload = BodyAsStringUtil.extractClientValueFrom(groovyDsl.outputMessage.body) + String payload = BodyAsStringUtil.extractStubValueFrom(groovyDsl.outputMessage.body) Map headers = groovyDsl.outputMessage.headers.asStubSideMap() return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy new file mode 100644 index 0000000000..2a16bff2df --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy @@ -0,0 +1,64 @@ +package org.springframework.cloud.contract.stubrunner.messaging.integration + +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.messaging.Message +import org.springframework.messaging.support.MessageBuilder +import spock.lang.Specification + +class StubRunnerIntegrationTransformerSpec extends Specification { + + Message message = MessageBuilder.withPayload("hello").build() + + def noOutputMessageContract = Contract.make { + label 'return_book_2' + input { + messageFrom('bookStorage') + messageBody([ + bookId: $(consumer(regex('[0-9]+')), producer('123')) + ]) + messageHeaders { + header('sample', 'header') + } + } + } + + def 'should not transform the message if there is no output message'() { + given: + StubRunnerIntegrationTransformer transformer = new StubRunnerIntegrationTransformer(noOutputMessageContract) + when: + def result = transformer.transform(message) + then: + result.is(message) + } + + def dsl = Contract.make { + label 'return_book_2' + input { + messageFrom('bookStorage') + messageBody([ + bookId: $(consumer(regex('[0-9]+')), producer('123')) + ]) + messageHeaders { + header('sample', 'header') + } + } + outputMessage { + sentTo('returnBook') + body([ + responseId: $(producer(regex('[0-9]+')), consumer('123')) + ]) + headers { + header('BOOK-NAME', 'foo') + } + } + } + + def 'should convert dsl into message'() { + given: + StubRunnerIntegrationTransformer transformer = new StubRunnerIntegrationTransformer(dsl) + when: + def result = transformer.transform(message) + then: + result.payload == '{"responseId":"123"}' + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy index 949304099c..fb304ca301 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy @@ -41,7 +41,7 @@ class StubRunnerStreamTransformer implements GenericTransformer, Mess if (!groovyDsl.outputMessage) { return source } - String payload = BodyAsStringUtil.extractClientValueFrom(groovyDsl.outputMessage.body) + String payload = BodyAsStringUtil.extractStubValueFrom(groovyDsl.outputMessage.body) Map headers = groovyDsl.outputMessage.headers.asStubSideMap() return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy new file mode 100644 index 0000000000..29029a39db --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy @@ -0,0 +1,64 @@ +package org.springframework.cloud.contract.stubrunner.messaging.stream + +import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.messaging.Message +import org.springframework.messaging.support.MessageBuilder +import spock.lang.Specification + +class StubRunnerStreamTransformerSpec extends Specification { + + Message message = MessageBuilder.withPayload("hello").build() + + def noOutputMessageContract = Contract.make { + label 'return_book_2' + input { + messageFrom('bookStorage') + messageBody([ + bookId: $(consumer(regex('[0-9]+')), producer('123')) + ]) + messageHeaders { + header('sample', 'header') + } + } + } + + def 'should not transform the message if there is no output message'() { + given: + StubRunnerStreamTransformer streamTransformer = new StubRunnerStreamTransformer(noOutputMessageContract) + when: + def result = streamTransformer.transform(message) + then: + result.is(message) + } + + def dsl = Contract.make { + label 'return_book_2' + input { + messageFrom('bookStorage') + messageBody([ + bookId: $(consumer(regex('[0-9]+')), producer('123')) + ]) + messageHeaders { + header('sample', 'header') + } + } + outputMessage { + sentTo('returnBook') + body([ + responseId: $(producer(regex('[0-9]+')), consumer('123')) + ]) + headers { + header('BOOK-NAME', 'foo') + } + } + } + + def 'should convert dsl into message'() { + given: + StubRunnerStreamTransformer streamTransformer = new StubRunnerStreamTransformer(dsl) + when: + def result = streamTransformer.transform(message) + then: + result.payload == '{"responseId":"123"}' + } +} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy index 44963c84b3..e6bfe085fd 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy @@ -40,7 +40,7 @@ class BodyAsStringUtil { * That means that all the interpolations etc. will be resolved for the * server side. */ - static String extractServerValueFrom(Object body) { + static String extractTestValueFrom(Object body) { Object bodyValue = extractServerValueFromBody(body) String json = new JsonOutput().toJson(bodyValue) json = StringEscapeUtils.unescapeJavaScript(json) @@ -52,7 +52,7 @@ class BodyAsStringUtil { * That means that all the interpolations etc. will be resolved for the * client side. */ - static String extractClientValueFrom(Object body) { + static String extractStubValueFrom(Object body) { Object bodyValue = extractClientValueFromBody(body); String json = new JsonOutput().toJson(bodyValue) json = StringEscapeUtils.unescapeJavaScript(json) From 89f937ea400c8813099e3e59a6c833cf0436d249 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 21 Jun 2016 10:37:41 +0200 Subject: [PATCH 698/719] Updated docs --- docs/src/main/asciidoc/introduction.adoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/introduction.adoc b/docs/src/main/asciidoc/introduction.adoc index 2e31be2989..725e5d51fe 100644 --- a/docs/src/main/asciidoc/introduction.adoc +++ b/docs/src/main/asciidoc/introduction.adoc @@ -2,8 +2,9 @@ == Introduction -IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here.]. -The Accurest project was initially started in cooperation with the http://codearte.io[Codearte Company] +IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here.] + +TIP: The Accurest project was initially started in cooperation with the http://codearte.io[Codearte Company] Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: From bad5d6de509cbe29526ff89652d35aa7ea8a2ab2 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 21 Jun 2016 10:58:13 +0200 Subject: [PATCH 699/719] Updated docs --- docs/src/main/asciidoc/introduction.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/introduction.adoc b/docs/src/main/asciidoc/introduction.adoc index 725e5d51fe..fbb2933bbf 100644 --- a/docs/src/main/asciidoc/introduction.adoc +++ b/docs/src/main/asciidoc/introduction.adoc @@ -4,7 +4,7 @@ IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here.] -TIP: The Accurest project was initially started in cooperation with the http://codearte.io[Codearte Company] +TIP: The Accurest project was initially started by Marcin Grzejszczak and Jakub Kubrynski (http://codearte.io[codearte.io]) Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: From b38372011c2e6b4b4da06f79878e518c655b6f08 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 21 Jun 2016 20:24:20 +0200 Subject: [PATCH 700/719] Fixed the bug with regex in GString in messaging --- .../camel/StubRunnerCamelProcessorSpec.groovy | 31 +++++++++++++++++++ ...tubRunnerIntegrationTransformerSpec.groovy | 31 +++++++++++++++++++ .../StubRunnerStreamTransformerSpec.groovy | 31 +++++++++++++++++++ .../verifier/util/BodyAsStringUtil.groovy | 7 +++-- 4 files changed, 97 insertions(+), 3 deletions(-) diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy index 4ef4464ae9..8e9eed110d 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy @@ -64,4 +64,35 @@ class StubRunnerCamelProcessorSpec extends Specification { then: message.getIn().getBody(String) == '{"responseId":"123"}' } + + def dslWithRegexInGString = Contract.make { + // Human readable description + description 'Should produce valid sensor data' + // Label by means of which the output message can be triggered + label 'sensor1' + // input to the contract + input { + // the contract will be triggered by a method + triggeredBy('createSensorData()') + } + // output message of the contract + outputMessage { + // destination to which the output message will be sent + sentTo 'sensor-data' + headers { + header('contentType': 'application/json') + } + // the body of the output message + body("""{"id":"${value(producer(regex('[0-9]+')), consumer('99'))}","temperature":"123.45"}""") + } + } + + def 'should convert dsl into message with regex in GString'() { + given: + StubRunnerCamelProcessor processor = new StubRunnerCamelProcessor(dslWithRegexInGString) + when: + processor.process(message) + then: + message.getIn().getBody(String) == '''{"id":"99","temperature":"123.45"}''' + } } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy index 2a16bff2df..010b849826 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy @@ -61,4 +61,35 @@ class StubRunnerIntegrationTransformerSpec extends Specification { then: result.payload == '{"responseId":"123"}' } + + def dslWithRegexInGString = Contract.make { + // Human readable description + description 'Should produce valid sensor data' + // Label by means of which the output message can be triggered + label 'sensor1' + // input to the contract + input { + // the contract will be triggered by a method + triggeredBy('createSensorData()') + } + // output message of the contract + outputMessage { + // destination to which the output message will be sent + sentTo 'sensor-data' + headers { + header('contentType': 'application/json') + } + // the body of the output message + body("""{"id":"${value(producer(regex('[0-9]+')), consumer('99'))}","temperature":"123.45"}""") + } + } + + def 'should convert dsl into message with regex in GString'() { + given: + StubRunnerIntegrationTransformer transformer = new StubRunnerIntegrationTransformer(dslWithRegexInGString) + when: + def result = transformer.transform(message) + then: + result.payload == '''{"id":"99","temperature":"123.45"}''' + } } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy index 29029a39db..15dd47545c 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy @@ -61,4 +61,35 @@ class StubRunnerStreamTransformerSpec extends Specification { then: result.payload == '{"responseId":"123"}' } + + def dslWithRegexInGString = Contract.make { + // Human readable description + description 'Should produce valid sensor data' + // Label by means of which the output message can be triggered + label 'sensor1' + // input to the contract + input { + // the contract will be triggered by a method + triggeredBy('createSensorData()') + } + // output message of the contract + outputMessage { + // destination to which the output message will be sent + sentTo 'sensor-data' + headers { + header('contentType': 'application/json') + } + // the body of the output message + body("""{"id":"${value(producer(regex('[0-9]+')), consumer('99'))}","temperature":"123.45"}""") + } + } + + def 'should convert dsl into message with regex in GString'() { + given: + StubRunnerStreamTransformer streamTransformer = new StubRunnerStreamTransformer(dslWithRegexInGString) + when: + def result = streamTransformer.transform(message) + then: + result.payload == '''{"id":"99","temperature":"123.45"}''' + } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy index e6bfe085fd..571dfdf2dc 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy @@ -74,10 +74,11 @@ class BodyAsStringUtil { private static Object extractClientValueFromBody(bodyValue) { if (bodyValue instanceof GString) { - bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.clientValue }) + return extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.clientValue }) + } else if (bodyValue instanceof DslProperty) { + return extractClientValueFromBody(bodyValue.clientValue) } else { - bodyValue = MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.clientValue : it }) + return MapConverter.transformValues(bodyValue, { it instanceof DslProperty ? it.clientValue : it }) } - return bodyValue } } From f51156fc3d5d5d81b340fe4f2f268e5081eebeb1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Sat, 25 Jun 2016 10:27:27 +0200 Subject: [PATCH 701/719] Added a section in introduction --- README.adoc | 18 ++++++++++++++++-- docs/src/main/asciidoc/introduction.adoc | 15 ++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/README.adoc b/README.adoc index aa162bf946..2796a76e7f 100644 --- a/README.adoc +++ b/README.adoc @@ -12,8 +12,9 @@ == Introduction -IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here.]. -The Accurest project was initially started in cooperation with the http://codearte.io[Codearte Company] +IMPORTANT: http://codearte.github.io/accurest/deprecated[The documentation to the deprecated Accurest project in version 1.1.0 is available here.] + +TIP: The Accurest project was initially started by Marcin Grzejszczak and Jakub Kubrynski (http://codearte.io[codearte.io]) Just to make long story short - Spring Cloud Contract Verifier is a tool that enables Consumer Driven Contract (CDC) development of JVM-based applications. It is shipped with __Contract Definition Language__ (DSL). Contract definitions are used to produce following resources: @@ -143,6 +144,19 @@ video::130779882[vimeo] Here you can find some https://github.com/Codearte/accurest-samples[working samples]. Check the readme of each project for more information. +=== Why use Spring Cloud Contract Verifier and not X ? + +For the time being Spring Cloud Contract Verifier is a JVM based tool. So it could be your first pick when you're already creating +software for the JVM. This project has a lot of really interesting features but especially quite a few of them definitely make +Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are: + +- Possibility to do CDC with messaging +- Clear and easy to use, statically typed DSL +- Possibility to copy paste your current JSON file to the contract and only edit its elements +- Automatic generation of tests from the defined Contract +- Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory +- Spring Cloud integration - no discovery service is needed for integration tests + == Documentation You can read more about Spring Cloud Contract Verifier by reading the {documentation_url}[docs] diff --git a/docs/src/main/asciidoc/introduction.adoc b/docs/src/main/asciidoc/introduction.adoc index fbb2933bbf..86eb75f37d 100644 --- a/docs/src/main/asciidoc/introduction.adoc +++ b/docs/src/main/asciidoc/introduction.adoc @@ -132,4 +132,17 @@ video::130779882[vimeo] === Samples -Here you can find some https://github.com/Codearte/accurest-samples[working samples]. Check the readme of each project for more information. \ No newline at end of file +Here you can find some https://github.com/Codearte/accurest-samples[working samples]. Check the readme of each project for more information. + +=== Why use Spring Cloud Contract Verifier and not X ? + +For the time being Spring Cloud Contract Verifier is a JVM based tool. So it could be your first pick when you're already creating +software for the JVM. This project has a lot of really interesting features but especially quite a few of them definitely make +Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are: + +- Possibility to do CDC with messaging +- Clear and easy to use, statically typed DSL +- Possibility to copy paste your current JSON file to the contract and only edit its elements +- Automatic generation of tests from the defined Contract +- Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory +- Spring Cloud integration - no discovery service is needed for integration tests \ No newline at end of file From d4e731f87b85ae03829bd644ae9ae6823d99364c Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 28 Jun 2016 22:38:29 +0200 Subject: [PATCH 702/719] Added a test to ensure that transformer is working fine --- .../StubRunnerStreamTransformerSpec.groovy | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy index 15dd47545c..1b53430f1c 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy @@ -92,4 +92,41 @@ class StubRunnerStreamTransformerSpec extends Specification { then: result.payload == '''{"id":"99","temperature":"123.45"}''' } + + def 'should parse dsl without DslProperty'() { + given: + Contract contract = Contract.make { + // Human readable description + description 'Sends an order message' + // Label by means of which the output message can be triggered + label 'send_order' + // input to the contract + input { + // the contract will be triggered by a method + triggeredBy('orderTrigger()') + } + // output message of the contract + outputMessage { + // destination to which the output message will be sent + sentTo('orders') + // any headers for the output message + headers { + header('contentType': 'application/json') + } + // the body of the output message + body( + orderId: value( + consumer('40058c70-891c-4176-a033-f70bad0c5f77'), + producer(regex('([0-9|a-f]*-*)*'))), + description: "This is the order description" + ) + } + } + StubRunnerStreamTransformer streamTransformer = new StubRunnerStreamTransformer(contract) + when: + def result = streamTransformer.transform(message) + then: + result.payload == '''{"orderId":"40058c70-891c-4176-a033-f70bad0c5f77","description":"This is the order description"}''' + } + } From 845002bc78c909135c63a867b9e0545e03e5f9b1 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 28 Jun 2016 22:38:36 +0200 Subject: [PATCH 703/719] Polish --- gradle.properties | 5 +++-- .../build.gradle | 2 +- .../build.gradle | 12 ------------ .../build.gradle | 11 ----------- .../build.gradle | 11 ----------- 5 files changed, 4 insertions(+), 37 deletions(-) diff --git a/gradle.properties b/gradle.properties index 4f7bae8abc..91057965e2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,8 +24,9 @@ BOM_VERSION=Brixton-SR1 springBootVersion=1.3.3.RELEASE springVersion=4.2.5.RELEASE springIntegrationDslVersion=1.1.2.RELEASE -springStreamVersion=1.0.0.RC2 -springCloudVersion=1.1.0.RC2 +springStreamVersion=1.0.0.RELEASE +springCloudVersion=1.1.0.RELEASE +springCloudZookeeperVersion=1.0.0.RELEASE camelVersion=2.17.0 aetherVersion=1.1.0 diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle index b015f00ef4..0484ddae5c 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle @@ -29,7 +29,7 @@ dependencies { } testCompile 'cglib:cglib-nodep:2.2' testCompile 'org.objenesis:objenesis:2.1' - testCompile 'org.springframework.cloud:spring-cloud-starter-zookeeper-discovery:1.0.0.RC2' + testCompile "org.springframework.cloud:spring-cloud-starter-zookeeper-discovery:${springCloudZookeeperVersion}" testCompile 'org.apache.curator:curator-test:2.9.1' testCompile 'io.reactivex:rxjava:1.1.1' testCompile "org.springframework.boot:spring-boot-starter-test:${springBootVersion}" diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle index dc27dcd2b2..fd255690d6 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle @@ -13,18 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - String verifier = "spring-cloud-contract-verifier" dependencies { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle index b69c26a76c..e785784138 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle @@ -16,17 +16,6 @@ String verifier = "spring-cloud-contract-verifier" -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - dependencies { compile project(":$verifier-root:$verifier-messaging-root:$verifier-messaging-core") compile "org.springframework:spring-messaging:${springVersion}" diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle index 6d894381a3..bfaed27076 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle @@ -14,17 +14,6 @@ * limitations under the License. */ -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - String verifier = "spring-cloud-contract-verifier" dependencies { From 68559b257701d484884eaa9afce29587f8c72d3d Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 28 Jun 2016 22:57:45 +0200 Subject: [PATCH 704/719] Fixed the bug with bad sent msgs --- .../messaging/camel/StubRunnerCamelProcessor.groovy | 4 ++-- .../integration/StubRunnerIntegrationTransformer.groovy | 4 ++-- .../messaging/stream/StubRunnerStreamTransformer.groovy | 4 ++-- .../cloud/contract/stubrunner/StubRunnerExecutor.groovy | 4 +++- .../{BodyAsStringUtil.groovy => BodyExtractor.groovy} | 8 ++++---- 5 files changed, 13 insertions(+), 11 deletions(-) rename spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/{BodyAsStringUtil.groovy => BodyExtractor.groovy} (93%) diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy index b081115b52..bca7ee94b9 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy @@ -17,7 +17,7 @@ package org.springframework.cloud.contract.stubrunner.messaging.camel import groovy.transform.PackageScope -import org.springframework.cloud.contract.verifier.util.BodyAsStringUtil +import org.springframework.cloud.contract.verifier.util.BodyExtractor import org.apache.camel.Exchange import org.apache.camel.Message import org.apache.camel.Processor @@ -47,7 +47,7 @@ class StubRunnerCamelProcessor implements Processor { if (!groovyDsl.outputMessage) { return } - input.body = BodyAsStringUtil.extractStubValueFrom(groovyDsl.outputMessage.body) + input.body = BodyExtractor.extractStubValueFrom(groovyDsl.outputMessage.body) groovyDsl.outputMessage.headers?.entries?.each { input.setHeader(it.name, it.clientValue) } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy index 3a88865e72..6dd212e46a 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy @@ -17,7 +17,7 @@ package org.springframework.cloud.contract.stubrunner.messaging.integration import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.util.BodyAsStringUtil +import org.springframework.cloud.contract.verifier.util.BodyExtractor import org.springframework.integration.transformer.GenericTransformer import org.springframework.messaging.Message import org.springframework.messaging.MessageHeaders @@ -41,7 +41,7 @@ class StubRunnerIntegrationTransformer implements GenericTransformer, if (!groovyDsl.outputMessage) { return source } - String payload = BodyAsStringUtil.extractStubValueFrom(groovyDsl.outputMessage.body) + String payload = BodyExtractor.extractStubValueFrom(groovyDsl.outputMessage.body) Map headers = groovyDsl.outputMessage.headers.asStubSideMap() return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy index fb304ca301..37ffc6ff76 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy @@ -16,7 +16,7 @@ package org.springframework.cloud.contract.stubrunner.messaging.stream -import org.springframework.cloud.contract.verifier.util.BodyAsStringUtil +import org.springframework.cloud.contract.verifier.util.BodyExtractor import org.springframework.cloud.contract.verifier.dsl.Contract import org.springframework.integration.transformer.GenericTransformer import org.springframework.messaging.Message @@ -41,7 +41,7 @@ class StubRunnerStreamTransformer implements GenericTransformer, Mess if (!groovyDsl.outputMessage) { return source } - String payload = BodyAsStringUtil.extractStubValueFrom(groovyDsl.outputMessage.body) + String payload = BodyExtractor.extractStubValueFrom(groovyDsl.outputMessage.body) Map headers = groovyDsl.outputMessage.headers.asStubSideMap() return MessageBuilder.createMessage(payload, new MessageHeaders(headers)) } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy index 3f688e177d..f2734d618a 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy @@ -22,6 +22,7 @@ import org.springframework.cloud.contract.verifier.dsl.Contract import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging +import org.springframework.cloud.contract.verifier.util.BodyExtractor /** * Runs stubs for a particular {@link StubServer} @@ -127,7 +128,8 @@ class StubRunnerExecutor implements StubFinder { if (!groovyDsl.outputMessage) { return } - ContractVerifierMessage message = contractVerifierMessaging.create(groovyDsl.outputMessage?.body?.clientValue, + ContractVerifierMessage message = contractVerifierMessaging.create( + BodyExtractor.extractClientValueFromBody(groovyDsl.outputMessage?.body?.clientValue), groovyDsl.outputMessage?.headers?.asStubSideMap()) contractVerifierMessaging.send(message, groovyDsl.outputMessage.sentTo.clientValue) } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy similarity index 93% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy index 571dfdf2dc..c5f4b4279a 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyAsStringUtil.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy @@ -31,9 +31,9 @@ import static ContentUtils.extractValue * @since 1.0.0 */ @CompileStatic -class BodyAsStringUtil { +class BodyExtractor { - private BodyAsStringUtil() {} + private BodyExtractor() {} /** * Returns the string representation of the body for the server side. @@ -63,7 +63,7 @@ class BodyAsStringUtil { return toTrim.startsWith('"') ? toTrim.replaceAll('"', '') : toTrim } - private static Object extractServerValueFromBody(bodyValue) { + static Object extractServerValueFromBody(bodyValue) { if (bodyValue instanceof GString) { bodyValue = extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.serverValue }) } else { @@ -72,7 +72,7 @@ class BodyAsStringUtil { return bodyValue } - private static Object extractClientValueFromBody(bodyValue) { + static Object extractClientValueFromBody(bodyValue) { if (bodyValue instanceof GString) { return extractValue(bodyValue, { DslProperty dslProperty -> dslProperty.clientValue }) } else if (bodyValue instanceof DslProperty) { From ddf92f7150dea3c7728966caaa3a0affb8277ced Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Tue, 28 Jun 2016 23:22:28 +0200 Subject: [PATCH 705/719] Added a missing test for message sending --- .../stubrunner/StubRunnerExecutorSpec.groovy | 50 +++++++++++++++++++ .../repository/contracts/contract1.groovy | 27 ++++++++++ 2 files changed, 77 insertions(+) create mode 100644 spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy index ad59d1374b..ad8b9bfe41 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy @@ -16,9 +16,14 @@ package org.springframework.cloud.contract.stubrunner +import groovy.json.JsonOutput import org.springframework.cloud.contract.stubrunner.util.StubsParser +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage +import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import spock.lang.Specification +import java.util.concurrent.TimeUnit + class StubRunnerExecutorSpec extends Specification { static final int MIN_PORT = 8999 @@ -71,10 +76,55 @@ class StubRunnerExecutorSpec extends Specification { executor.findStubUrl("group", "artifact") == 'http://localhost:12345'.toURL() } + def 'should ensure that triggered contracts have properly parsed message body when a message is sent'() { + given: + StubRunnerExecutor executor = new StubRunnerExecutor(portScanner, new AssertingContractVerifierMessaging()) + executor.runStubs(stubRunnerOptions, repository, stub) + when: + executor.trigger('send_order') + then: + noExceptionThrown() + } + Map stubIdsWithPortsFromString(String stubIdsToPortMapping) { return stubIdsToPortMapping.split(',').collectEntries { String entry -> return StubsParser.fromStringWithPort(entry) } } + private class AssertingContractVerifierMessaging implements ContractVerifierMessaging { + + @Override + void send(ContractVerifierMessage message, String destination) { + + } + + @Override + ContractVerifierMessage receiveMessage(String destination, long timeout, TimeUnit timeUnit) { + return null + } + + @Override + ContractVerifierMessage receiveMessage(String destination) { + return null + } + + @Override + void send(Object o, Map headers, String destination) { + + } + + @Override + ContractVerifierMessage create(Object o, Map headers) { + assert !(JsonOutput.toJson(o).contains("serverValue")) + assert headers.entrySet().every { !(it.value.toString().contains("serverValue")) } + return null + } + + @Override + ContractVerifierMessage create(Object o) { + return null + } + } + } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy new file mode 100644 index 0000000000..bd67b68b91 --- /dev/null +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy @@ -0,0 +1,27 @@ +org.springframework.cloud.contract.verifier.dsl.Contract.make { + // Human readable description + description 'Sends an order message' + // Label by means of which the output message can be triggered + label 'send_order' + // input to the contract + input { + // the contract will be triggered by a method + triggeredBy('orderTrigger()') + } + // output message of the contract + outputMessage { + // destination to which the output message will be sent + sentTo('orders') + // any headers for the output message + headers { + header('contentType': 'application/json') + } + // the body of the output message + body( + orderId: value( + consumer('40058c70-891c-4176-a033-f70bad0c5f77'), + producer(regex('([0-9|a-f]*-*)*'))), + description: "This is the order description" + ) + } +} \ No newline at end of file From 8f37b1823dc2f5716a9f1b636b8cc0c606e0e521 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Jun 2016 18:59:44 +0200 Subject: [PATCH 706/719] Big refactoring moved the contract to the spec modules changed the package of the contract fixed a couple of bugs related to stream messaging fixed a bug related to not copying of contracts via Gradle --- docs/src/main/asciidoc/contract.adoc | 6 +- samples/samples-messaging-camel/build.gradle | 12 -- .../CamelMessagingApplicationSpec.groovy | 2 +- .../build.gradle | 12 -- ...IntegrationMessagingApplicationSpec.groovy | 2 +- .../spring/SpringApplicationSpec.groovy | 2 +- .../StreamMessagingApplicationSpec.groovy | 2 +- settings.gradle | 2 + .../cloud/contract/spec}/Contract.groovy | 10 +- .../spec}/ContractVerifierException.groovy | 2 +- .../cloud/contract/spec}/internal/Body.groovy | 2 +- .../spec}/internal/ClientDslProperty.groovy | 2 +- .../contract/spec}/internal/Common.groovy | 2 +- .../spec}/internal/DslProperty.groovy | 2 +- .../spec}/internal/ExecutionProperty.groovy | 2 +- .../contract/spec}/internal/Header.groovy | 2 +- .../contract/spec}/internal/Headers.groovy | 2 +- .../contract/spec}/internal/Input.groovy | 2 +- .../spec}/internal/JSONCompareMode.groovy | 2 +- .../spec}/internal/MatchingStrategy.groovy | 2 +- .../contract/spec}/internal/Multipart.groovy | 2 +- .../spec}/internal/NamedProperty.groovy | 2 +- .../spec}/internal/OptionalProperty.groovy | 2 +- .../spec}/internal/OutputMessage.groovy | 2 +- .../spec}/internal/QueryParameter.groovy | 4 +- .../spec}/internal/QueryParameters.groovy | 2 +- .../spec}/internal/RegexPatterns.groovy | 2 +- .../contract/spec}/internal/Request.groovy | 2 +- .../contract/spec}/internal/Response.groovy | 2 +- .../spec}/internal/ServerDslProperty.groovy | 2 +- .../cloud/contract/spec}/internal/Url.groovy | 4 +- .../contract/spec}/internal/UrlPath.groovy | 2 +- .../contract/spec}/util/ValidateUtils.groovy | 10 +- .../internal/ExecutionPropertySpec.groovy | 35 ++++++ .../spec/internal/RegexPatternsSpec.groovy | 78 +++++++++++++ .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 1788 -> 1762 bytes .../stubrunner/junit/StubRunnerRule.java | 2 +- .../build.gradle | 12 -- .../camel/StubRunnerCamelConfiguration.groovy | 2 +- .../camel/StubRunnerCamelPredicate.groovy | 2 +- .../camel/StubRunnerCamelProcessor.groovy | 2 +- .../camel/CamelStubRunnerSpec.groovy | 2 +- .../camel/StubRunnerCamelProcessorSpec.groovy | 2 +- .../camelService-0.0.1-SNAPSHOT-stubs.jar | Bin 1797 -> 1773 bytes .../build.gradle | 11 -- .../StubRunnerIntegrationConfiguration.groovy | 2 +- ...tubRunnerIntegrationMessageSelector.groovy | 2 +- .../StubRunnerIntegrationTransformer.groovy | 2 +- .../IntegrationStubRunnerSpec.groovy | 2 +- ...tubRunnerIntegrationTransformerSpec.groovy | 2 +- ...ntegrationService-0.0.1-SNAPSHOT-stubs.jar | Bin 1788 -> 1762 bytes .../build.gradle | 12 -- .../StubRunnerStreamConfiguration.groovy | 2 +- .../StubRunnerStreamMessageSelector.groovy | 2 +- .../stream/StubRunnerStreamTransformer.groovy | 2 +- .../stream/StreamStubRunnerSpec.groovy | 2 +- .../StubRunnerStreamTransformerSpec.groovy | 2 +- .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin 1809 -> 1769 bytes .../stubrunner/BatchStubRunner.groovy | 4 +- .../stubrunner/GroovyDslWrapper.groovy | 2 +- .../cloud/contract/stubrunner/StubData.groovy | 2 +- .../contract/stubrunner/StubFinder.groovy | 2 +- .../contract/stubrunner/StubRepository.groovy | 2 +- .../contract/stubrunner/StubRunner.groovy | 2 +- .../stubrunner/StubRunnerExecutor.groovy | 5 +- .../contract/stubrunner/StubServer.groovy | 2 +- .../repository/contracts/contract1.groovy | 2 +- spring-cloud-contract-verifier/build.gradle | 1 + ...ConversionContractVerifierException.groovy | 2 +- .../wiremock/DslToWireMockConverter.groovy | 2 +- .../wiremock/RecursiveFilesConverter.groovy | 34 ++++-- .../wiremock/WireMockToDslConverter.groovy | 2 +- .../DslToWireMockClientConverterSpec.groovy | 10 +- .../RecursiveFilesConverterSpec.groovy | 10 +- .../WireMockToDslConverterSpec.groovy | 24 ++-- .../scenario/main_scenario/01_login.groovy | 2 +- .../scenario/main_scenario/02_showCart.groovy | 2 +- .../scenario/main_scenario/03_logout.groovy | 2 +- .../converter/source/dir1/dsl1.groovy | 2 +- .../converter/source/dir1/dsl1b.groovy | 2 +- .../converter/source/dir2/dsl2.groovy | 2 +- .../resources/converter/source/dslRoot.groovy | 2 +- .../contract/verifier/TestGenerator.groovy | 8 +- .../JUnitMessagingMethodBodyBuilder.groovy | 10 +- .../builder/JUnitMethodBodyBuilder.groovy | 10 +- .../JaxRsClientJUnitMethodBodyBuilder.groovy | 10 +- ...kMethodRequestProcessingBodyBuilder.groovy | 10 +- .../builder/MessagingMethodBodyBuilder.groovy | 6 +- .../verifier/builder/MethodBodyBuilder.groovy | 14 +-- .../verifier/builder/MethodBuilder.groovy | 6 +- .../MockMvcJUnitMethodBodyBuilder.groovy | 6 +- ...kMethodRequestProcessingBodyBuilder.groovy | 6 +- .../RequestProcessingMethodBodyBuilder.groovy | 16 +-- .../builder/SingleTestGenerator.groovy | 4 +- .../SpockMessagingMethodBodyBuilder.groovy | 10 +- ...kMethodRequestProcessingBodyBuilder.groovy | 10 +- .../wiremock/BaseWireMockStubStrategy.groovy | 4 +- .../WireMockRequestStubStrategy.groovy | 18 +-- .../WireMockResponseStubStrategy.groovy | 6 +- .../dsl/wiremock/WireMockStubStrategy.groovy | 2 +- .../verifier/util/BodyExtractor.groovy | 2 +- .../verifier/util/ContentUtils.groovy | 12 +- .../util/ContractVerifierDslConverter.groovy | 2 +- .../util/JsonToJsonPathsConverter.groovy | 4 +- .../verifier/util/MapConverter.groovy | 4 +- .../verifier/util/RegexpBuilders.groovy | 4 +- .../builder/ContractHttpDocsSpec.groovy | 44 ++++---- .../JaxRsClientMethodBuilderSpec.groovy | 104 +++++++++--------- .../MessagingMethodBodyBuilderSpec.groovy | 2 +- .../MockMvcMethodBodyBuilderSpec.groovy | 4 +- .../builder/SingleTestGeneratorSpec.groovy | 4 +- .../verifier/dsl/WireMockGroovyDslSpec.groovy | 70 ++++++------ .../verifier/dsl/WireMockStubVerifier.groovy | 4 +- .../dsl/internal/ExecutionPropertySpec.groovy | 2 +- .../dsl/internal/RegexPatternsSpec.groovy | 2 +- .../test/resources/dsl/basic/sampleDsl.groovy | 2 +- .../plugin/GenerateServerTestsTask.groovy | 2 +- ...ngCloudContractVerifierGradlePlugin.groovy | 2 +- .../pairId/collerate_PlacesFrom_Tweet.groovy | 2 +- .../pairId/moreComplexVersion.groovy | 2 +- .../repository/mappings/a_foo.groovy | 2 +- .../repository/mappings/bookDeleted.groovy | 2 +- .../repository/mappings/bookReturned1.groovy | 2 +- .../repository/mappings/bookReturned2.groovy | 2 +- .../shouldMarkClientAsFraud.groovy | 2 +- .../shouldMarkClientAsNotFraud.groovy | 2 +- .../shouldMarkClientAsFraud.groovy | 2 +- .../shouldMarkClientAsNotFraud.groovy | 2 +- .../1_shouldMarkClientAsNotFraud.groovy | 2 +- .../2_shouldMarkClientAsFraud.groovy | 2 +- 130 files changed, 470 insertions(+), 392 deletions(-) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/Contract.groovy (85%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/ContractVerifierException.groovy (94%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Body.groovy (96%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/ClientDslProperty.groovy (93%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Common.groovy (98%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/DslProperty.groovy (95%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/ExecutionProperty.groovy (95%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Header.groovy (95%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Headers.groovy (96%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Input.groovy (97%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/JSONCompareMode.groovy (92%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/MatchingStrategy.groovy (96%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Multipart.groovy (96%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/NamedProperty.groovy (95%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/OptionalProperty.groovy (94%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/OutputMessage.groovy (97%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/QueryParameter.groovy (90%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/QueryParameters.groovy (95%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/RegexPatterns.groovy (97%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Request.groovy (98%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Response.groovy (97%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/ServerDslProperty.groovy (94%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/Url.groovy (89%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/internal/UrlPath.groovy (94%) rename {spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier => spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec}/util/ValidateUtils.groovy (82%) create mode 100644 spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy create mode 100644 spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy diff --git a/docs/src/main/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc index a7216e3bd0..9a3ee50346 100644 --- a/docs/src/main/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -5,14 +5,16 @@ == Contract DSL IMPORTANT: Remember that inside the contract file you have to provide the fully qualified name to -the `Contract` class and the `make` static import i.e. `org.springframework.cloud.contract.verifier.dsl.Contract.make { ... }`. -You can also provide an import to the `Contract` class `import org.springframework.cloud.contract.verifier.dsl.Contract` and then call +the `Contract` class and the `make` static import i.e. `org.springframework.cloud.contract.spec.Contract.make { ... }`. +You can also provide an import to the `Contract` class `import org.springframework.cloud.contract.spec.Contract` and then call `Contract.make { ... }` Contract DSL is written in Groovy, but don't be alarmed if you didn't use Groovy before. Knowledge of the language is not really needed as our DSL uses only a tiny subset of it (namely literals, method calls and closures). What's more the DSL is designed to be programmer-readable without any knowledge of the DSL itself - it's statically typed. +The Contract is present in the `spring-cloud-contract-spec` module of the Spring Cloud Contract Verifier repository. + Let's look at full example of a contract definition. [source,groovy,indent=0] diff --git a/samples/samples-messaging-camel/build.gradle b/samples/samples-messaging-camel/build.gradle index 067b6cdeb2..bf8efc7f10 100644 --- a/samples/samples-messaging-camel/build.gradle +++ b/samples/samples-messaging-camel/build.gradle @@ -13,18 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - String verifier = "spring-cloud-contract-verifier" dependencies { diff --git a/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy b/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy index 38337f6b76..09f5a23df7 100644 --- a/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy +++ b/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy @@ -19,7 +19,7 @@ package org.springframework.cloud.contract.verifier.samples.camel import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.apache.camel.model.ModelCamelContext import org.springframework.beans.factory.annotation.Autowired diff --git a/samples/samples-messaging-integration/build.gradle b/samples/samples-messaging-integration/build.gradle index 990aa349b2..21eeaff00b 100644 --- a/samples/samples-messaging-integration/build.gradle +++ b/samples/samples-messaging-integration/build.gradle @@ -13,18 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} - String verifier = "spring-cloud-contract-verifier" dependencies { diff --git a/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy b/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy index 7307d4ea71..68eaf5009b 100644 --- a/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy +++ b/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy @@ -21,7 +21,7 @@ import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy index 7737cd4270..082cf2f2fc 100644 --- a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy +++ b/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy @@ -21,7 +21,7 @@ import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper diff --git a/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy b/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy index 2aa6c241a9..1a21561554 100644 --- a/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy +++ b/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy @@ -19,7 +19,7 @@ package org.springframework.cloud.contract.verifier.samples.messaging import com.jayway.jsonpath.DocumentContext import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.test.SpringApplicationContextLoader diff --git a/settings.gradle b/settings.gradle index c86dce469d..bb28620d0c 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,6 +5,8 @@ rootProject.name = "$verifier-parent" include "docs" +include ":spring-cloud-contract-spec" + include ":$verifier:$verifier-core", ":$verifier:$verifier-gradle-plugin", ":$verifier:$verifier-converters", diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/Contract.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/Contract.groovy similarity index 85% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/Contract.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/Contract.groovy index 57ccd03dea..7e424d019d 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/Contract.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/Contract.groovy @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl +package org.springframework.cloud.contract.spec import groovy.transform.EqualsAndHashCode import groovy.transform.ToString import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.internal.Input -import org.springframework.cloud.contract.verifier.dsl.internal.OutputMessage -import org.springframework.cloud.contract.verifier.dsl.internal.Request -import org.springframework.cloud.contract.verifier.dsl.internal.Response +import org.springframework.cloud.contract.spec.internal.Input +import org.springframework.cloud.contract.spec.internal.OutputMessage +import org.springframework.cloud.contract.spec.internal.Request +import org.springframework.cloud.contract.spec.internal.Response /** * The point of entry to the DSL diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/ContractVerifierException.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/ContractVerifierException.groovy similarity index 94% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/ContractVerifierException.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/ContractVerifierException.groovy index 6b1d5a9c79..2750320176 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/ContractVerifierException.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/ContractVerifierException.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier +package org.springframework.cloud.contract.spec import groovy.transform.CompileStatic diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Body.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy similarity index 96% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Body.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy index 07051bd494..38e42ad8ba 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Body.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ClientDslProperty.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ClientDslProperty.groovy similarity index 93% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ClientDslProperty.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ClientDslProperty.groovy index 4e0a7aad8e..e16afaffb5 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ClientDslProperty.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ClientDslProperty.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Common.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Common.groovy similarity index 98% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Common.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Common.groovy index f167521fa4..6cbf2a3a6f 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Common.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Common.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.PackageScope import groovy.transform.TypeChecked diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/DslProperty.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy similarity index 95% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/DslProperty.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy index b7bea9e3fb..4be6c853ae 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/DslProperty.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionProperty.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ExecutionProperty.groovy similarity index 95% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionProperty.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ExecutionProperty.groovy index 8948cccf0e..6f79e6dbcf 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionProperty.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ExecutionProperty.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Header.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Header.groovy similarity index 95% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Header.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Header.groovy index 3ab86a08b6..9989d875b4 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Header.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Header.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Headers.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Headers.groovy similarity index 96% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Headers.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Headers.groovy index 03af32fbe9..036a23598e 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Headers.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Headers.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.EqualsAndHashCode import groovy.transform.ToString diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Input.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Input.groovy similarity index 97% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Input.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Input.groovy index 34a16d1579..124b25ce50 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Input.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Input.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/JSONCompareMode.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/JSONCompareMode.groovy similarity index 92% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/JSONCompareMode.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/JSONCompareMode.groovy index 8fb8d92738..c1e3b21e7d 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/JSONCompareMode.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/JSONCompareMode.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal /** * Represents JSON comparison modes diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/MatchingStrategy.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/MatchingStrategy.groovy similarity index 96% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/MatchingStrategy.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/MatchingStrategy.groovy index f4d1ec0248..0b30b40f23 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/MatchingStrategy.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/MatchingStrategy.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Multipart.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Multipart.groovy similarity index 96% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Multipart.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Multipart.groovy index 554afad2ae..59efa9fe77 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Multipart.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Multipart.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/NamedProperty.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/NamedProperty.groovy similarity index 95% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/NamedProperty.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/NamedProperty.groovy index 6c1ca066c7..798ddcb0f2 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/NamedProperty.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/NamedProperty.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OptionalProperty.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy similarity index 94% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OptionalProperty.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy index d822cb043f..6ac232f29c 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OptionalProperty.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OutputMessage.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy similarity index 97% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OutputMessage.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy index 0435ac5a76..260bd68f5a 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/OutputMessage.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameter.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameter.groovy similarity index 90% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameter.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameter.groovy index 21e6aab67c..d34ea61383 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameter.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameter.groovy @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -import static org.springframework.cloud.contract.verifier.util.ValidateUtils.validateServerValueIsAvailable +import static org.springframework.cloud.contract.spec.util.ValidateUtils.validateServerValueIsAvailable /** * Represents a single HTTP query parameter diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameters.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameters.groovy similarity index 95% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameters.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameters.groovy index dd69ff707a..26cbec3730 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/QueryParameters.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameters.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.EqualsAndHashCode import groovy.transform.ToString diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatterns.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/RegexPatterns.groovy similarity index 97% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatterns.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/RegexPatterns.groovy index 4315e7965c..7177ecf7c0 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatterns.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/RegexPatterns.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Request.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy similarity index 98% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Request.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy index 8e189a9b60..724771d2f4 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Request.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Response.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy similarity index 97% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Response.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy index 44da4a5aa9..454841becd 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Response.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ServerDslProperty.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ServerDslProperty.groovy similarity index 94% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ServerDslProperty.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ServerDslProperty.groovy index 3f2cf0e59e..3cf7ec93cc 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ServerDslProperty.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ServerDslProperty.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Url.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy similarity index 89% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Url.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy index 8c5b3e8a0f..1abee32aa5 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/Url.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy @@ -14,13 +14,13 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode import groovy.transform.ToString -import static org.springframework.cloud.contract.verifier.util.ValidateUtils.validateServerValueIsAvailable +import static org.springframework.cloud.contract.spec.util.ValidateUtils.validateServerValueIsAvailable /** * Represents a URL that may contain query parameters diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/UrlPath.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/UrlPath.groovy similarity index 94% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/UrlPath.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/UrlPath.groovy index 62a8d8c60e..df4f277459 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/internal/UrlPath.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/UrlPath.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ValidateUtils.groovy b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/util/ValidateUtils.groovy similarity index 82% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ValidateUtils.groovy rename to spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/util/ValidateUtils.groovy index 98aebb1ca8..087ddb77f0 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ValidateUtils.groovy +++ b/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/util/ValidateUtils.groovy @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.util +package org.springframework.cloud.contract.spec.util import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty -import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy +import org.springframework.cloud.contract.spec.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.MatchingStrategy import java.util.regex.Pattern -import static org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy.Type.ABSENT -import static org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy.Type.EQUAL_TO +import static org.springframework.cloud.contract.spec.internal.MatchingStrategy.Type.ABSENT +import static org.springframework.cloud.contract.spec.internal.MatchingStrategy.Type.EQUAL_TO /** * Checks the validity of DSL entries. diff --git a/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy b/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy new file mode 100644 index 0000000000..65b3997d99 --- /dev/null +++ b/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.spec.internal + +import spock.lang.Specification + +class ExecutionPropertySpec extends Specification { + + def 'should insert passed value in place of $it placeholder'() { + given: + String commandToExecute = 'commandToExecute($it)' + ExecutionProperty executionProperty = new ExecutionProperty(commandToExecute) + and: + String valueToInsert = 'someObject.itsValue' + when: + String commandWithInsertedValue = executionProperty.insertValue(valueToInsert) + then: + 'commandToExecute(someObject.itsValue)' == commandWithInsertedValue + } + +} diff --git a/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy b/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy new file mode 100644 index 0000000000..80b9333bce --- /dev/null +++ b/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy @@ -0,0 +1,78 @@ +/* + * Copyright 2013-2016 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.contract.spec.internal + +import spock.lang.Specification + +import java.util.regex.Pattern + +class RegexPatternsSpec extends Specification { + + RegexPatterns regexPatterns = new RegexPatterns() + + def "should generate a regex for ip address [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.ipAddress()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + '123.123.123.123' || true + 'a.b.' || false + } + + def "should generate a regex for hostname [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.hostname()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + 'https://asd.com' || true + 'https://asd.com:8080' || true + 'https://localhost' || true + 'https://localhost:8080' || true + 'https://asd.com/asd' || false + 'asd.com' || false + } + + def "should generate a regex for email [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.email()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + 'asd@asd.com' || true + 'a.b.' || false + } + + def "should generate a regex for url [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.url()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + 'ftp://asd.com:9090/asd/a?a=b' || true + 'a.b.' || false + } + + def "should generate a regex for a number [#textToMatch] that is a match [#shouldMatch]"() { + expect: + shouldMatch == Pattern.compile(regexPatterns.number()).matcher(textToMatch).matches() + where: + textToMatch || shouldMatch + '1' || true + '1.0' || true + '0.1' || true + '.1' || true + '1.' || false + } +} diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar index 4f874c72510c8870ffaf12cd6305e57ac2535711..a84e468496c7d48104dde102f229a12e49cb1bec 100644 GIT binary patch delta 884 zcmeyv`-peKeLkDcyBNNT=kp`%!i*8hwlaA(h6<{Mwai4 z3=AwHKt-l~2e}Rz@Hm{m8$Ko0$dNs6@5+ivnjPOSuHD#|d)C9+CFOsf^}WiA(991d$dr)hk=)%o@NDF^#qd_$Hvb39PK z9I?A4KX~Wlm(3begBb#=7F{}#m-nZghwu99%Ho^i>Ji=?zjFLOe)_^1;LQwnKL>*= z(953}ooG1#^o_@4UM7?Ji$HIl!t`ouuPyf>1A(^ZU&2dvbKN?4(brYbCH9VsO78iv zTTf1@y1M*%ucleY(^PP}`u%a|m}SeJcI%zj5smA7ZIZu2`_h~(sWYR~ljog__c|%{ zxLQSOW}-0j;?+xu)g zANo8oJMvL`hf}1&Yy-_z3PJ`!TX_!|wEYvFCO^^s)f(sAUqu;`SIYc3zxZ{e)xW%| z|0ZX9bpN)?XAe!T{ncA*!-(*+DbUYL`m>}~0sZ_Dh}9Tm7>ZI0@{2P|@{1-}SQl`;{xUpex`>MWgCN(KokB4kCroDAWn9wq?CSV(-*@q% z?#MgG=Xmc6O#E{9!WB80dndnpMbGNFWa7eawM=5`t-7hraz8gGh-qz!k=P>fF--95 zqJ+B!eubVh4+|_fxYtu%-Ci~D-yhzY?R!+t-uP7Ib2(ctYY|K0_5F_+4=&)JdGeOd z5{?IM-APA}-ah%nQnsbRZeCPJkj@?Bme_k{n_|3*4fivEJUw|8o7BYp+?!)rxEaxt zcp0lBC~Z&P#VVtSk`#a`T!TRZ7&r_JKqf;&<2y!%$qvktlLgpBnSn_JtOGM3k#z_# cgLG)Jv4R6~@)R~JMybi?+0@zmSU|=C0EUun(*OVf delta 916 zcmaFF`-gYJeZJJh3m*OtRHOGZFfgz)PJC-zZ&#fZZVAMt72FJrEZ-R!7+6GrlBRtJ zyABx$IGleO-V(R0iEYn2Uvd9MO%>C(%uI8>-QyGFy5xV}rK^vh?A;@owE9r*-0ixr z8Rd`6&8m{>%{t+J%{Qbx<+@c$s?++q{p*|G1?=Ox_*$x(v!^hner@Nj*HT;$|K#?} z>^@O{E-J<3b~@|K`RSr(pK`Ba)!{M}Z8|oiPS$`W_xTQv7mr)DeyB$Zo6ZzrsyJzM zz3=6#pnoSescJo);xO%Bfb3cgpZuwKJiLCjy zbrF&_!rM1pxH5f{!s|%UxPMCKq0Ktp%b#A4HC=V|%PfwyMOQQpe$9JpsGe2dFF&E< zSlM3w^27_4p^v*xrU<0YuzAWlb$X8d8>f~xWj_+|NzjwlQeVqe+dy z%PwR^KOx5{-bzw5M|K824TPH5; z_|_IP-E>pwqqo0avt=06s-1G~v%AV?>$c~KORrzZ-Ll#_+q4$=a)j(i<$5N3>E`+P ziPbYMub4W^@B3r!(;?GclwIcjZ?a}-*D(%`O;6n7@WSSm>#FX1El%HQ#85+XLz`XWBarhD-F0J5Z zU}X8u$iToN0#s?*caZCl0guD^yWvw}jU3tI_O7g$WI5sP(&*&5x1~I-T~hw%S$~zd zciOwd_nq9GsNz)92a|W4o;}ZPu6c^>>SOFZzWe_BH@^zlCwy_WR5fQ$T}t)J&RwUa zgf78;ah*YytO84=wR+z?JC}bVA$;2LtC`U<37U#8Hd`KjeVIML zn;Gl{4u;7X$ZOg7(sOR`k!Lnf8CQp1mp(p|Wvy#Hr?!*i$L=e} z{Xbqb3!TZocroi(OkMi-bVYrETz>0X$?FP53U9L`pSm8|Iw6+3M&{GQdNmud%e<3Vv3+^H{)#$Z_1}NfHqFkTo_BZW{mcF8hydsW20*WMEuoxsg$Us)=DpdyXUiXh%9FJpBHA*7XXfuemFWJ`I#7&z zlcvNbkr!bGZk@}7&>h86j^^RW@mbFU$@gJ+!F3YAX zU-c^#OrE4ZTa_jz#d0@+GfY!w{!E)=&VrvFUP-uMPniR jI;AGZG7GQ)^#H>Xs7GY-Mm9A@)yX&5)Y&3gK(+t?CwFO( delta 907 zcmaFM+sZfLKJVJN3m$sLddChkFfedWd}C5CTAmcn2gIcn+zgB?-x(PgSVVwwrhOap z4jBkIq(9eQqa(f~sdMVu5T8&7r#B}$_1Aema!y|^>h!bxO~A3w)pg}Z!dj)R^R2Hb z{}cSaN;bo2m8yK?_Q1bNyU!_V3$uOwS|?lD|0%G;(cHo#p-1?)xAT>FvjC3g`N3ym z>RrmNDJ{NvSNp`DEh{q4SF?1Vjn3j=ucnuz^d(ScUq`PN)XQj z#nUl1OHO<5oSNz$a>}w%=kEfu6NxYX@Qc3bJO2Lb!_D^&x3?_Oe>P|PdH(=!X0Ts4 z7*+s%J?&5VmD50lvX_)2o2N5W777 zVysq%nBLu$8ci#t%f%;dnQNCbNptd-IK4;vZ!h@~!Eq?(+#K~F%^dHon%tA5{!NgY zsQIR7;=)1|WA(bmSBuz$c7`VX{E>Cjp{94nB+V5wgm?6vv2@Kj7c95&)|R>TpKUHD ztkp^MT_Id|u}nT*r<&2;G{atrl=NW6#{KJ0vhj>rOoM?*(W1Uc-UAnrV zKiRIv>67lK_PMWDmo;1N(2*!Vl6d?8Tjj4($FD1^3N3QffB(#TdVBA$$lBe^h~U@& z3=V-tk5IV<$8%>@y;^yR zFW6KvNkjGE3BI|@I?Ll3d~Y9Y|KDD3=KZ{6Qr(-VgC6sBnzNbC-!rvQJE*pk-Shr8 zm2=qz=lACwX*~7*5X&0PDGxLQ7WL1nY&i7gvB`4NAk&E<8yAN^%y=mGb%*%EU#I8Y zsK5DrO>gA&^FMo&IdzNKX1?D4sPn?)7spJu`$h!x1S?of*y0eec?9mx6TcLEfD_n@wuse(ueFEZmH!Nq=%0s}nOY?N46KDx-**JS2dj!oUDb zDGUvbzZe-N^D$|&u`)0NQwdlDW&k2>B)5)!DR*bfj53s4T6|#Vg F1po~-c^d!# diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle index 338123d564..714d543a31 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle @@ -13,17 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - -repositories { - mavenLocal() - jcenter() - maven { - url "http://repo.spring.io/snapshot" - } - maven { - url "http://repo.spring.io/milestone" - } -} String verifier = "spring-cloud-contract-verifier" String stubRunner = "spring-cloud-contract-stub-runner" diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy index 2d777d252e..70f082d629 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy @@ -17,7 +17,7 @@ package org.springframework.cloud.contract.stubrunner.messaging.integration import groovy.transform.CompileStatic -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.stubrunner.StubConfiguration import org.springframework.beans.factory.config.AutowireCapableBeanFactory import org.springframework.cloud.contract.stubrunner.BatchStubRunner diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy index e3a7a87e69..ff4413d5d5 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy @@ -21,7 +21,7 @@ import com.jayway.jsonpath.JsonPath import com.toomuchcoding.jsonassert.JsonAssertion import com.toomuchcoding.jsonassert.JsonVerifiable import groovy.transform.CompileStatic -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.messaging.ContractVerifierObjectMapper import org.springframework.cloud.contract.verifier.util.JsonPaths import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy index 6dd212e46a..0bf9278b01 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy @@ -16,7 +16,7 @@ package org.springframework.cloud.contract.stubrunner.messaging.integration -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.util.BodyExtractor import org.springframework.integration.transformer.GenericTransformer import org.springframework.messaging.Message diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy index 3f7a37f357..bdd7368377 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy @@ -22,7 +22,7 @@ import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMes import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.EnableAutoConfiguration import org.springframework.boot.test.SpringApplicationContextLoader -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.stubrunner.StubFinder import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import org.springframework.context.annotation.ComponentScan diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy index 010b849826..31b4d19ab4 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy @@ -1,6 +1,6 @@ package org.springframework.cloud.contract.stubrunner.messaging.integration -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.messaging.Message import org.springframework.messaging.support.MessageBuilder import spock.lang.Specification diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar index a9abc9528a591ccbf363db42ffd2d2fcd98cf77b..9cb1d97128317912625c1aa09877b4e7431e6119 100644 GIT binary patch delta 884 zcmeyv`-peKeZDnqcRiM>J-ff1fq~&a!(=`twaKekx#~F?n4df-4!;Y;r4`%^j4a<7 z85meZfQn4}4ssnb;Bh#AH+)L0kt2KD-jx-TG&{auT)VL^_pFDtOUnN|>$`?~rcW1` zeTVl>#OH*okGprAeck6a_j-!$>RaqRrFAjO;bK6 zc0~_&8nQ`#&3ri5@yYf`*V=f8ZB3y{%UmwJI2_h^PSf~!tMlvkQx5jK_=YTT=6Ild zIbwH9e(=u8FPk-{1~UX!ExL3fFYiw~58w6ImBly3)g!z)e&zUm{Pcx2z?&KDeh!8W zKreq@bfV<|&^I2Fd6`V=-vGV&6w|A%y|&zk3gw|6y_#knPgB9^>i5T;W0oy@+O2n9M>MYUwMqU8?MrjEq|S^^Po8%!-s_~) z<7ySDnTf*8i{D1fH(K<|q|GCyV>BJXf=LlJNVpo@uO)nbHomnZ|}41 zeCYGU?8ry$9Zr!7vkf#?DF_(^ZRI^=(DqMwn*2ojS8JSee-&j&UMchE{NmS=cUWIAJo=F5{A>XIICU`@V}8 zbw}PgKF51sVB(j%7p}<3+&lT*D|%MXB@-8Zt7Q^fZ`Dn0mixImK}>5)jKmg+k70se z7bV;^@GJD3d01eh`LE|NijKY~Q1D_Qt0wpUc^LS&LW_ukU}vcyIy#%#*it zmT)|9>rOg)^!CXoma;7kcJrb-f^_Z}x5VBv+Z5wfY`C8R;;ul%xPm;TjAQz`$W(05TaG8s9N8Om<+FoGid5$_z{*U>%qNiL66_ c8Kgs#jTIb_lc%s*F-lE7&!*1i#{x1I0Ld3|UH||9 delta 916 zcmaFF`-gYJeZFIH7d-qQs7CK+U|?WpocPwb-laS#+zyCKE4UdLS-vweFtCUKB~AMd zb{#Sha5(=myd`c~6WgA5zT*CinkuGmnVIH%yT>QUb;kl` z*?pq^TvUq5?R3_e^V3DoKILA;s>5X{+H`D2ovZ;%?(-cSFCMpQ{ZNk-Hk~QLRB_Vi zdf&@eLH|x{Qq_7o#bMgN0O=nHbD_1=y1G5h>6x=aGqP5Sz8yFHt z&%a#$B3CPeulmb2y{-)_rtj_axaF6fIZ1PJiR+Q~`+U3V`3@b5d3Lt?z4?)?C9>w* z)JDY=j3Wq(s8)Euy>V9*~Xwbk0vz+ zFT2cfS;S4%?EWN!E58}HN**?Rdf}J+sf0Z)+5hzae&O4FU$l3rP7SbY z5EMvCa!PXG*x4JsO06_?xkAgY_gh$5n%k}C-=Dc-)1|_@VXDpttP7L5{r7HW-8yk$ z$G5ha>86`XAHDtcnk~biR_&B?pWRhHTem$=TzdUN?v~Zg*`~F?mm_3HD%UgNOE=HQ zPpqDCdBxOOe%~K+pAMPsqUiYXFm zV0vL_X#B=FIgeEdm`->>i3F?xE&LeN7?3q6GXph90fSS3jg^5J7@|NuB9r^r)EG@B NZ)H~VW7KdJ-^yk8uhEPH#_#IlYP|L&HZNv_b>S2Wuxy>siclUWDM z3#Xgg`da0ms0!=lmze$M%Y3%03;(Ds3OD^GB=PsiwpE?GviLhQ-dg-T(fa(FM9P(; z>dhG^-gkHX`pABh&8%~Vu;XO@XjQA_XN1K0*477Xd)B={HZ*WDpJBs#pX85Hc79JC zm-#OWImhVoveip@_tMRLk|Nu0rq|ye4{>DmyN5QlY!Y7=v{S8FSq*b1$tRv-sR;lrg7amc=2qPlE>=>vpbf&-RdT|G2hMP<&!SvxW|>OW?hsu(EY?JRgc&ZCR%Q1*eS ziO$kROqVBHJ?S``c!s$wC^lc_yh=vBZdQcAsSfM9<8!?C1txyE zd*Opxx9+5)M{l2e zVkz6wU^g$SBS`0taZBtyvrREx#fJMCK)#&3pG|7we(udhEZmH!>3VV(s}nOYVNX8K zDx-js3V_L5gFylq7z_+RCPPEx2gb>BS(Sh(gBO%6z#1^a4OxRYGf;!niI$J0U$Y21Z1ZI-} delta 918 zcmaFKJCSd~ecs5p3mz{n?VWjyfq{W%;v19tsX3ne>-Cr6EqTkD*zW9`d$gT9(D9DAuDVfciZG{N&lzV4o7nfkAxoO-`UPr;;#pA zJgDU(!TYsN{H%1l81t_=i?Q3ur*(nhvTKaa7s{q}H`v9k`1R`bm2)dH zPN+y8h@N({!e{;TPwvxX12vb6q`ctY>d3eG`RhZ}{_+9d z%wX?uFr)xIZXeKf2<(Li5nFvu_zr4~&5COcV=iMPHR7z8bt!O-e=I_t23fX(Un zhqGfmN>6OuK1+?4MZNt=Sl7h2Uzxq5Hctw6`mjGd$m_QA!VT?rXWpFY_^M@YhC!@% z&|&sV8d@Teb;z*{^RMU!t^uyxSreTo?2Zm{iWXZ`SHj9K7NSF zajFWach{ef2$m3Fu*_RCgUx0OFkF63)?+rRF8~HZ24+zB_8sIpWWdvQ{%-J_Yh0Ju zKWHqPXTvGyq7uE?@|vFV%2N~e?!GJXMc~B$=jW#jTo0?t+qEl+XZ#p@EO^+EEu0TCj QjGmMCu&J}vvVhD70QLTT`2YX_ diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy index 978ca3e109..a39d74fbe6 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy @@ -17,7 +17,7 @@ package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /** * Manages lifecycle of multiple {@link StubRunner} instances. * @@ -84,7 +84,7 @@ class BatchStubRunner implements StubRunning { if (!triggered) { throw new IllegalArgumentException("No label with name [$labelName] for " + "dependency [$ivyNotation] was found. Here you have the list of dependencies " + - "and their labels [${ivyToLabels()}") + "and their labels [${ivyToLabels()}]") } return triggered } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy index 252a60510c..2f2ca4f0b0 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy @@ -18,7 +18,7 @@ package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /** * @author Marcin Grzejszczak diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy index c203c5659d..e66fbb3217 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy @@ -18,7 +18,7 @@ package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.transform.EqualsAndHashCode -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /** * @author Marcin Grzejszczak diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy index 368494fb04..d2ba01caa9 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy @@ -16,7 +16,7 @@ package org.springframework.cloud.contract.stubrunner -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract interface StubFinder extends StubTrigger { /** diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy index b82b1c1694..2f7f77c74a 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy @@ -19,7 +19,7 @@ package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter /** diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy index 388eafcbce..7b460ebce7 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy @@ -18,7 +18,7 @@ package org.springframework.cloud.contract.stubrunner import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy index f2734d618a..7e49ad4ee0 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy @@ -16,9 +16,10 @@ package org.springframework.cloud.contract.stubrunner +import groovy.json.JsonOutput import groovy.transform.CompileStatic import groovy.util.logging.Slf4j -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessage import org.springframework.cloud.contract.verifier.messaging.ContractVerifierMessaging import org.springframework.cloud.contract.verifier.messaging.noop.NoOpContractVerifierMessaging @@ -129,7 +130,7 @@ class StubRunnerExecutor implements StubFinder { return } ContractVerifierMessage message = contractVerifierMessaging.create( - BodyExtractor.extractClientValueFromBody(groovyDsl.outputMessage?.body?.clientValue), + new JsonOutput().toJson(BodyExtractor.extractClientValueFromBody(groovyDsl.outputMessage?.body?.clientValue)), groovyDsl.outputMessage?.headers?.asStubSideMap()) contractVerifierMessaging.send(message, groovyDsl.outputMessage.sentTo.clientValue) } diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy index 5889584035..5ef2d0968d 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy @@ -22,7 +22,7 @@ import com.github.tomakehurst.wiremock.core.WireMockConfiguration import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract @CompileStatic @Slf4j diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy index bd67b68b91..94fc426530 100644 --- a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy +++ b/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy @@ -1,4 +1,4 @@ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { // Human readable description description 'Sends an order message' // Label by means of which the output message can be triggered diff --git a/spring-cloud-contract-verifier/build.gradle b/spring-cloud-contract-verifier/build.gradle index 178c42a48e..7872495400 100644 --- a/spring-cloud-contract-verifier/build.gradle +++ b/spring-cloud-contract-verifier/build.gradle @@ -19,6 +19,7 @@ String verifier = "spring-cloud-contract-verifier" project(":$verifier-root:$verifier-core") { dependencies { + compile project(":spring-cloud-contract-spec") compile 'org.slf4j:slf4j-api:1.6.0' compile 'commons-io:commons-io:2.0' compile 'org.apache.commons:commons-lang3:3.3' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy index 205dd170e4..f6f9d5a6ee 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy @@ -17,7 +17,7 @@ package org.springframework.cloud.contract.verifier.wiremock import groovy.transform.CompileStatic -import org.springframework.cloud.contract.verifier.ContractVerifierException +import org.springframework.cloud.contract.spec.ContractVerifierException /** * Thrown when a a DSL can't be properly converted diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy index 289b1d6ed0..7cb8172674 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy @@ -17,7 +17,7 @@ package org.springframework.cloud.contract.verifier.wiremock import groovy.transform.CompileStatic -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.converter.SingleFileConverter import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy index 57a56c9c77..8cc1c372d4 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy @@ -21,14 +21,14 @@ import groovy.transform.CompileStatic import groovy.util.logging.Slf4j import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.converter.SingleFileConverter -import org.springframework.cloud.contract.verifier.file.ContractMetadata import org.springframework.cloud.contract.verifier.file.ContractFileScanner +import org.springframework.cloud.contract.verifier.file.ContractMetadata import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths - +import java.nio.file.StandardCopyOption /** * Recursively converts contracts into their stub representations * @@ -38,6 +38,8 @@ import java.nio.file.Paths @CompileStatic class RecursiveFilesConverter { + private static final String DEFAULT_CONTRACTS_FOLDER = "contracts" + private static final String DEFAULT_MAPPINGS_FOLDER = "mappings" private final SingleFileConverter singleFileConverter private final ContractVerifierConfigProperties properties @@ -49,6 +51,8 @@ class RecursiveFilesConverter { void processFiles() { ContractFileScanner scanner = new ContractFileScanner(properties.contractsDslDir, properties.excludedFiles as Set, [] as Set) ListMultimap contracts = scanner.findContracts() + log.debug("Found the following contracts $contracts") + createContractDirInOutputStubsFolder() contracts.asMap().entrySet().each { entry -> entry.value.each { ContractMetadata contract -> File sourceFile = contract.path.toFile() @@ -56,13 +60,15 @@ class RecursiveFilesConverter { if (!singleFileConverter.canHandleFileName(sourceFile.name)) { return } + Path targetContractDir = createAndReturnTargetDirectory(sourceFile, DEFAULT_CONTRACTS_FOLDER) + Files.copy(sourceFile.toPath(), new File(targetContractDir.toFile(), sourceFile.name).toPath(), StandardCopyOption.REPLACE_EXISTING) 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()) + Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile, DEFAULT_MAPPINGS_FOLDER) + File newJsonFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) + newJsonFile.setText(convertedContent, StandardCharsets.UTF_8.toString()) } catch (Exception e) { throw new ConversionContractVerifierException("Unable to make conversion of ${sourceFile.name}", e) } @@ -70,16 +76,24 @@ class RecursiveFilesConverter { } } - private Path createAndReturnTargetDirectory(File sourceFile) { + private boolean createContractDirInOutputStubsFolder() { + return contractDir().mkdirs() + } + + private File contractDir() { + return new File(properties.stubsOutputDir, DEFAULT_CONTRACTS_FOLDER) + } + + private Path createAndReturnTargetDirectory(File sourceFile, String defaultFolder) { Path relativePath = Paths.get(properties.contractsDslDir.toURI()).relativize(sourceFile.parentFile.toPath()) - Path absoluteTargetPath = properties.stubsOutputDir.toPath().resolve(relativePath) + Path absoluteTargetPath = new File(properties.stubsOutputDir, defaultFolder).toPath().resolve(relativePath) Files.createDirectories(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]") - return newGroovyFile + File newJsonFile = new File(absoluteTargetPath.toFile(), singleFileConverter.generateOutputFileNameForInput(sourceFile.name)) + log.info("Creating new json [$newJsonFile.path]") + return newJsonFile } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy index 7844605653..960797316c 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy @@ -22,7 +22,7 @@ import groovy.json.JsonParserType import groovy.json.JsonSlurper import groovy.transform.CompileDynamic import groovy.xml.XmlUtil -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import nl.flotsam.xeger.Xeger import java.nio.charset.StandardCharsets diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy index 9bd88e86c7..dbd37a54f3 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy @@ -34,7 +34,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl1.groovy") file.write(""" - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method('PUT') url \$(client(~/\\/[0-9]{2}/), server('/12')) @@ -59,7 +59,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl-delay.groovy") file.write(""" - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { } response { @@ -82,7 +82,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl2.groovy") file.write(""" - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'PUT' url '/api/12' @@ -188,7 +188,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl-mapinlist.groovy") file.write(""" - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath '/foos' @@ -222,7 +222,7 @@ class DslToWireMockClientConverterSpec extends Specification { and: File file = tmpFolder.newFile("dsl_from_docs.groovy") file.write(''' - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { priority 1 request { method 'POST' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy index 0e3de65413..6e58c029f2 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy @@ -30,7 +30,12 @@ import java.nio.file.Paths class RecursiveFilesConverterSpec extends Specification { private static - final Set EXPECTED_TARGET_FILES = [Paths.get("dslRoot.json"), Paths.get("dir1/dsl1.json"), Paths.get("dir1/dsl1b.json"), Paths.get("dir2/dsl2.json")] + final Set EXPECTED_TARGET_FILES = [ + Paths.get("contracts/dir1/dsl1.groovy"), Paths.get("contracts/dir1/dsl1b.groovy"), + Paths.get("contracts/dir2/dsl2.groovy"), Paths.get("contracts/dslRoot.groovy"), + Paths.get("mappings/dslRoot.json"), Paths.get("mappings/dir1/dsl1.json"), + Paths.get("mappings/dir1/dsl1b.json"), Paths.get("mappings/dir2/dsl2.json") + ] @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); @@ -79,7 +84,8 @@ class RecursiveFilesConverterSpec extends Specification { then: Collection createdFiles = FileUtils.listFiles(properties.stubsOutputDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, properties.stubsOutputDir) - [Paths.get("dslRoot.json"), Paths.get("dir2/dsl2.json")] as Set == relativizedCreatedFiles as Set + [ Paths.get("mappings/dslRoot.json"), Paths.get("mappings/dir2/dsl2.json") , + Paths.get("contracts/dslRoot.groovy"), Paths.get("contracts/dir2/dsl2.groovy")] as Set == relativizedCreatedFiles as Set and: createdFiles.each { it.text == "converted" } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy index f564abadb2..9b1e4c2367 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy @@ -18,7 +18,7 @@ package org.springframework.cloud.contract.verifier.wiremock import com.github.tomakehurst.wiremock.stubbing.StubMapping import org.springframework.cloud.contract.verifier.util.ContractVerifierDslConverter -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import spock.lang.Specification class WireMockToDslConverterSpec extends Specification { @@ -85,7 +85,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -139,7 +139,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -190,7 +190,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -244,7 +244,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -309,7 +309,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") == expectedGroovyDsl } @@ -347,7 +347,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") and: @@ -387,7 +387,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") and: @@ -428,7 +428,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") and: @@ -468,7 +468,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") and: @@ -508,7 +508,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") and: @@ -546,7 +546,7 @@ class WireMockToDslConverterSpec extends Specification { String groovyDsl = WireMockToDslConverter.fromWireMockStub(wireMockStub) then: Contract evaluatedGroovyDsl = ContractVerifierDslConverter.convert( - """org.springframework.cloud.contract.verifier.dsl.Contract.make { + """org.springframework.cloud.contract.spec.Contract.make { $groovyDsl }""") and: diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy index c2c151e460..2911d82295 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy @@ -1,4 +1,4 @@ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /* * Copyright 2013-2016 the original author or authors. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy index a4284fe016..c7ed09b07c 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy @@ -1,4 +1,4 @@ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /* * Copyright 2013-2016 the original author or authors. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy index d2675b3a90..221416f88a 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy @@ -1,4 +1,4 @@ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /* * Copyright 2013-2016 the original author or authors. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy index b23e11ed01..c724017ffd 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy @@ -1,4 +1,4 @@ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /* * Copyright 2013-2016 the original author or authors. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy index 3a8bed4ecc..daaf2950e8 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy @@ -1,4 +1,4 @@ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /* * Copyright 2013-2016 the original author or authors. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy index b23e11ed01..c724017ffd 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy @@ -1,4 +1,4 @@ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /* * Copyright 2013-2016 the original author or authors. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy index b23e11ed01..c724017ffd 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy @@ -1,4 +1,4 @@ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /* * Copyright 2013-2016 the original author or authors. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy index 47f3da17b1..5457f654a7 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy @@ -19,19 +19,17 @@ package org.springframework.cloud.contract.verifier import com.google.common.collect.ListMultimap import groovy.transform.PackageScope import org.apache.commons.lang3.StringUtils +import org.springframework.cloud.contract.spec.ContractVerifierException import org.springframework.cloud.contract.verifier.builder.SingleTestGenerator import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties -import org.springframework.cloud.contract.verifier.file.ContractMetadata import org.springframework.cloud.contract.verifier.file.ContractFileScanner +import org.springframework.cloud.contract.verifier.file.ContractMetadata import java.nio.charset.StandardCharsets import java.nio.file.Path import java.util.concurrent.atomic.AtomicInteger -import static org.springframework.cloud.contract.verifier.util.NamesUtil.afterLast -import static org.springframework.cloud.contract.verifier.util.NamesUtil.beforeLast -import static org.springframework.cloud.contract.verifier.util.NamesUtil.convertIllegalPackageChars -import static org.springframework.cloud.contract.verifier.util.NamesUtil.directoryToPackage +import static org.springframework.cloud.contract.verifier.util.NamesUtil.* /** * @author Jakub Kubrynski, codearte.io diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy index bf58dbef87..e43b17e1c6 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy @@ -19,11 +19,11 @@ package org.springframework.cloud.contract.verifier.builder import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.Input -import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.Input +import org.springframework.cloud.contract.spec.internal.NamedProperty +import org.springframework.cloud.contract.spec.internal.ExecutionProperty import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy index 8c3fc89258..153542ea8d 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy @@ -19,11 +19,11 @@ package org.springframework.cloud.contract.verifier.builder import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty -import org.springframework.cloud.contract.verifier.dsl.internal.Request -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.NamedProperty +import org.springframework.cloud.contract.spec.internal.Request +import org.springframework.cloud.contract.spec.internal.ExecutionProperty import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy index feb23dfd57..2e5a36af8b 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy @@ -18,11 +18,11 @@ package org.springframework.cloud.contract.verifier.builder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty -import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameters +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.QueryParameter +import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.internal.QueryParameters import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy index b45c7981f2..c639383e0e 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy @@ -18,11 +18,11 @@ package org.springframework.cloud.contract.verifier.builder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter -import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameters -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.QueryParameter +import org.springframework.cloud.contract.spec.internal.QueryParameters +import org.springframework.cloud.contract.spec.internal.ExecutionProperty import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy index 33229a001a..29e0b6d415 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy @@ -19,9 +19,9 @@ package org.springframework.cloud.contract.verifier.builder import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Input -import org.springframework.cloud.contract.verifier.dsl.internal.OutputMessage +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Input +import org.springframework.cloud.contract.spec.internal.OutputMessage import org.springframework.cloud.contract.verifier.util.ContentType import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromContent diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy index eb7b7fc1ea..c1c4ca440e 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy @@ -18,13 +18,13 @@ package org.springframework.cloud.contract.verifier.builder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.spec.internal.NamedProperty import org.springframework.cloud.contract.verifier.util.MapConverter -import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy -import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter +import org.springframework.cloud.contract.spec.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.MatchingStrategy +import org.springframework.cloud.contract.spec.internal.QueryParameter import org.springframework.cloud.contract.verifier.util.ContentType import org.springframework.cloud.contract.verifier.util.JsonPaths import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter @@ -329,7 +329,7 @@ abstract class MethodBodyBuilder { } /** - * Converts the {@link org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter} server side value into its String + * Converts the {@link org.springframework.cloud.contract.spec.internal.QueryParameter} server side value into its String * representation */ protected String resolveParamValue(QueryParameter param) { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy index 090f87273e..29176013d8 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy @@ -38,11 +38,11 @@ import org.springframework.cloud.contract.verifier.file.ContractMetadata class MethodBuilder { private final String methodName - private final org.springframework.cloud.contract.verifier.dsl.Contract stubContent + private final org.springframework.cloud.contract.spec.Contract stubContent private final ContractVerifierConfigProperties configProperties private final boolean ignored - private MethodBuilder(String methodName, org.springframework.cloud.contract.verifier.dsl.Contract stubContent, ContractVerifierConfigProperties configProperties, boolean ignored) { + private MethodBuilder(String methodName, org.springframework.cloud.contract.spec.Contract stubContent, ContractVerifierConfigProperties configProperties, boolean ignored) { this.ignored = ignored this.stubContent = stubContent this.methodName = methodName @@ -52,7 +52,7 @@ class MethodBuilder { /** * A factory method that creates a {@link MethodBuilder} for the given arguments */ - static MethodBuilder createTestMethod(ContractMetadata contract, File stubsFile, org.springframework.cloud.contract.verifier.dsl.Contract stubContent, ContractVerifierConfigProperties configProperties) { + static MethodBuilder createTestMethod(ContractMetadata contract, File stubsFile, org.springframework.cloud.contract.spec.Contract stubContent, ContractVerifierConfigProperties 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) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy index 406ad8a5f2..baf893c1b6 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy @@ -18,9 +18,9 @@ package org.springframework.cloud.contract.verifier.builder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.ExecutionProperty import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy index 742a49ab41..cc0c873546 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy @@ -18,9 +18,9 @@ package org.springframework.cloud.contract.verifier.builder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty -import org.springframework.cloud.contract.verifier.dsl.internal.Header +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.internal.Header import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy index ce3385a18d..c80a3e902f 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy @@ -20,14 +20,14 @@ import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Request -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy -import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty -import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameter -import org.springframework.cloud.contract.verifier.dsl.internal.Response -import org.springframework.cloud.contract.verifier.dsl.internal.Url +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Request +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.MatchingStrategy +import org.springframework.cloud.contract.spec.internal.NamedProperty +import org.springframework.cloud.contract.spec.internal.QueryParameter +import org.springframework.cloud.contract.spec.internal.Response +import org.springframework.cloud.contract.spec.internal.Url import org.springframework.cloud.contract.verifier.util.ContentType import org.springframework.cloud.contract.verifier.util.MapConverter diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy index 58e406b66a..dcfa2d4757 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy @@ -120,7 +120,7 @@ class SingleTestGenerator { return listOfFiles.collectEntries { File stubsFile = it.path.toFile() log.debug("Stub content from file [${stubsFile.text}]") - org.springframework.cloud.contract.verifier.dsl.Contract stubContent = ContractVerifierDslConverter.convert(stubsFile) + org.springframework.cloud.contract.spec.Contract stubContent = ContractVerifierDslConverter.convert(stubsFile) TestType testType = (stubContent.input || stubContent.outputMessage) ? TestType.MESSAGING : TestType.HTTP return [(new ParsedDsl(it, stubContent, stubsFile)): testType] } @@ -130,7 +130,7 @@ class SingleTestGenerator { @EqualsAndHashCode private static class ParsedDsl { ContractMetadata contract - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl + org.springframework.cloud.contract.spec.Contract groovyDsl File stubsFile } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy index 7996f413f7..701ae25501 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy @@ -19,11 +19,11 @@ package org.springframework.cloud.contract.verifier.builder import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.Input -import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.Input +import org.springframework.cloud.contract.spec.internal.NamedProperty import java.util.regex.Pattern /** diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy index cc60ff5055..dac23ae776 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy @@ -19,11 +19,11 @@ package org.springframework.cloud.contract.verifier.builder import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Header -import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty -import org.springframework.cloud.contract.verifier.dsl.internal.Request -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.spec.internal.NamedProperty +import org.springframework.cloud.contract.spec.internal.Request +import org.springframework.cloud.contract.spec.internal.ExecutionProperty import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy index 914c705bb6..1226c39bf1 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy @@ -19,9 +19,9 @@ package org.springframework.cloud.contract.verifier.dsl.wiremock import groovy.json.JsonBuilder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.internal.Headers +import org.springframework.cloud.contract.spec.internal.Headers import org.springframework.cloud.contract.verifier.util.MapConverter -import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.DslProperty import org.springframework.cloud.contract.verifier.util.ContentType import org.springframework.cloud.contract.verifier.util.ContentUtils diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy index 0fad82f131..68606b280c 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy @@ -23,19 +23,19 @@ import groovy.json.JsonOutput import groovy.transform.PackageScope import groovy.transform.TypeChecked import groovy.transform.TypeCheckingMode -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Body -import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty -import org.springframework.cloud.contract.verifier.dsl.internal.QueryParameters +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Body +import org.springframework.cloud.contract.spec.internal.NamedProperty +import org.springframework.cloud.contract.spec.internal.QueryParameters import org.springframework.cloud.contract.verifier.util.ContentUtils import org.springframework.cloud.contract.verifier.util.JsonPaths import org.springframework.cloud.contract.verifier.util.MapConverter -import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty -import org.springframework.cloud.contract.verifier.dsl.internal.OptionalProperty -import org.springframework.cloud.contract.verifier.dsl.internal.RegexPatterns -import org.springframework.cloud.contract.verifier.dsl.internal.Request +import org.springframework.cloud.contract.spec.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.OptionalProperty +import org.springframework.cloud.contract.spec.internal.RegexPatterns +import org.springframework.cloud.contract.spec.internal.Request import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter -import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy +import org.springframework.cloud.contract.spec.internal.MatchingStrategy import org.springframework.cloud.contract.verifier.util.ContentType import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy index 96eda8c33b..e1c6ecf4d2 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy @@ -22,9 +22,9 @@ import com.github.tomakehurst.wiremock.http.HttpHeaders import com.github.tomakehurst.wiremock.http.ResponseDefinition import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.verifier.dsl.Contract -import org.springframework.cloud.contract.verifier.dsl.internal.Request -import org.springframework.cloud.contract.verifier.dsl.internal.Response +import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.Request +import org.springframework.cloud.contract.spec.internal.Response import org.springframework.cloud.contract.verifier.util.ContentType import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromContent diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy index e40850cbe4..41c1ed1615 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy @@ -39,7 +39,7 @@ class WireMockStubStrategy { private final ContractMetadata contract private final String rootName - WireMockStubStrategy(String rootName, ContractMetadata contract, org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl) { + WireMockStubStrategy(String rootName, ContractMetadata contract, org.springframework.cloud.contract.spec.Contract groovyDsl) { this.rootName = rootName this.contract = contract this.wireMockRequestStubStrategy = new WireMockRequestStubStrategy(groovyDsl) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy index c5f4b4279a..9e69876737 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy @@ -19,7 +19,7 @@ package org.springframework.cloud.contract.verifier.util import groovy.json.JsonOutput import groovy.json.StringEscapeUtils import groovy.transform.CompileStatic -import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.DslProperty import static ContentUtils.extractValue /** diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy index c2168f564d..366c03f5d8 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy @@ -20,13 +20,13 @@ import groovy.json.JsonOutput import groovy.json.JsonSlurper import groovy.transform.TypeChecked import groovy.util.logging.Slf4j -import org.springframework.cloud.contract.verifier.dsl.internal.Headers +import org.springframework.cloud.contract.spec.internal.Headers import org.codehaus.groovy.runtime.GStringImpl -import org.springframework.cloud.contract.verifier.dsl.internal.NamedProperty -import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty -import org.springframework.cloud.contract.verifier.dsl.internal.MatchingStrategy -import org.springframework.cloud.contract.verifier.dsl.internal.OptionalProperty +import org.springframework.cloud.contract.spec.internal.NamedProperty +import org.springframework.cloud.contract.spec.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.internal.MatchingStrategy +import org.springframework.cloud.contract.spec.internal.OptionalProperty import java.util.regex.Matcher import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy index 31c29365f3..9cd8eb5956 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy @@ -18,7 +18,7 @@ package org.springframework.cloud.contract.verifier.util import groovy.transform.CompileStatic import org.codehaus.groovy.control.CompilerConfiguration -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /** * Converts a file or String into a {@link Contract} diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy index f4c35bb866..625fbc415d 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy @@ -19,8 +19,8 @@ package org.springframework.cloud.contract.verifier.util import com.toomuchcoding.jsonassert.JsonAssertion import groovy.json.JsonOutput import groovy.json.JsonSlurper -import org.springframework.cloud.contract.verifier.dsl.internal.OptionalProperty -import org.springframework.cloud.contract.verifier.dsl.internal.ExecutionProperty +import org.springframework.cloud.contract.spec.internal.OptionalProperty +import org.springframework.cloud.contract.spec.internal.ExecutionProperty import java.util.regex.Pattern diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy index ed83f76a3d..31c5aa1899 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy @@ -17,7 +17,7 @@ package org.springframework.cloud.contract.verifier.util import groovy.json.JsonSlurper -import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.DslProperty /** * Converts an object into either client or server side representation. @@ -35,7 +35,7 @@ class MapConverter { public static final boolean TEST_SIDE = false /** - * Returns the object with client side values of {@link org.springframework.cloud.contract.verifier.dsl.internal.DslProperty} + * Returns the object with client side values of {@link org.springframework.cloud.contract.spec.internal.DslProperty} */ static def transformToClientValues(def value) { return transformValues(value) { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy index cb284679a5..df267cfd87 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy @@ -18,7 +18,7 @@ package org.springframework.cloud.contract.verifier.util import groovy.transform.TypeChecked import org.codehaus.groovy.runtime.GStringImpl -import org.springframework.cloud.contract.verifier.dsl.internal.DslProperty +import org.springframework.cloud.contract.spec.internal.DslProperty import java.util.regex.Pattern @@ -53,7 +53,7 @@ class RegexpBuilders { } /** - * Converts the {@link org.springframework.cloud.contract.verifier.dsl.internal.DslProperty} passed values into their stub side String representations + * Converts the {@link org.springframework.cloud.contract.spec.internal.DslProperty} passed values into their stub side String representations */ static String buildGStringRegexpForStubSide(DslProperty dslProperty) { return buildGStringRegexpForStubSide(dslProperty.clientValue) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy index 27b417a9e7..c2a34bd06f 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy @@ -25,9 +25,9 @@ import spock.lang.Specification */ class ContractHttpDocsSpec extends Specification { - org.springframework.cloud.contract.verifier.dsl.Contract httpDsl = + org.springframework.cloud.contract.spec.Contract httpDsl = // tag::http_dsl[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { // Definition of HTTP request part of the contract // (this can be a valid request or invalid depending // on type of contract being specified). @@ -49,9 +49,9 @@ class ContractHttpDocsSpec extends Specification { } // end::http_dsl[] - org.springframework.cloud.contract.verifier.dsl.Contract request = + org.springframework.cloud.contract.spec.Contract request = // tag::request[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { // HTTP request method (GET/POST/PUT/DELETE). method 'GET' @@ -66,9 +66,9 @@ class ContractHttpDocsSpec extends Specification { } // end::request[] - org.springframework.cloud.contract.verifier.dsl.Contract url = + org.springframework.cloud.contract.spec.Contract url = // tag::url[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' @@ -82,9 +82,9 @@ class ContractHttpDocsSpec extends Specification { } // end::url[] - org.springframework.cloud.contract.verifier.dsl.Contract urlPaths = + org.springframework.cloud.contract.spec.Contract urlPaths = // tag::urlpath[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { //... @@ -127,9 +127,9 @@ class ContractHttpDocsSpec extends Specification { } // end::urlpath[] - org.springframework.cloud.contract.verifier.dsl.Contract headers = + org.springframework.cloud.contract.spec.Contract headers = // tag::headers[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { //... @@ -147,9 +147,9 @@ class ContractHttpDocsSpec extends Specification { } // end::headers[] - org.springframework.cloud.contract.verifier.dsl.Contract body = + org.springframework.cloud.contract.spec.Contract body = // tag::body[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { //... @@ -164,9 +164,9 @@ class ContractHttpDocsSpec extends Specification { } // end::body[] - org.springframework.cloud.contract.verifier.dsl.Contract bodyAsXml = + org.springframework.cloud.contract.spec.Contract bodyAsXml = // tag::bodyAsXml[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { //... @@ -182,9 +182,9 @@ class ContractHttpDocsSpec extends Specification { } // end::bodyAsXml[] - org.springframework.cloud.contract.verifier.dsl.Contract response = + org.springframework.cloud.contract.spec.Contract response = // tag::response[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { //... } @@ -196,9 +196,9 @@ class ContractHttpDocsSpec extends Specification { } // end::response[] - org.springframework.cloud.contract.verifier.dsl.Contract regex = + org.springframework.cloud.contract.spec.Contract regex = // tag::regex[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -227,9 +227,9 @@ class ContractHttpDocsSpec extends Specification { } // end::regex[] - org.springframework.cloud.contract.verifier.dsl.Contract optionals = + org.springframework.cloud.contract.spec.Contract optionals = // tag::optionals[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { priority 1 request { method 'POST' @@ -282,9 +282,9 @@ class ContractHttpDocsSpec extends Specification { stripped(blockBuilder.toString()) == stripped(expectedTest) } - org.springframework.cloud.contract.verifier.dsl.Contract method = + org.springframework.cloud.contract.spec.Contract method = // tag::method[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'PUT' url $(client(regex('^/api/[0-9]{2}$')), server('/api/12')) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy index cf419bd745..105bcbce66 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy @@ -26,7 +26,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub def "should generate assertions for simple response body with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -50,14 +50,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#187") def "should generate assertions for null and boolean values with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -83,14 +83,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub()) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#79") def "should generate assertions for simple response body constructed from map with a list with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -119,14 +119,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub()) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } @Issue("#82") def "should generate proper request when body constructed from map with a list with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -148,14 +148,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('{\"items\":[\"HOP\"]}', 'application/json')""" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("{\\"items\\":[\\"HOP\\"]}", "application/json")' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('{\"items\":[\"HOP\"]}', 'application/json')""" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("{\\"items\\":[\\"HOP\\"]}", "application/json")' } @Issue("#88") def "should generate proper request when body constructed from GString with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -177,13 +177,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('property1=VAL1', 'application/octet-stream')""" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"property1=VAL1\\"", "application/octet-stream")' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('property1=VAL1', 'application/octet-stream')""" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"property1=VAL1\\"", "application/octet-stream")' } def "should generate assertions for array in response body with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -210,13 +210,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for array inside response body element with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -242,13 +242,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should generate assertions for nested objects in response body with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -274,13 +274,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should generate regex assertions for map objects in response body with #methodBodyName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -312,13 +312,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should generate regex assertions for string objects in response body with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -344,13 +344,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } } def "should ignore 'Accept' header and use 'request' method with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -372,13 +372,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | requestString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "request('text/plain')" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "request('text/plain')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")' } def "should ignore 'Content-Type' header and use 'entity' method with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "GET" url "test" @@ -405,13 +405,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | requestStrings - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ["""entity('', 'text/plain')""", """header('Timer', '123')"""] - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")'] + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ["""entity('', 'text/plain')""", """header('Timer', '123')"""] + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")'] } def "should generate a call with an url path and query parameters with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath('/users') { @@ -459,14 +459,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | modifyStringIfRequired - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } } @Issue('#169') def "should generate a call with an url path and query parameters with url containing a pattern with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url($(stub(regex('/foo/[0-9]+')), test('/foo/123456'))) { @@ -514,13 +514,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | modifyStringIfRequired - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } } def "should generate test for empty body with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('POST') url("/ws/payments") @@ -542,13 +542,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "entity('', 'application/octet-stream')" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"\\"", "application/octet-stream"' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "entity('', 'application/octet-stream')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"\\"", "application/octet-stream"' } def "should generate test for String in response body with #methodBodyName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "POST" url "test" @@ -570,14 +570,14 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "String responseAsString = response.readEntity(String)" | 'responseBody == "test"' - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (responseAsString);' | 'assertThat(responseBody).isEqualTo("test");' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "String responseAsString = response.readEntity(String)" | 'responseBody == "test"' + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (responseAsString);' | 'assertThat(responseBody).isEqualTo("test");' } @Issue('#171') def "should generate test with uppercase method name with #methodBuilderName"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "get" url "/v1/some_cool_requests/e86df6f693de4b35ae648464c5b0dc08" @@ -603,13 +603,13 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | methodString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ".method('GET')" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.verifier.dsl.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ".method('GET')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")' } def "should generate a call with an url path and query parameters with JUnit - we'll put it into docs"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath('/users') { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy index 98e02596de..b23add6810 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy @@ -16,7 +16,7 @@ package org.springframework.cloud.contract.verifier.builder -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import spock.lang.Specification /** * @author Marcin Grzejszczak diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy index 42a9c7db8c..9918f7055a 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -16,7 +16,7 @@ package org.springframework.cloud.contract.verifier.builder -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Shared @@ -1398,7 +1398,7 @@ World.'''""" Contract dslForDocs = // tag::dsl_example[] - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'PUT' url '/api/12' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy index d4b3bb3485..8bb9f1591f 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy @@ -46,7 +46,7 @@ class SingleTestGeneratorSpec extends Specification { def setup() { file = tmpFolder.newFile() file.write(""" - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'PUT' url 'url' @@ -105,7 +105,7 @@ class SingleTestGeneratorSpec extends Specification { given: File secondFile = tmpFolder.newFile() secondFile.write(""" - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { label 'some_label' input { messageFrom('delete') diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy index 458e94ab9e..92c0f26a49 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy @@ -28,7 +28,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub to wireMock stub for the client side'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -77,7 +77,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue("#79") def 'should convert groovy dsl stub to wireMock stub for the client side with a body containing a map'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url '/ingredients' @@ -124,7 +124,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue("#86") def 'should convert groovy dsl stub with GString and regexp'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('POST') url('/ws/payments') @@ -176,7 +176,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with Body as String to wireMock stub for the client side'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -221,7 +221,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with simple Body as String to wireMock stub for the client side'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('GET') url $(client(regex('/[0-9]{2}')), server('/12')) @@ -271,7 +271,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToJson when body match is defined as map'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -321,7 +321,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToJson when content type ends with json'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url "/users" @@ -366,7 +366,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToXml when content type ends with xml'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url "/users" @@ -411,7 +411,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToXml when content type is parsable xml'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url "/users" @@ -448,7 +448,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should support xml as a response body'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url "/users" @@ -481,7 +481,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToJson'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url "/users" @@ -516,7 +516,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use equalToXml'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url "/users" @@ -553,7 +553,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with regexp Body as String to wireMock stub for the client side'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('GET') url $(client(regex('/[0-9]{2}')), server('/12')) @@ -603,7 +603,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with a regexp and an integer in request body'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'PUT' url '/fraudcheck' @@ -665,7 +665,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate request with urlPath and queryParameters for client side"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath($(client("users"), server("items"))) { @@ -733,7 +733,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate request with urlPathPattern and queryParameters for client side\ when both contains regular expressions"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath($(client(regex("/users/[0-9]+")), server("/users/1"))) { @@ -772,7 +772,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate request with urlPath for client side"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath $(client("boxes"), server("items")) @@ -801,7 +801,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate simple request with urlPath for client side"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath "boxes" @@ -830,7 +830,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should not allow regexp in url for server value"() { when: - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url(regex(/users\/[0-9]*/)) { @@ -851,7 +851,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should not allow regexp in query parameter for server value"() { when: - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url("abc") { @@ -871,7 +871,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should not allow query parameter unresolvable for a server value"() { when: - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath("users") { @@ -892,7 +892,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should not allow query parameter with a different absent variation for server/client"() { when: - org.springframework.cloud.contract.verifier.dsl.Contract.make dsl + org.springframework.cloud.contract.spec.Contract.make dsl then: def e = thrown(IllegalStateException) e.message.contains "Absent cannot only be used only on one side" @@ -942,7 +942,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate request with url and queryParameters for client side"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url($(client(regex(/users\/[0-9]*/)), server("users/123"))) { @@ -984,7 +984,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should convert groovy dsl stub with rich tree Body as String to wireMock stub for the client side'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('GET') url $(client(~/\/[0-9]{2}/), server('/12')) @@ -1055,7 +1055,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should use regexp matches when request body match is defined using a map with a pattern'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'POST' url '/reissue-payment-order' @@ -1115,7 +1115,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate stub for empty body"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('POST') url("test") @@ -1148,7 +1148,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def "should generate stub with priority"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { priority 9 request { method('POST') @@ -1178,7 +1178,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue("#127") def 'should use "test" as an alias for "server"'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('POST') body( @@ -1212,7 +1212,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue("#121") def 'should generate stub with empty list as a value of a field'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method('POST') body( @@ -1247,7 +1247,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should generate stub properly resolving GString with regular expression'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { priority 1 request { method 'POST' @@ -1306,7 +1306,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie def 'should generate stub properly resolving GString with regular expression in url'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'PUT' @@ -1383,7 +1383,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie stubMappingIsValidWireMockStub(wireMockStub) where: contractDsl << [ - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { priority 1 request { method 'POST' @@ -1407,7 +1407,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie ) } }, - org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract.make { priority 1 request { method 'POST' @@ -1455,7 +1455,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue('180') def 'should generate stub with multipart parameters'() { given: - org.springframework.cloud.contract.verifier.dsl.Contract contractDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { request { method "PUT" url "/multipart" @@ -1500,7 +1500,7 @@ class WireMockGroovyDslSpec extends Specification implements WireMockStubVerifie @Issue('#219') def "should generate request with an optional queryParameter for client side"() { given: - org.springframework.cloud.contract.verifier.dsl.Contract groovyDsl = org.springframework.cloud.contract.verifier.dsl.Contract.make { + org.springframework.cloud.contract.spec.Contract groovyDsl = org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' urlPath ('/some/api') { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy index f0d7a9d50a..825b913136 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy @@ -29,10 +29,10 @@ trait WireMockStubVerifier { stubMapping.request.bodyPatterns.findAll { it.matches }.every { Pattern.compile(it.matches) } - assert !mappingDefinition.contains('org.springframework.cloud.contract.verifier.dsl.internal') + assert !mappingDefinition.contains('org.springframework.cloud.contract.spec.internal') } - void stubMappingIsValidWireMockStub(org.springframework.cloud.contract.verifier.dsl.Contract contractDsl) { + void stubMappingIsValidWireMockStub(org.springframework.cloud.contract.spec.Contract contractDsl) { stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub()) } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy index 4d3144371e..65b3997d99 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import spock.lang.Specification diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy index 4f3b7cdcde..80b9333bce 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.springframework.cloud.contract.verifier.dsl.internal +package org.springframework.cloud.contract.spec.internal import spock.lang.Specification diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy index 38f5869fc5..a24fc9fb0a 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy @@ -1,4 +1,4 @@ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract /* * Copyright 2013-2016 the original author or authors. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy index 71935b4d5f..ce5301b3fd 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy @@ -21,7 +21,7 @@ import org.gradle.api.internal.ConventionTask import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputDirectory import org.gradle.api.tasks.TaskAction -import org.springframework.cloud.contract.verifier.ContractVerifierException +import org.springframework.cloud.contract.spec.ContractVerifierException import org.springframework.cloud.contract.verifier.TestGenerator import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy index e699653491..ff6d2a06f5 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy @@ -107,7 +107,7 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { task.group = GROUP_NAME task.conventionMapping.with { contractsDslDir = { extension.contractsDslDir } - stubsOutputDir = { extension.stubsOutputDir } + stubsOutputDir = { extension.stubsOutputDir ?: project.file("${project.buildDir}/stubs") } configProperties = { extension } } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy index 2f01af1c93..ab1d853b3e 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { priority 2 diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy index c98b51279d..887e54edf7 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { request { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy index 202c8808fe..476aa94eb3 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { request { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy index 4c73b42e4d..4f7ca765f5 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { label 'some_label' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy index 3d4ba32c3a..302e1d11f2 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { label 'some_label' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy index 91ae4361ef..c5a9919e99 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { label 'some_label' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy index 2634bca6cc..1fc39340b5 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { request { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy index 249de5bc5f..94026415f3 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { request { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy index 91246ddfee..a2e6875fd9 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { request { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy index 5a2f1a1312..76df090cd6 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { request { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy index 5a2f1a1312..76df090cd6 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { request { diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy index 2634bca6cc..1fc39340b5 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy @@ -14,7 +14,7 @@ * limitations under the License. */ -import org.springframework.cloud.contract.verifier.dsl.Contract +import org.springframework.cloud.contract.spec.Contract Contract.make { request { From 5f04ebdbd89ec5a2c7972f8943795a6e44ff5c34 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Jun 2016 19:02:51 +0200 Subject: [PATCH 707/719] Updated the plugin according to new Contract naming --- .../cloud/contract/verifier/maven/GenerateTestsMojo.java | 2 +- .../basic/src/test/resources/contracts/Messaging.groovy | 2 +- .../projects/basic/src/test/resources/contracts/Sample.groovy | 2 +- .../src/test/contracts/brokenContract.groovy | 2 +- .../src/test/contracts/shouldMarkClientAsFraud.groovy | 2 +- .../src/test/contracts/shouldMarkClientAsNotFraud.groovy | 2 +- .../generatedStubs/target/stubs/contracts/Sample.groovy | 2 +- .../src/test/resources/contracts/greetings_ok.groovy | 2 +- .../resources/contracts/greetings_with_default_value.groovy | 2 +- .../src/test/projects/pomless/Sample.groovy | 2 +- .../src/test/resources/contracts/greetings_ok.groovy | 2 +- .../resources/contracts/greetings_with_default_value.groovy | 2 +- .../src/test/resources/contracts/greetings_ok.groovy | 2 +- .../resources/contracts/greetings_with_default_value.groovy | 2 +- .../projects/withStubs/src/test/resources/stubs/Sample.groovy | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java b/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java index d3a051961d..ddd78f7c2d 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java +++ b/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java @@ -27,7 +27,7 @@ import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; import org.apache.maven.project.MavenProject; -import org.springframework.cloud.contract.verifier.ContractVerifierException; +import org.springframework.cloud.contract.spec.ContractVerifierException; import org.springframework.cloud.contract.verifier.TestGenerator; import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties; import org.springframework.cloud.contract.verifier.config.TestFramework; diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy index 60ff2c083a..b21f448049 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { label 'some_label' input { messageFrom('jms:input') diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy index 8b10943730..094820225b 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { request { method 'POST' url('/users') { diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy index 22b6f23bc6..48435cb1a2 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { request { method 'PUT' url '/fraudcheck' diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy index 315fc317f9..9cd6dec8b1 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { request { method """PUT""" url """/fraudcheck""" diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy index a85b6b2737..92b2646567 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { request { method 'PUT' url '/fraudcheck' diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy index b716f77dec..fb8ef5908e 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy @@ -1,4 +1,4 @@ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { request { method 'POST' url('/users') { diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy index 4fecfabb2e..4a5d9a792f 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { priority 2 request { method 'GET' diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy index f2412db397..5b65b65ca7 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { priority 2 request { method 'GET' diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy index 8b10943730..094820225b 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { request { method 'POST' url('/users') { diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy index e96a275e8f..e782af7b50 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { priority 2 request { method 'GET' diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy index 41ae428a8e..ad5e45965c 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { priority 2 request { method 'GET' diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy index 4fecfabb2e..4a5d9a792f 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { priority 2 request { method 'GET' diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy index f2412db397..5b65b65ca7 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { priority 2 request { method 'GET' diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy index 8b10943730..094820225b 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy +++ b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -org.springframework.cloud.contract.verifier.dsl.Contract.make { +org.springframework.cloud.contract.spec.Contract.make { request { method 'POST' url('/users') { From 2f3887753e5a86881a4a888f8bfc48c7c44a5d07 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Jun 2016 19:18:11 +0200 Subject: [PATCH 708/719] Fixed funcTest --- spring-cloud-contract-verifier/build.gradle | 10 ---------- .../functionalTest/bootSimple/build.gradle | 20 +++---------------- 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/spring-cloud-contract-verifier/build.gradle b/spring-cloud-contract-verifier/build.gradle index 7872495400..b83dd96ee3 100644 --- a/spring-cloud-contract-verifier/build.gradle +++ b/spring-cloud-contract-verifier/build.gradle @@ -87,16 +87,8 @@ project(":$verifier-root:$verifier-gradle-plugin") { } test { - exclude '**/*FunctionalSpec.*' systemProperties = testSystemProperties } - task funcTest(type: Test) { - include '**/*FunctionalSpec.*' - systemProperties = testSystemProperties - reports.html { - destination = file("${reporting.baseDir}/funcTests") - } - } task archiveMessagingLibsDependencies(type: Sync) { from configurations.messagingLibs.resolvedConfiguration.resolvedArtifacts.collect { it.file } @@ -113,7 +105,5 @@ project(":$verifier-root:$verifier-gradle-plugin") { archiveContractVerifierGradlePluginLibsDependencies.dependsOn project(":$verifier-root:$verifier-gradle-plugin").tasks.jar test.dependsOn archiveMessagingLibsDependencies, archiveContractVerifierGradlePluginLibsDependencies - funcTest.dependsOn archiveMessagingLibsDependencies, archiveContractVerifierGradlePluginLibsDependencies - uploadArchives.dependsOn { funcTest } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 1acee5de97..3e1383337b 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -12,9 +12,7 @@ group = 'org.springframework.cloud.testprojects' ext { contractsDir = file("repository/mappings") - stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) - contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/contracts/')) + stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/repository/") } configurations { @@ -54,29 +52,17 @@ contractVerifier { basePackageForTests = 'contracts' contractsDslDir = contractsDir // generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/") - stubsOutputDir = wireMockStubsOutputDir + stubsOutputDir = stubsOutputDirRoot targetFramework = 'Spock' } -//TODO: Put it into the plugin -task createWireMockStubsOutputDir << { - wireMockStubsOutputDir.mkdirs() -} - -generateWireMockClientStubs.dependsOn { createWireMockStubsOutputDir } generateContractTests.dependsOn generateWireMockClientStubs wrapper { gradleVersion '2.2.1' } -task copyContracts(type: Copy) { - from contractsDir - include '**/*.groovy' - into contractsOutputDir -} - -task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { +task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs"]) { baseName = "${project.name}" classifier = "stubs" from stubsOutputDirRoot From 24e7b9bf42a27c35e30269d10af5bb82ab98c8aa Mon Sep 17 00:00:00 2001 From: Mariusz Smykula Date: Wed, 29 Jun 2016 21:16:04 +0200 Subject: [PATCH 709/719] fixed site url and accurest names --- spring-cloud-contract-verifier-maven-plugin/pom.xml | 2 +- .../src/site/site.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spring-cloud-contract-verifier-maven-plugin/pom.xml b/spring-cloud-contract-verifier-maven-plugin/pom.xml index 17d3dfe4d6..ae2ee8a46b 100644 --- a/spring-cloud-contract-verifier-maven-plugin/pom.xml +++ b/spring-cloud-contract-verifier-maven-plugin/pom.xml @@ -41,7 +41,7 @@ github - scm:git:ssh://git@github.com:Codearte/accurest-maven-plugin.git + scm:git:git@github.com:Codearte/accurest-maven-plugin.git diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/site.xml b/spring-cloud-contract-verifier-maven-plugin/src/site/site.xml index 8d23c5f4d2..f2b1e347e5 100644 --- a/spring-cloud-contract-verifier-maven-plugin/src/site/site.xml +++ b/spring-cloud-contract-verifier-maven-plugin/src/site/site.xml @@ -16,7 +16,7 @@ limitations under the License. --> - + ${project.name} @@ -46,8 +46,8 @@ - - + + From 52a12824a26c462fa14683d2f98b0560fd31a54a Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Jun 2016 23:25:05 +0200 Subject: [PATCH 710/719] Added bash for docs publishing --- publishDocs.sh | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 publishDocs.sh diff --git a/publishDocs.sh b/publishDocs.sh new file mode 100644 index 0000000000..1e9bc2032e --- /dev/null +++ b/publishDocs.sh @@ -0,0 +1,2 @@ +#!/bin/sh +mvn clean site site:stage scm-publish:publish-scm -DskipTests -pl spring-cloud-contract-verifier-maven-plugin \ No newline at end of file From 8540e75cfd49a414306dbaf9ae7f425b26fb28e3 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 29 Jun 2016 23:27:30 +0200 Subject: [PATCH 711/719] Added missing tasks Added default Gradle tasks --- docs/src/main/asciidoc/README.adoc | 2 + docs/src/main/asciidoc/links.adoc | 11 +++ .../spring-cloud-contract-verifier.adoc | 4 +- .../wiremock/RecursiveFilesConverter.groovy | 29 +++--- .../RecursiveFilesConverterSpec.groovy | 10 +- .../ContractVerifierConfigProperties.groovy | 5 + ...erateWireMockClientStubsFromDslTask.groovy | 5 +- ...ngCloudContractVerifierGradlePlugin.groovy | 91 ++++++++++++++++++- .../functionalTest/bootSimple/build.gradle | 19 ---- .../messagingProject/build.gradle | 35 +------ .../sampleJerseyProject/build.gradle | 31 +------ .../functionalTest/sampleProject/build.gradle | 31 +------ .../scenarioProject/build.gradle | 27 ++---- 13 files changed, 141 insertions(+), 159 deletions(-) create mode 100644 docs/src/main/asciidoc/links.adoc diff --git a/docs/src/main/asciidoc/README.adoc b/docs/src/main/asciidoc/README.adoc index 1a31f6af8e..cc85698563 100644 --- a/docs/src/main/asciidoc/README.adoc +++ b/docs/src/main/asciidoc/README.adoc @@ -8,6 +8,8 @@ include::introduction.adoc[] +include::links.adoc[] + == Documentation You can read more about Spring Cloud Contract Verifier by reading the {documentation_url}[docs] diff --git a/docs/src/main/asciidoc/links.adoc b/docs/src/main/asciidoc/links.adoc new file mode 100644 index 0000000000..e8e1df762b --- /dev/null +++ b/docs/src/main/asciidoc/links.adoc @@ -0,0 +1,11 @@ +== Links + +Here you can find interesting links related to Spring Cloud Contract Verifier: + +- https://github.com/Codearte/accurest[Spring Cloud Contract Verifier Github Repository] +- http://codearte.github.io/accurest[Spring Cloud Contract Verifier Documentation] +- http://codearte.github.io/accurest/deprecated[Accurest Legacy Documentation] +- https://codearte.github.io/accurest/#spring-cloud-contract-stub-runner[Spring Cloud Contract Stub Runner Documentation] +- http://codearte.github.io/accurest/#stub-runner-for-messaging[Spring Cloud Contract Stub Runner Messaging Documentation] +- https://gitter.im/Codearte/accurest[Spring Cloud Contract Verifier Gitter] +- https://github.com/Codearte/accurest-maven-plugin[Spring Cloud Contract Verifier Maven Plugin] diff --git a/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc b/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc index 859cd12fc2..96cc64d927 100644 --- a/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc +++ b/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc @@ -17,4 +17,6 @@ include::messaging.adoc[] include::stubrunner.adoc[] -include::stubrunner_msg.adoc[] \ No newline at end of file +include::stubrunner_msg.adoc[] + +include::links.adoc[] \ No newline at end of file diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy index 8cc1c372d4..a8a9db6688 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy @@ -28,7 +28,6 @@ import java.nio.charset.StandardCharsets import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths -import java.nio.file.StandardCopyOption /** * Recursively converts contracts into their stub representations * @@ -38,21 +37,26 @@ import java.nio.file.StandardCopyOption @CompileStatic class RecursiveFilesConverter { - private static final String DEFAULT_CONTRACTS_FOLDER = "contracts" - private static final String DEFAULT_MAPPINGS_FOLDER = "mappings" private final SingleFileConverter singleFileConverter private final ContractVerifierConfigProperties properties + private final String additionalFolder RecursiveFilesConverter(SingleFileConverter singleFileConverter, ContractVerifierConfigProperties properties) { this.properties = properties this.singleFileConverter = singleFileConverter + this.additionalFolder = "" + } + + RecursiveFilesConverter(SingleFileConverter singleFileConverter, ContractVerifierConfigProperties properties, String additionalFolder) { + this.properties = properties + this.singleFileConverter = singleFileConverter + this.additionalFolder = additionalFolder } void processFiles() { ContractFileScanner scanner = new ContractFileScanner(properties.contractsDslDir, properties.excludedFiles as Set, [] as Set) ListMultimap contracts = scanner.findContracts() log.debug("Found the following contracts $contracts") - createContractDirInOutputStubsFolder() contracts.asMap().entrySet().each { entry -> entry.value.each { ContractMetadata contract -> File sourceFile = contract.path.toFile() @@ -60,13 +64,11 @@ class RecursiveFilesConverter { if (!singleFileConverter.canHandleFileName(sourceFile.name)) { return } - Path targetContractDir = createAndReturnTargetDirectory(sourceFile, DEFAULT_CONTRACTS_FOLDER) - Files.copy(sourceFile.toPath(), new File(targetContractDir.toFile(), sourceFile.name).toPath(), StandardCopyOption.REPLACE_EXISTING) String convertedContent = singleFileConverter.convertContent(entry.key.last().toString(), contract) if (!convertedContent) { return } - Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile, DEFAULT_MAPPINGS_FOLDER) + Path absoluteTargetPath = createAndReturnTargetDirectory(sourceFile) File newJsonFile = createTargetFileWithProperName(absoluteTargetPath, sourceFile) newJsonFile.setText(convertedContent, StandardCharsets.UTF_8.toString()) } catch (Exception e) { @@ -76,17 +78,10 @@ class RecursiveFilesConverter { } } - private boolean createContractDirInOutputStubsFolder() { - return contractDir().mkdirs() - } - - private File contractDir() { - return new File(properties.stubsOutputDir, DEFAULT_CONTRACTS_FOLDER) - } - - private Path createAndReturnTargetDirectory(File sourceFile, String defaultFolder) { + private Path createAndReturnTargetDirectory(File sourceFile) { Path relativePath = Paths.get(properties.contractsDslDir.toURI()).relativize(sourceFile.parentFile.toPath()) - Path absoluteTargetPath = new File(properties.stubsOutputDir, defaultFolder).toPath().resolve(relativePath) + File rootFile = additionalFolder ? new File(properties.stubsOutputDir, additionalFolder) : properties.stubsOutputDir + Path absoluteTargetPath = rootFile.toPath().resolve(relativePath) Files.createDirectories(absoluteTargetPath) return absoluteTargetPath } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy index 6e58c029f2..0e3de65413 100755 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy @@ -30,12 +30,7 @@ import java.nio.file.Paths class RecursiveFilesConverterSpec extends Specification { private static - final Set EXPECTED_TARGET_FILES = [ - Paths.get("contracts/dir1/dsl1.groovy"), Paths.get("contracts/dir1/dsl1b.groovy"), - Paths.get("contracts/dir2/dsl2.groovy"), Paths.get("contracts/dslRoot.groovy"), - Paths.get("mappings/dslRoot.json"), Paths.get("mappings/dir1/dsl1.json"), - Paths.get("mappings/dir1/dsl1b.json"), Paths.get("mappings/dir2/dsl2.json") - ] + final Set EXPECTED_TARGET_FILES = [Paths.get("dslRoot.json"), Paths.get("dir1/dsl1.json"), Paths.get("dir1/dsl1b.json"), Paths.get("dir2/dsl2.json")] @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); @@ -84,8 +79,7 @@ class RecursiveFilesConverterSpec extends Specification { then: Collection createdFiles = FileUtils.listFiles(properties.stubsOutputDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE) Set relativizedCreatedFiles = getRelativePathsForFilesInDirectory(createdFiles, properties.stubsOutputDir) - [ Paths.get("mappings/dslRoot.json"), Paths.get("mappings/dir2/dsl2.json") , - Paths.get("contracts/dslRoot.groovy"), Paths.get("contracts/dir2/dsl2.groovy")] as Set == relativizedCreatedFiles as Set + [Paths.get("dslRoot.json"), Paths.get("dir2/dsl2.json")] as Set == relativizedCreatedFiles as Set and: createdFiles.each { it.text == "converted" } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy index 58b81803a4..2e38d50db6 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy @@ -91,4 +91,9 @@ class ContractVerifierConfigProperties { */ File stubsOutputDir + /** + * Suffix for the generated Stubs Jar task + */ + String stubsSuffix = 'stubs' + } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy index e8f565eb46..6b960510e7 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy @@ -32,6 +32,8 @@ import org.springframework.cloud.contract.verifier.wiremock.RecursiveFilesConver */ class GenerateWireMockClientStubsFromDslTask extends ConventionTask { + private static final String DEFAULT_MAPPINGS_FOLDER = 'mappings' + @InputDirectory File contractsDslDir @OutputDirectory @@ -43,7 +45,8 @@ class GenerateWireMockClientStubsFromDslTask extends ConventionTask { void generate() { logger.info("Spring Cloud Contract Verifier Plugin: Invoking DSL to WireMock client stubs conversion") logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") - RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), getConfigProperties()) + RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), + getConfigProperties(), DEFAULT_MAPPINGS_FOLDER) converter.processFiles() } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy index ff6d2a06f5..1d176070cc 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy @@ -19,8 +19,11 @@ package org.springframework.cloud.contract.verifier.plugin import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.publish.maven.plugins.MavenPublishPlugin +import org.gradle.api.tasks.Copy +import org.gradle.jvm.tasks.Jar import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties - /** * Gradle plugin for Spring Cloud Contract Verifier that from the DSL contract can *
    @@ -44,6 +47,8 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { private static final String GENERATE_SERVER_TESTS_TASK_NAME = 'generateContractTests' private static final String DSL_TO_WIREMOCK_CLIENT_TASK_NAME = 'generateWireMockClientStubs' + private static final String COPY_CONTRACTS_TASK_NAME = 'copyContracts' + private static final String VERIFIER_STUBS_JAR_TASK_NAME = 'verifierStubsJar' private static final Class IDEA_PLUGIN_CLASS = org.gradle.plugins.ide.idea.IdeaPlugin private static final String GROUP_NAME = "Verification" @@ -61,6 +66,9 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { setConfigurationDefaults(extension) createGenerateTestsTask(extension) createAndConfigureGenerateWireMockClientStubsFromDslTask(extension) + Task stubsJar = createAndConfigureStubsJarTasks(extension) + createAndConfigureCopyContractsTask(stubsJar, extension) + createAndConfigureMavenPublishPlugin(stubsJar, extension) project.dependencies.add("testCompile", "com.github.tomakehurst:wiremock:2.0.10-beta") project.dependencies.add("testCompile", "com.toomuchcoding.jsonassert:jsonassert:0.4.7") project.dependencies.add("testCompile", "org.assertj:assertj-core:2.3.0") @@ -111,4 +119,85 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { configProperties = { extension } } } + + private Task createAndConfigureStubsJarTasks(ContractVerifierConfigProperties extension) { + Task task = stubsTask() + if (task) { + project.logger.warn("Stubs jar task was present - won't create one. Remember about adding it to artifacts as an archive!") + return task + } else { + task = project.tasks.create(type: Jar, name: VERIFIER_STUBS_JAR_TASK_NAME, + dependsOn: DSL_TO_WIREMOCK_CLIENT_TASK_NAME) { + baseName = project.name + classifier = extension.stubsSuffix + from { extension.stubsOutputDir } + } + task.description = "Creates the stubs JAR task" + task.group = GROUP_NAME + + project.artifacts { + archives task + } + return task + } + } + + private Task stubsTask() { + try { + return project.tasks.getByName(VERIFIER_STUBS_JAR_TASK_NAME) + } catch (Exception e) { + return null + } + } + + private Task createAndConfigureCopyContractsTask(Task stubs, ContractVerifierConfigProperties extension) { + Task task = project.tasks.create(type: Copy, name: COPY_CONTRACTS_TASK_NAME) { + from { extension.contractsDslDir } + into { project.file("${extension.stubsOutputDir}/contracts") ?: project.file("${project.buildDir}/stubs/contracts") } + } + task.description = "Copies contracts to the output folder" + task.group = GROUP_NAME + stubs.dependsOn task + return task + } + + private void createAndConfigureMavenPublishPlugin(Task stubsTask, ContractVerifierConfigProperties extension) { + if (!classIsOnClasspath("org.gradle.api.publish.maven.plugins.MavenPublishPlugin")) { + return + } + project.logger.debug("Generating default publication") + project.afterEvaluate { + project.plugins.withType(MavenPublishPlugin) { def publishingPlugin -> + def publishingExtension = project.extensions.findByName('publishing') + if (!hasPublication(publishingExtension)) { + project.logger.debug("Stubs publication is not present - will create one") + publishingExtension.publications { + stubs(MavenPublication) { + artifactId "${project.name}-${extension.stubsSuffix}" + artifact stubsTask + } + } + } else { + project.logger.warn("Stubs publication was present - won't create a new one. Remember about passing stubs as artifact") + } + } + } + } + + private boolean hasPublication(def publishingExtension) { + try { + return publishingExtension.publications.getByName('stubs') + } catch (Exception e) { + return false + } + } + + private boolean classIsOnClasspath(String className) { + try { + Class.forName(className) + return true + } catch (Exception e) { + project.logger.debug("Maven Publish Plugin is not available") + } + } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle index 3e1383337b..1f0e725251 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle @@ -62,25 +62,6 @@ wrapper { gradleVersion '2.2.1' } -task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs"]) { - baseName = "${project.name}" - classifier = "stubs" - from stubsOutputDirRoot -} - -artifacts { - archives stubsJar -} - -publishing { - publications { - stubs(MavenPublication) { - artifactId "${project.name}-stubs" - artifact stubsJar - } - } -} - test { testLogging { exceptionFormat = 'full' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle index 2f5a549e19..222f9b241c 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle @@ -14,8 +14,6 @@ group = 'org.springframework.cloud.testprojects' ext { contractsDir = file("repository/mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = new File(stubsOutputDirRoot, 'repository/mappings/') - contractsOutputDir = new File(stubsOutputDirRoot, 'repository/contracts/') targetFramework = 'Spock' } @@ -66,46 +64,15 @@ contractVerifier { targetFramework = 'Spock' contractsDslDir = contractsDir // generatedTestSourcesDir = file("${project.rootDir}/src/test/groovy/") - stubsOutputDir = wireMockStubsOutputDir + stubsOutputDir = stubsOutputDirRoot } -//TODO: Put it into the plugin -task createWireMockStubsOutputDir << { - wireMockStubsOutputDir.mkdirs() -} - -generateWireMockClientStubs.dependsOn { createWireMockStubsOutputDir } generateContractTests.dependsOn generateWireMockClientStubs wrapper { gradleVersion '2.12' } -task copyContracts(type: Copy) { - from contractsDir - include '**/*.groovy' - into contractsOutputDir -} - -task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}" - classifier = "stubs" - from stubsOutputDirRoot -} - -artifacts { - archives stubsJar -} - -publishing { - publications { - stubs(MavenPublication) { - artifactId "${project.name}-stubs" - artifact stubsJar - } - } -} - test { testLogging { exceptionFormat = 'full' diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle index 5b67157601..9375d437c5 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle @@ -58,8 +58,6 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') ext { contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) - contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/contracts/')) } contractVerifier { @@ -68,7 +66,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') baseClassForTests = 'org.springframework.cloud.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") - stubsOutputDir = wireMockStubsOutputDir + stubsOutputDir = stubsOutputDirRoot } jar { @@ -96,31 +94,6 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') clean.dependsOn('cleanup') - task copyContracts(type: Copy) { - from contractsDir - include '**/*.groovy' - into contractsOutputDir - } - - task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}" - classifier = "stubs" - from stubsOutputDirRoot - } - - artifacts { - archives stubsJar - } - - publishing { - publications { - stubs(MavenPublication) { - artifactId "${project.name}-stubs" - artifact stubsJar - } - } - } - test { testLogging { exceptionFormat = 'full' @@ -137,7 +110,7 @@ configure(project(':loanApplicationService')) { task copyCollaboratorStubs(type: Copy) { File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/repository/")) + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) into "src/test/resources/" } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle index b388ed0da6..eb108f14e3 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle @@ -58,8 +58,6 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') ext { contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) - contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/contracts/')) } contractVerifier { @@ -68,7 +66,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') baseClassForTests = 'org.springframework.cloud.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") - stubsOutputDir = wireMockStubsOutputDir + stubsOutputDir = stubsOutputDirRoot } jar { @@ -94,31 +92,6 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') clean.dependsOn('cleanup') - task copyContracts(type: Copy) { - from contractsDir - into contractsOutputDir - includeEmptyDirs = true - } - - task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}" - classifier = "stubs" - from stubsOutputDirRoot - } - - artifacts { - archives stubsJar - } - - publishing { - publications { - stubs(MavenPublication) { - artifactId "${project.name}-stubs" - artifact stubsJar - } - } - } - test { testLogging { exceptionFormat = 'full' @@ -134,7 +107,7 @@ configure(project(':loanApplicationService')) { task copyCollaboratorStubs(type: Copy) { File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/repository/")) + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) into "src/test/resources/" } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle index 75060f4740..67fa4ba4b8 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle @@ -59,31 +59,18 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') ext { contractsDir = file("mappings") stubsOutputDirRoot = file("${project.buildDir}/production/${project.name}-stubs/") - wireMockStubsOutputDir = file(new File(stubsOutputDirRoot, 'repository/mappings/')) - contractsOutputDir = file(new File(stubsOutputDirRoot, 'repository/contracts/')) } - task copyContracts(type: Copy) { - from contractsDir - include '**/*.groovy' - into contractsOutputDir - } - - task stubsJar(type: Jar, dependsOn: ["generateWireMockClientStubs", copyContracts]) { - baseName = "${project.name}" - classifier = "stubs" - from stubsOutputDirRoot - } - - artifacts { - archives stubsJar - } + // Automatically added by plugin: + // copyContracts - copies contracts to the output folder from which JAR will be created + // verifierStubsJar - JAR with a provided stub suffix + // the presented publication is also added by the plugin but you can modify it as you wish publishing { publications { stubs(MavenPublication) { artifactId "${project.name}-stubs" - artifact stubsJar + artifact verifierStubsJar } } } @@ -97,7 +84,7 @@ configure([project(':fraudDetectionService'), project(':loanApplicationService') baseClassForTests = 'org.springframework.cloud.MvcSpec' contractsDslDir = file("${project.projectDir.absolutePath}/mappings/") generatedTestSourcesDir = file("${project.buildDir}/generated-test-sources/") - stubsOutputDir = wireMockStubsOutputDir + stubsOutputDir = stubsOutputDirRoot } jar { @@ -138,7 +125,7 @@ configure(project(':loanApplicationService')) { task copyCollaboratorStubs(type: Copy) { File fraudBuildDir = project(':fraudDetectionService').buildDir - from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/repository/")) + from(new File(fraudBuildDir, "/production/${project(':fraudDetectionService').name}-stubs/")) into "src/test/resources/" } From 24fc9e13514c2ccd5ea59ee631c89a38f3fd8eac Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 30 Jun 2016 00:30:17 +0200 Subject: [PATCH 712/719] Fixed wrong gradle plugin setup --- .../wiremock/RecursiveFilesConverter.groovy | 11 +++++------ ...erateWireMockClientStubsFromDslTask.groovy | 6 ++++-- ...ngCloudContractVerifierGradlePlugin.groovy | 19 +++++++++++-------- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy index a8a9db6688..56ddd3f99e 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy @@ -39,18 +39,18 @@ class RecursiveFilesConverter { private final SingleFileConverter singleFileConverter private final ContractVerifierConfigProperties properties - private final String additionalFolder + private final File outMappingsDir RecursiveFilesConverter(SingleFileConverter singleFileConverter, ContractVerifierConfigProperties properties) { this.properties = properties this.singleFileConverter = singleFileConverter - this.additionalFolder = "" + this.outMappingsDir = properties.stubsOutputDir } - RecursiveFilesConverter(SingleFileConverter singleFileConverter, ContractVerifierConfigProperties properties, String additionalFolder) { + RecursiveFilesConverter(SingleFileConverter singleFileConverter, ContractVerifierConfigProperties properties, File outMappingsDir) { this.properties = properties this.singleFileConverter = singleFileConverter - this.additionalFolder = additionalFolder + this.outMappingsDir = outMappingsDir } void processFiles() { @@ -80,8 +80,7 @@ class RecursiveFilesConverter { private Path createAndReturnTargetDirectory(File sourceFile) { Path relativePath = Paths.get(properties.contractsDslDir.toURI()).relativize(sourceFile.parentFile.toPath()) - File rootFile = additionalFolder ? new File(properties.stubsOutputDir, additionalFolder) : properties.stubsOutputDir - Path absoluteTargetPath = rootFile.toPath().resolve(relativePath) + Path absoluteTargetPath = outMappingsDir.toPath().resolve(relativePath) Files.createDirectories(absoluteTargetPath) return absoluteTargetPath } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy index 6b960510e7..e87a0422cd 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy @@ -23,7 +23,6 @@ import org.gradle.api.tasks.TaskAction import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter import org.springframework.cloud.contract.verifier.wiremock.RecursiveFilesConverter - //TODO: Implement as an incremental task: https://gradle.org/docs/current/userguide/custom_tasks.html#incremental_tasks ? /** * Generates WireMock stubs from the contracts @@ -45,8 +44,11 @@ class GenerateWireMockClientStubsFromDslTask extends ConventionTask { void generate() { logger.info("Spring Cloud Contract Verifier Plugin: Invoking DSL to WireMock client stubs conversion") logger.debug("From '${getContractsDslDir()}' to '${getStubsOutputDir()}'") + ContractVerifierConfigProperties props = getConfigProperties() + File outMappingsDir = props.stubsOutputDir != null ? new File(props.stubsOutputDir, DEFAULT_MAPPINGS_FOLDER) + : new File(project.buildDir, "stubs/$DEFAULT_MAPPINGS_FOLDER") RecursiveFilesConverter converter = new RecursiveFilesConverter(new DslToWireMockClientConverter(), - getConfigProperties(), DEFAULT_MAPPINGS_FOLDER) + getConfigProperties(), outMappingsDir) converter.processFiles() } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy index 1d176070cc..2ee94f97da 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy @@ -91,6 +91,7 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { generatedTestSourcesDir = project.file("${project.buildDir}/generated-test-sources/contracts") contractsDslDir = defaultContractsDir() //TODO: Use sourceset basePackageForTests = 'org.springframework.cloud.contract.verifier.tests' + stubsOutputDir = stubsOutputDir ?: project.file("${project.buildDir}/stubs") } } @@ -115,7 +116,7 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { task.group = GROUP_NAME task.conventionMapping.with { contractsDslDir = { extension.contractsDslDir } - stubsOutputDir = { extension.stubsOutputDir ?: project.file("${project.buildDir}/stubs") } + stubsOutputDir = { extension.stubsOutputDir } configProperties = { extension } } } @@ -123,14 +124,14 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { private Task createAndConfigureStubsJarTasks(ContractVerifierConfigProperties extension) { Task task = stubsTask() if (task) { - project.logger.warn("Stubs jar task was present - won't create one. Remember about adding it to artifacts as an archive!") + project.logger.info("Spring Cloud Contract Verifier Plugin: Stubs jar task was present - won't create one. Remember about adding it to artifacts as an archive!") return task } else { task = project.tasks.create(type: Jar, name: VERIFIER_STUBS_JAR_TASK_NAME, dependsOn: DSL_TO_WIREMOCK_CLIENT_TASK_NAME) { baseName = project.name classifier = extension.stubsSuffix - from { extension.stubsOutputDir } + from { extension.stubsOutputDir ?: project.file("${project.buildDir}/stubs") } } task.description = "Creates the stubs JAR task" task.group = GROUP_NAME @@ -153,7 +154,8 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { private Task createAndConfigureCopyContractsTask(Task stubs, ContractVerifierConfigProperties extension) { Task task = project.tasks.create(type: Copy, name: COPY_CONTRACTS_TASK_NAME) { from { extension.contractsDslDir } - into { project.file("${extension.stubsOutputDir}/contracts") ?: project.file("${project.buildDir}/stubs/contracts") } + into { extension.stubsOutputDir != null ? + project.file("${extension.stubsOutputDir}/contracts") : project.file("${project.buildDir}/stubs/contracts") } } task.description = "Copies contracts to the output folder" task.group = GROUP_NAME @@ -163,22 +165,23 @@ class SpringCloudContractVerifierGradlePlugin implements Plugin { private void createAndConfigureMavenPublishPlugin(Task stubsTask, ContractVerifierConfigProperties extension) { if (!classIsOnClasspath("org.gradle.api.publish.maven.plugins.MavenPublishPlugin")) { + project.logger.debug("Maven Publish Plugin is not present - won't add default publication") return } - project.logger.debug("Generating default publication") + project.logger.debug("Spring Cloud Contract Verifier Plugin: Generating default publication") project.afterEvaluate { project.plugins.withType(MavenPublishPlugin) { def publishingPlugin -> def publishingExtension = project.extensions.findByName('publishing') if (!hasPublication(publishingExtension)) { - project.logger.debug("Stubs publication is not present - will create one") + project.logger.debug("Spring Cloud Contract Verifier Plugin: Stubs publication is not present - will create one") publishingExtension.publications { stubs(MavenPublication) { - artifactId "${project.name}-${extension.stubsSuffix}" + artifactId "${project.name}" artifact stubsTask } } } else { - project.logger.warn("Stubs publication was present - won't create a new one. Remember about passing stubs as artifact") + project.logger.info("Spring Cloud Contract Verifier Plugin: Stubs publication was present - won't create a new one. Remember about passing stubs as artifact") } } } From 647e5f028e4a23c74dd1654c6597c90c11ad34cc Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Thu, 30 Jun 2016 00:40:57 +0200 Subject: [PATCH 713/719] Updated the docs --- .travis.yml | 2 +- README.adoc | 12 +++++++ docs/src/main/asciidoc/rest.adoc | 44 +++++++++++++++++++++++++- docs/src/main/asciidoc/stubrunner.adoc | 13 ++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index b63ed069cf..7a80f5443e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,4 +9,4 @@ jdk: - oraclejdk8 install: ./gradlew assemble -s -script: ./gradlew check funcTest install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh +script: ./gradlew check install -s --continue && jdk_switcher use oraclejdk8 && ./scripts/runTests.sh diff --git a/README.adoc b/README.adoc index 2796a76e7f..9bd94b36f0 100644 --- a/README.adoc +++ b/README.adoc @@ -157,6 +157,18 @@ Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Cont - Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory - Spring Cloud integration - no discovery service is needed for integration tests +== Links + +Here you can find interesting links related to Spring Cloud Contract Verifier: + +- https://github.com/Codearte/accurest[Spring Cloud Contract Verifier Github Repository] +- http://codearte.github.io/accurest[Spring Cloud Contract Verifier Documentation] +- http://codearte.github.io/accurest/deprecated[Accurest Legacy Documentation] +- https://codearte.github.io/accurest/#spring-cloud-contract-stub-runner[Spring Cloud Contract Stub Runner Documentation] +- http://codearte.github.io/accurest/#stub-runner-for-messaging[Spring Cloud Contract Stub Runner Messaging Documentation] +- https://gitter.im/Codearte/accurest[Spring Cloud Contract Verifier Gitter] +- https://github.com/Codearte/accurest-maven-plugin[Spring Cloud Contract Verifier Maven Plugin] + == Documentation You can read more about Spring Cloud Contract Verifier by reading the {documentation_url}[docs] diff --git a/docs/src/main/asciidoc/rest.adoc b/docs/src/main/asciidoc/rest.adoc index 6bf3c847dd..843d396ec6 100644 --- a/docs/src/main/asciidoc/rest.adoc +++ b/docs/src/main/asciidoc/rest.adoc @@ -42,7 +42,7 @@ Add the additional snapshot repository to your build.gradle to use snapshot vers repositories { (...) //Required only for SNAPSHOT versions - maven { url "https://oss.sonatype.org/content/repositories/snapshots" } + maven { url "https://repo.spring.io/plugins-snapshot-local" } } ---- @@ -91,6 +91,48 @@ Spring Cloud Contract Verifier will create test class `defaultBasePackage.MyServ Plugin registers itself to be invoked before `check` 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 `generateContractTests` task. +==== Default setup + +Default Gradle Plugin setup creates the following Gradle part of the build (it's a pseudocode) + +[source,groovy,indent=0] +---- +contractVerifier { + targetFramework = 'JUNIT' + testMode = 'MockMvc' + generatedTestSourcesDir = project.file("${project.buildDir}/generated-test-sources/contracts") + contractsDslDir = "${project.rootDir}/src/test/resources/contracts" + basePackageForTests = 'org.springframework.cloud.contract.verifier.tests' + stubsOutputDir = project.file("${project.buildDir}/stubs") +} + +tasks.create(type: Jar, name: 'verifierStubsJar', dependsOn: 'generateWireMockClientStubs') { + baseName = project.name + classifier = contractVerifier.stubsSuffix + from contractVerifier.stubsOutputDir +} + +project.artifacts { + archives task +} + +tasks.create(type: Copy, name: 'copyContracts') { + from contractVerifier.contractsDslDir + into contractVerifier.stubsOutputDir +} + +verifierStubsJar.dependsOn 'copyContracts' + +publishing { + publications { + stubs(MavenPublication) { + artifactId project.name + artifact verifierStubsJar + } + } +} +---- + ==== Configure plugin To change default configuration just add `contractVerifier` snippet to your Gradle config diff --git a/docs/src/main/asciidoc/stubrunner.adoc b/docs/src/main/asciidoc/stubrunner.adoc index 3478146c9f..6ba4fb98f9 100644 --- a/docs/src/main/asciidoc/stubrunner.adoc +++ b/docs/src/main/asciidoc/stubrunner.adoc @@ -9,6 +9,19 @@ One of the issues that you could have encountered while using Spring Cloud Contr Copying the JSON files / setting the client side for messaging manually is out of the question. +=== Snapshot versions + +Add the additional snapshot repository to your build.gradle to use snapshot versions which are automatically uploaded after every successful build: + +[source,groovy,indent=0] +---- +repositories { + (...) + //Required only for SNAPSHOT versions + maven { url "https://repo.spring.io/libs-snapshot-local" } +} +---- + === Publishing stubs as JARs The easiest approach would be to centralize the way stubs are kept. For example you can keep them as JARs in a Maven repository. From da801e52c7a4b7aacc4908415b674588869ea06f Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 6 Jul 2016 15:38:20 +0200 Subject: [PATCH 714/719] Added property to skip array size assertion (#295) with this fix you can pass set the Contract Verifier property 'assertJsonSize' to true / false in order to check / not check the array size of a JSON workaround to #293 --- docs/src/main/asciidoc/contract.adoc | 4 + .../JUnitMessagingMethodBodyBuilder.groovy | 7 +- .../builder/JUnitMethodBodyBuilder.groovy | 7 +- .../JaxRsClientJUnitMethodBodyBuilder.groovy | 5 +- ...kMethodRequestProcessingBodyBuilder.groovy | 5 +- .../builder/MessagingMethodBodyBuilder.groovy | 4 +- .../verifier/builder/MethodBodyBuilder.groovy | 18 ++- .../verifier/builder/MethodBuilder.groovy | 19 +-- .../MockMvcJUnitMethodBodyBuilder.groovy | 5 +- ...kMethodRequestProcessingBodyBuilder.groovy | 5 +- .../RequestProcessingMethodBodyBuilder.groovy | 4 +- .../SpockMessagingMethodBodyBuilder.groovy | 5 +- ...kMethodRequestProcessingBodyBuilder.groovy | 5 +- .../ContractVerifierConfigProperties.groovy | 6 + .../util/JsonToJsonPathsConverter.groovy | 53 ++++--- .../builder/ContractHttpDocsSpec.groovy | 6 +- .../JaxRsClientMethodBuilderSpec.groovy | 74 ++++----- .../MessagingMethodBodyBuilderSpec.groovy | 22 +-- .../MockMvcMethodBodyBuilderSpec.groovy | 143 +++++++++--------- .../util/JsonToJsonPathsConverterSpec.groovy | 36 ++--- 20 files changed, 246 insertions(+), 187 deletions(-) diff --git a/docs/src/main/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc index 9a3ee50346..450319ffd9 100644 --- a/docs/src/main/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -32,6 +32,10 @@ WARNING: Spring Cloud Contract Verifier doesn't support XML properly. Please use WARNING: Spring Cloud Contract Verifier supports equality check on text response. Regular expressions are not yet available. +WARNING: The support for the verification of size of JSON arrays is experimental. If you want to turn it on please provide +the value of a system property `spring.cloud.contract.verifier.assert.size` equal to `turn`. By default this feature is +`off`. + === HTTP Top-Level Elements Following methods can be called in the top-level closure of a contract definition. Request and response are mandatory, priority is optional. diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy index e43b17e1c6..25063a8d7f 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy @@ -20,10 +20,11 @@ import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.ExecutionProperty import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.Input import org.springframework.cloud.contract.spec.internal.NamedProperty -import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern @@ -43,8 +44,8 @@ import static org.springframework.cloud.contract.verifier.config.TestFramework.J @TypeChecked class JUnitMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { - JUnitMessagingMethodBodyBuilder(Contract stubDefinition) { - super(stubDefinition) + JUnitMessagingMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) } @Override diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy index 153542ea8d..730ade10c2 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy @@ -20,10 +20,11 @@ import groovy.json.StringEscapeUtils import groovy.transform.PackageScope import groovy.transform.TypeChecked import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.spec.internal.ExecutionProperty import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.NamedProperty import org.springframework.cloud.contract.spec.internal.Request -import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern @@ -45,8 +46,8 @@ import static org.springframework.cloud.contract.verifier.util.ContentUtils.getJ @PackageScope abstract class JUnitMethodBodyBuilder extends RequestProcessingMethodBodyBuilder { - JUnitMethodBodyBuilder(Contract stubDefinition) { - super(stubDefinition) + JUnitMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) } @Override diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy index 2e5a36af8b..61916f3197 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy @@ -23,6 +23,7 @@ import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.QueryParameter import org.springframework.cloud.contract.spec.internal.ExecutionProperty import org.springframework.cloud.contract.spec.internal.QueryParameters +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern @@ -42,8 +43,8 @@ import static org.springframework.cloud.contract.verifier.config.TestFramework.J @PackageScope class JaxRsClientJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { - JaxRsClientJUnitMethodBodyBuilder(Contract stubDefinition) { - super(stubDefinition) + JaxRsClientJUnitMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) } @Override diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy index c639383e0e..97283c9596 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy @@ -23,6 +23,7 @@ import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.QueryParameter import org.springframework.cloud.contract.spec.internal.QueryParameters import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern @@ -39,8 +40,8 @@ import java.util.regex.Pattern @TypeChecked class JaxRsClientSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestProcessingBodyBuilder { - JaxRsClientSpockMethodRequestProcessingBodyBuilder(Contract stubDefinition) { - super(stubDefinition) + JaxRsClientSpockMethodRequestProcessingBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) } @Override diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy index 29e0b6d415..88366ce7b8 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy @@ -22,6 +22,7 @@ import groovy.transform.TypeChecked import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.spec.internal.Input import org.springframework.cloud.contract.spec.internal.OutputMessage +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.util.ContentType import static org.springframework.cloud.contract.verifier.util.ContentUtils.recognizeContentTypeFromContent @@ -43,7 +44,8 @@ abstract class MessagingMethodBodyBuilder extends MethodBodyBuilder { protected final Input inputMessage protected final OutputMessage outputMessage - MessagingMethodBodyBuilder(Contract stubDefinition) { + MessagingMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(configProperties) this.inputMessage = stubDefinition.input this.outputMessage = stubDefinition.outputMessage } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy index c1c4ca440e..a0b2730efc 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy @@ -18,16 +18,12 @@ package org.springframework.cloud.contract.verifier.builder import groovy.transform.PackageScope import groovy.transform.TypeChecked -import org.springframework.cloud.contract.spec.internal.NamedProperty -import org.springframework.cloud.contract.verifier.util.MapConverter -import org.springframework.cloud.contract.spec.internal.DslProperty -import org.springframework.cloud.contract.spec.internal.ExecutionProperty -import org.springframework.cloud.contract.spec.internal.Header -import org.springframework.cloud.contract.spec.internal.MatchingStrategy -import org.springframework.cloud.contract.spec.internal.QueryParameter +import org.springframework.cloud.contract.spec.internal.* +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.util.ContentType import org.springframework.cloud.contract.verifier.util.JsonPaths import org.springframework.cloud.contract.verifier.util.JsonToJsonPathsConverter +import org.springframework.cloud.contract.verifier.util.MapConverter import java.util.regex.Pattern @@ -46,6 +42,12 @@ import static org.springframework.cloud.contract.verifier.util.ContentUtils.extr @PackageScope abstract class MethodBodyBuilder { + protected final ContractVerifierConfigProperties configProperties + + protected MethodBodyBuilder(ContractVerifierConfigProperties configProperties) { + this.configProperties = configProperties + } + /** * Builds the response body validation code block */ @@ -245,7 +247,7 @@ abstract class MethodBodyBuilder { } if (contentType == ContentType.JSON) { appendJsonPath(bb, getResponseAsString()) - JsonPaths jsonPaths = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(responseBody) + JsonPaths jsonPaths = new JsonToJsonPathsConverter(configProperties).transformToJsonPathWithTestsSideValues(responseBody) jsonPaths.each { String method = it.method() String postProcessedMethod = postProcessJsonPathCall(method) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy index 29176013d8..0d17899d91 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy @@ -19,6 +19,7 @@ package org.springframework.cloud.contract.verifier.builder import groovy.transform.CompileStatic import groovy.transform.PackageScope import groovy.util.logging.Slf4j +import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.config.TestFramework import org.springframework.cloud.contract.verifier.util.NamesUtil @@ -38,11 +39,11 @@ import org.springframework.cloud.contract.verifier.file.ContractMetadata class MethodBuilder { private final String methodName - private final org.springframework.cloud.contract.spec.Contract stubContent + private final Contract stubContent private final ContractVerifierConfigProperties configProperties private final boolean ignored - private MethodBuilder(String methodName, org.springframework.cloud.contract.spec.Contract stubContent, ContractVerifierConfigProperties configProperties, boolean ignored) { + private MethodBuilder(String methodName, Contract stubContent, ContractVerifierConfigProperties configProperties, boolean ignored) { this.ignored = ignored this.stubContent = stubContent this.methodName = methodName @@ -52,7 +53,7 @@ class MethodBuilder { /** * A factory method that creates a {@link MethodBuilder} for the given arguments */ - static MethodBuilder createTestMethod(ContractMetadata contract, File stubsFile, org.springframework.cloud.contract.spec.Contract stubContent, ContractVerifierConfigProperties configProperties) { + static MethodBuilder createTestMethod(ContractMetadata contract, File stubsFile, Contract stubContent, ContractVerifierConfigProperties 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) @@ -76,20 +77,20 @@ class MethodBuilder { private MethodBodyBuilder getMethodBodyBuilder() { if (stubContent.input || stubContent.outputMessage) { if (configProperties.targetFramework == TestFramework.JUNIT){ - return new JUnitMessagingMethodBodyBuilder(stubContent) + return new JUnitMessagingMethodBodyBuilder(stubContent, configProperties) } - return new SpockMessagingMethodBodyBuilder(stubContent) + return new SpockMessagingMethodBodyBuilder(stubContent, configProperties) } if (configProperties.testMode == TestMode.MOCKMVC && configProperties.targetFramework == TestFramework.JUNIT){ - return new MockMvcJUnitMethodBodyBuilder(stubContent) + return new MockMvcJUnitMethodBodyBuilder(stubContent, configProperties) } if (configProperties.testMode == TestMode.JAXRSCLIENT) { if (configProperties.targetFramework == TestFramework.JUNIT){ - return new JaxRsClientJUnitMethodBodyBuilder(stubContent) + return new JaxRsClientJUnitMethodBodyBuilder(stubContent, configProperties) } - return new JaxRsClientSpockMethodRequestProcessingBodyBuilder(stubContent) + return new JaxRsClientSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties) } - return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent) + return new MockMvcSpockMethodRequestProcessingBodyBuilder(stubContent, configProperties) } } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy index baf893c1b6..d4556732aa 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy @@ -21,6 +21,7 @@ import groovy.transform.TypeChecked import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern @@ -35,8 +36,8 @@ import java.util.regex.Pattern @PackageScope class MockMvcJUnitMethodBodyBuilder extends JUnitMethodBodyBuilder { - MockMvcJUnitMethodBodyBuilder(Contract stubDefinition) { - super(stubDefinition) + MockMvcJUnitMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) } @Override diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy index cc0c873546..a1655e52ce 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy @@ -21,6 +21,7 @@ import groovy.transform.TypeChecked import org.springframework.cloud.contract.spec.Contract import org.springframework.cloud.contract.spec.internal.ExecutionProperty import org.springframework.cloud.contract.spec.internal.Header +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern @@ -33,8 +34,8 @@ import java.util.regex.Pattern @TypeChecked class MockMvcSpockMethodRequestProcessingBodyBuilder extends SpockMethodRequestProcessingBodyBuilder { - MockMvcSpockMethodRequestProcessingBodyBuilder(Contract stubDefinition) { - super(stubDefinition) + MockMvcSpockMethodRequestProcessingBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) } @Override diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy index c80a3e902f..f1251acd6f 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy @@ -28,6 +28,7 @@ import org.springframework.cloud.contract.spec.internal.NamedProperty import org.springframework.cloud.contract.spec.internal.QueryParameter import org.springframework.cloud.contract.spec.internal.Response import org.springframework.cloud.contract.spec.internal.Url +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.util.ContentType import org.springframework.cloud.contract.verifier.util.MapConverter @@ -50,7 +51,8 @@ abstract class RequestProcessingMethodBodyBuilder extends MethodBodyBuilder { protected final Request request protected final Response response - RequestProcessingMethodBodyBuilder(Contract stubDefinition) { + RequestProcessingMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(configProperties) this.request = stubDefinition.request this.response = stubDefinition.response } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy index 701ae25501..639d28bbd6 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy @@ -24,6 +24,7 @@ import org.springframework.cloud.contract.spec.internal.ExecutionProperty import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.Input import org.springframework.cloud.contract.spec.internal.NamedProperty +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern /** @@ -33,8 +34,8 @@ import java.util.regex.Pattern @TypeChecked class SpockMessagingMethodBodyBuilder extends MessagingMethodBodyBuilder { - SpockMessagingMethodBodyBuilder(Contract stubDefinition) { - super(stubDefinition) + SpockMessagingMethodBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) } @Override diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy index dac23ae776..a9d8274509 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy @@ -24,6 +24,7 @@ import org.springframework.cloud.contract.spec.internal.Header import org.springframework.cloud.contract.spec.internal.NamedProperty import org.springframework.cloud.contract.spec.internal.Request import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern @@ -40,8 +41,8 @@ import static org.springframework.cloud.contract.verifier.util.ContentUtils.getG @TypeChecked abstract class SpockMethodRequestProcessingBodyBuilder extends RequestProcessingMethodBodyBuilder { - SpockMethodRequestProcessingBodyBuilder(Contract stubDefinition) { - super(stubDefinition) + SpockMethodRequestProcessingBodyBuilder(Contract stubDefinition, ContractVerifierConfigProperties configProperties) { + super(stubDefinition, configProperties) } @Override diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy index 2e38d50db6..366c9c4c96 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy @@ -96,4 +96,10 @@ class ContractVerifierConfigProperties { */ String stubsSuffix = 'stubs' + /** + * Incubating feature. You can check the size of JSON arrays. If not turned on + * explicitly will be disabled. + */ + Boolean assertJsonSize + } diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy index 625fbc415d..7825035622 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy @@ -19,8 +19,10 @@ package org.springframework.cloud.contract.verifier.util import com.toomuchcoding.jsonassert.JsonAssertion import groovy.json.JsonOutput import groovy.json.JsonSlurper +import groovy.util.logging.Slf4j import org.springframework.cloud.contract.spec.internal.OptionalProperty import org.springframework.cloud.contract.spec.internal.ExecutionProperty +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import java.util.regex.Pattern @@ -31,6 +33,7 @@ import java.util.regex.Pattern * * @author Marcin Grzejszczak */ +@Slf4j class JsonToJsonPathsConverter { /** @@ -42,15 +45,25 @@ class JsonToJsonPathsConverter { private static final Boolean SERVER_SIDE = false private static final Boolean CLIENT_SIDE = true + private final ContractVerifierConfigProperties configProperties + + JsonToJsonPathsConverter(ContractVerifierConfigProperties configProperties) { + this.configProperties = configProperties + } + + JsonToJsonPathsConverter() { + this.configProperties = new ContractVerifierConfigProperties() + } + public static JsonPaths transformToJsonPathWithTestsSideValues(def json) { - return transformToJsonPathWithValues(json, SERVER_SIDE) + return new JsonToJsonPathsConverter().transformToJsonPathWithValues(json, SERVER_SIDE) } public static JsonPaths transformToJsonPathWithStubsSideValues(def json) { - return transformToJsonPathWithValues(json, CLIENT_SIDE) + return new JsonToJsonPathsConverter().transformToJsonPathWithValues(json, CLIENT_SIDE) } - private static JsonPaths transformToJsonPathWithValues(def json, boolean clientSide) { + private JsonPaths transformToJsonPathWithValues(def json, boolean clientSide) { if(!json) { return new JsonPaths() } @@ -69,7 +82,7 @@ class JsonToJsonPathsConverter { return pathsAndValues } - protected static def traverseRecursively(Class parentType, MethodBufferingJsonVerifiable key, def value, Closure closure) { + protected def traverseRecursively(Class parentType, MethodBufferingJsonVerifiable key, def value, Closure closure) { value = ContentUtils.returnParsedObject(value) if (value instanceof String && value) { try { @@ -120,10 +133,16 @@ class JsonToJsonPathsConverter { } // Size verification: https://github.com/Codearte/accurest/issues/279 - private static void addSizeVerificationForListWithPrimitives(MethodBufferingJsonVerifiable key, Closure closure, List value) { - if (System.getProperty(SIZE_ASSERTION_SYSTEM_PROP, "true") == "false") { + private void addSizeVerificationForListWithPrimitives(MethodBufferingJsonVerifiable key, Closure closure, List value) { + Boolean systemPropValue = Boolean.parseBoolean(System.getProperty(SIZE_ASSERTION_SYSTEM_PROP, "false")) + Boolean configPropValue = configProperties.assertJsonSize + boolean configPropSet = configPropValue != null + if (configPropSet && !configPropValue) { + return + } else if (!configPropSet && systemPropValue) { return } + log.debug("WARNING: Turning on the incubating feature of JSON array check") if (isRootElement(key) || key.assertsConcreteValue()) { if (value.size() > 0) { closure(key.hasSize(value.size()), value) @@ -131,12 +150,12 @@ class JsonToJsonPathsConverter { } } - private static boolean isRootElement(MethodBufferingJsonVerifiable key) { + private boolean isRootElement(MethodBufferingJsonVerifiable key) { return key.jsonPath() == '$' } // If you have a list of not-only primitives it can contain different sets of elements (maps, lists, primitives) - private static MethodBufferingJsonVerifiable createAsserterFromList(MethodBufferingJsonVerifiable key, List value) { + private MethodBufferingJsonVerifiable createAsserterFromList(MethodBufferingJsonVerifiable key, List value) { if (key.isIteratingOverNamelessArray()) { return key.array() } else if (key.isIteratingOverArray() && isAnEntryWithLists(value)) { @@ -151,7 +170,7 @@ class JsonToJsonPathsConverter { return key } - private static MethodBufferingJsonVerifiable createAsserterFromListElement(MethodBufferingJsonVerifiable jsonPathVerifiable, def element) { + private MethodBufferingJsonVerifiable createAsserterFromListElement(MethodBufferingJsonVerifiable jsonPathVerifiable, def element) { if (jsonPathVerifiable.isAssertingAValueInArray()) { def object = ContentUtils.returnParsedObject(element) if (object instanceof Pattern) { @@ -162,14 +181,14 @@ class JsonToJsonPathsConverter { return jsonPathVerifiable } - private static def runClosure(Closure closure, MethodBufferingJsonVerifiable key, def value) { + private def runClosure(Closure closure, MethodBufferingJsonVerifiable key, def value) { if (key.isAssertingAValueInArray() && !(value instanceof List || value instanceof Map)) { return closure(valueToAsserter(key, value), value) } return closure(key, value) } - private static boolean isAnEntryWithNonCollectionLikeValue(def value) { + private boolean isAnEntryWithNonCollectionLikeValue(def value) { if (!(value instanceof Map)) { return false } @@ -182,7 +201,7 @@ class JsonToJsonPathsConverter { return !(valueOfEntry instanceof Map || valueOfEntry instanceof List) } - private static boolean isAnEntryWithoutNestedStructures(def value) { + private boolean isAnEntryWithoutNestedStructures(def value) { if (!(value instanceof Map)) { return false } @@ -192,14 +211,14 @@ class JsonToJsonPathsConverter { } } - private static boolean listContainsOnlyPrimitives(List list) { + private boolean listContainsOnlyPrimitives(List list) { return list.every { def element -> [String, Number, Boolean].any { it.isAssignableFrom(element.getClass()) } } } - private static boolean isAnEntryWithLists(def value) { + private boolean isAnEntryWithLists(def value) { if (!(value instanceof Iterable)) { return false } @@ -208,7 +227,7 @@ class JsonToJsonPathsConverter { } } - private static Map convertWithKey(Class parentType, MethodBufferingJsonVerifiable parentKey, Map map, Closure closureToExecute) { + private Map convertWithKey(Class parentType, MethodBufferingJsonVerifiable parentKey, Map map, Closure closureToExecute) { return map.collectEntries { Object entrykey, value -> def convertedValue = ContentUtils.returnParsedObject(value) @@ -222,11 +241,11 @@ class JsonToJsonPathsConverter { } } - private static void traverseRecursivelyForKey(def json, MethodBufferingJsonVerifiable rootKey, Closure closure) { + private void traverseRecursivelyForKey(def json, MethodBufferingJsonVerifiable rootKey, Closure closure) { traverseRecursively(Map, rootKey, json, closure) } - protected static MethodBufferingJsonVerifiable valueToAsserter(MethodBufferingJsonVerifiable key, Object value) { + protected MethodBufferingJsonVerifiable valueToAsserter(MethodBufferingJsonVerifiable key, Object value) { def convertedValue = ContentUtils.returnParsedObject(value) if (key instanceof FinishedDelegatingJsonVerifiable) { return key diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy index c2a34bd06f..1c23b37367 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy @@ -16,6 +16,8 @@ package org.springframework.cloud.contract.verifier.builder +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import spock.lang.Shared import spock.lang.Specification /** @@ -25,6 +27,8 @@ import spock.lang.Specification */ class ContractHttpDocsSpec extends Specification { + @Shared ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(assertJsonSize: true) + org.springframework.cloud.contract.spec.Contract httpDsl = // tag::http_dsl[] org.springframework.cloud.contract.spec.Contract.make { @@ -257,7 +261,7 @@ class ContractHttpDocsSpec extends Specification { def 'should convert dsl with optionals to proper Spock test'() { given: BlockBuilder blockBuilder = new BlockBuilder(" ") - new MockMvcSpockMethodRequestProcessingBodyBuilder(optionals).appendTo(blockBuilder) + new MockMvcSpockMethodRequestProcessingBodyBuilder(optionals, properties).appendTo(blockBuilder) expect: String expectedTest = // tag::optionals_test[] diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy index 105bcbce66..777c28a59c 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy @@ -16,14 +16,18 @@ package org.springframework.cloud.contract.verifier.builder +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier import org.springframework.cloud.contract.verifier.file.ContractMetadata import org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockStubStrategy import spock.lang.Issue +import spock.lang.Shared import spock.lang.Specification class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStubVerifier { + @Shared ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(assertJsonSize: true) + def "should generate assertions for simple response body with #methodBuilderName"() { given: org.springframework.cloud.contract.spec.Contract contractDsl = org.springframework.cloud.contract.spec.Contract.make { @@ -50,8 +54,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } @Issue("#187") @@ -83,8 +87,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub()) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } @Issue("#79") @@ -119,8 +123,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(new WireMockStubStrategy("Test", new ContractMetadata(null, false, 0, null), contractDsl).toWireMockClientStub()) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } @Issue("#82") @@ -148,8 +152,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('{\"items\":[\"HOP\"]}', 'application/json')""" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("{\\"items\\":[\\"HOP\\"]}", "application/json")' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """entity('{\"items\":[\"HOP\"]}', 'application/json')""" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | 'entity("{\\"items\\":[\\"HOP\\"]}", "application/json")' } @Issue("#88") @@ -177,8 +181,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | """entity('property1=VAL1', 'application/octet-stream')""" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"property1=VAL1\\"", "application/octet-stream")' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """entity('property1=VAL1', 'application/octet-stream')""" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | 'entity("\\"property1=VAL1\\"", "application/octet-stream")' } def "should generate assertions for array in response body with #methodBuilderName"() { @@ -210,8 +214,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } def "should generate assertions for array inside response body element with #methodBuilderName"() { @@ -242,8 +246,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } def "should generate assertions for nested objects in response body with #methodBuilderName"() { @@ -274,8 +278,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } def "should generate regex assertions for map objects in response body with #methodBodyName"() { @@ -312,8 +316,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } def "should generate regex assertions for string objects in response body with #methodBuilderName"() { @@ -344,8 +348,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } } def "should ignore 'Accept' header and use 'request' method with #methodBuilderName"() { @@ -372,8 +376,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | requestString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "request('text/plain')" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'request("text/plain")' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | "request('text/plain')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | 'request("text/plain")' } def "should ignore 'Content-Type' header and use 'entity' method with #methodBuilderName"() { @@ -405,8 +409,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | requestStrings - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ["""entity('', 'text/plain')""", """header('Timer', '123')"""] - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")'] + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ["""entity('', 'text/plain')""", """header('Timer', '123')"""] + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | ['entity("\\"\\"", "text/plain")', 'header("Timer", "123")'] } def "should generate a call with an url path and query parameters with #methodBuilderName"() { @@ -459,8 +463,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | modifyStringIfRequired - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String paramString -> paramString } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String paramString -> paramString.replace("'", "\"") } } @Issue('#169') @@ -514,8 +518,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | modifyStringIfRequired - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | { String paramString -> paramString } - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | { String paramString -> paramString.replace("'", "\"") } + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | { String paramString -> paramString } + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | { String paramString -> paramString.replace("'", "\"") } } def "should generate test for empty body with #methodBuilderName"() { @@ -542,8 +546,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "entity('', 'application/octet-stream')" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'entity("\\"\\"", "application/octet-stream"' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | "entity('', 'application/octet-stream')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | 'entity("\\"\\"", "application/octet-stream"' } def "should generate test for String in response body with #methodBodyName"() { @@ -570,8 +574,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | "String responseAsString = response.readEntity(String)" | 'responseBody == "test"' - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (responseAsString);' | 'assertThat(responseBody).isEqualTo("test");' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | "String responseAsString = response.readEntity(String)" | 'responseBody == "test"' + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | 'Object responseBody = (responseAsString);' | 'assertThat(responseBody).isEqualTo("test");' } @Issue('#171') @@ -603,8 +607,8 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | methodString - "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl) } | ".method('GET')" - "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl) } | 'method("GET")' + "JaxRsClientSpockMethodRequestProcessingBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ".method('GET')" + "JaxRsClientJUnitMethodBodyBuilder" | { org.springframework.cloud.contract.spec.Contract dsl -> new JaxRsClientJUnitMethodBodyBuilder(dsl, properties) } | 'method("GET")' } def "should generate a call with an url path and query parameters with JUnit - we'll put it into docs"() { @@ -636,7 +640,7 @@ class JaxRsClientMethodBuilderSpec extends Specification implements WireMockStub """ } } - MethodBodyBuilder builder = new JaxRsClientJUnitMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new JaxRsClientJUnitMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy index b23add6810..2257459583 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy @@ -17,12 +17,16 @@ package org.springframework.cloud.contract.verifier.builder import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties +import spock.lang.Shared import spock.lang.Specification /** * @author Marcin Grzejszczak */ class MessagingMethodBodyBuilderSpec extends Specification { + @Shared ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(assertJsonSize: true) + def "should work for triggered based messaging with Spock"() { given: // tag::trigger_method_dsl[] @@ -40,7 +44,7 @@ def contractDsl = Contract.make { } } // end::trigger_method_dsl[] - MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -80,7 +84,7 @@ def contractDsl = Contract.make { } } } - MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -129,7 +133,7 @@ def contractDsl = Contract.make { } } // end::trigger_message_dsl[] - MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -182,7 +186,7 @@ and: } } } - MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -229,7 +233,7 @@ def contractDsl = Contract.make { } } // end::trigger_no_output_dsl[] - MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -270,7 +274,7 @@ then: assertThat('bookWasDeleted()') } } - MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -315,7 +319,7 @@ then: ]) } } - MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -361,7 +365,7 @@ then: ]) } } - MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new SpockMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -414,7 +418,7 @@ Contract.make { } } // end::consumer_producer[] - MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new JUnitMessagingMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy index 9918f7055a..7f8dec46f2 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy @@ -17,6 +17,7 @@ package org.springframework.cloud.contract.verifier.builder import org.springframework.cloud.contract.spec.Contract +import org.springframework.cloud.contract.verifier.config.ContractVerifierConfigProperties import org.springframework.cloud.contract.verifier.dsl.WireMockStubVerifier import spock.lang.Issue import spock.lang.Shared @@ -28,6 +29,8 @@ import java.util.regex.Pattern */ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStubVerifier { + @Shared ContractVerifierConfigProperties properties = new ContractVerifierConfigProperties(assertJsonSize: true) + @Shared Contract dslWithOptionalsInString = Contract.make { priority 1 @@ -118,8 +121,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue("#187") @@ -151,8 +154,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue("#79") @@ -187,8 +190,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue("#82") @@ -216,8 +219,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """.body('''{\"items\":[\"HOP\"]}''')""" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("{\\"items\\":[\\"HOP\\"]}")' + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''{\"items\":[\"HOP\"]}''')""" + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("{\\"items\\":[\\"HOP\\"]}")' } @Issue("#88") @@ -245,8 +248,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """.body('''property1=VAL1''')""" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.body("\\"property1=VAL1\\"")' + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """.body('''property1=VAL1''')""" + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.body("\\"property1=VAL1\\"")' } @Issue("185") @@ -278,8 +281,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should generate assertions for array in response body with #methodBuilderName"() { @@ -311,8 +314,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should generate assertions for array inside response body element with #methodBuilderName"() { @@ -343,8 +346,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should generate assertions for nested objects in response body with #methodBuilderName"() { @@ -375,8 +378,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should generate regex assertions for map objects in response body with #methodBuilderName"() { @@ -411,8 +414,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should generate regex assertions for string objects in response body with #methodBuilderName"() { @@ -443,8 +446,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue(["#126", "#143"]) @@ -475,8 +478,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should generate a call with an url path and query parameters with #methodBuilderName"() { @@ -522,8 +525,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue('#169') @@ -570,8 +573,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should generate test for empty body with #methodBuilderName"() { @@ -597,8 +600,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ".body('''''')" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ".body(\"\\\"\\\"\")" + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ".body('''''')" + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ".body(\"\\\"\\\"\")" } def "should generate test for String in response body with #methodBuilderName"() { @@ -625,8 +628,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyDefinitionString | bodyEvaluationString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'Object responseBody = (response.getBody().asString());' | 'assertThat(responseBody).isEqualTo("test");' + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | 'def responseBody = (response.body.asString())' | 'responseBody == "test"' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'Object responseBody = (response.getBody().asString());' | 'assertThat(responseBody).isEqualTo("test");' } @Issue('113') @@ -664,8 +667,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | headerEvaluationString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('http://localhost/partners/[0-9]+/users/[0-9]+')''' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("http://localhost/partners/[0-9]+/users/[0-9]+");' } @Issue('115') @@ -703,8 +706,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | headerEvaluationString - "MockMvcSpockMethodBuilder" | { Contract 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" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");' + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '''response.header('Location') ==~ java.util.regex.Pattern.compile('^((http[s]?|ftp):\\/)\\/?([^:\\/\\s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+')''' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | 'assertThat(response.header("Location")).matches("^((http[s]?|ftp):/)/?([^:/s]+)(:[0-9]{1,5})?/partners/[0-9]+/users/[0-9]+");' } def "should work with more complex stuff and jsonpaths with #methodBuilderName"() { @@ -744,8 +747,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should work properly with GString url with #methodBuilderName"() { @@ -777,8 +780,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } def "should resolve properties in GString with regular expression with #methodBuilderName"() { @@ -816,14 +819,14 @@ 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" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue('42') def "should not omit the optional field in the test creation with MockMvcSpockMethodBodyBuilder"() { given: - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) + MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -841,7 +844,7 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub @Issue('42') def "should not omit the optional field in the test creation with MockMvcJUnitMethodBodyBuilder"() { given: - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -905,8 +908,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub } where: methodBuilderName | methodBuilder | assertionStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''', '''assertThatLocationIsNull(response.header('Location'))'''] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read('$.rejectionReason'))''', '''assertThatLocationIsNull(response.header('Location'))'''] + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['''assertThatRejectionReasonIsNull(parsedJson.read("$.rejectionReason"))''', '''assertThatLocationIsNull(response.header("Location"))'''] } def "should support inner map and list definitions with #methodBuilderName"() { @@ -972,8 +975,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub !test.contains("cursor") where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '"street":"Light Street"' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"street\\":\\"Light Street\\"' + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '"street":"Light Street"' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '\\"street\\":\\"Light Street\\"' } @@ -1011,8 +1014,8 @@ class MockMvcMethodBodyBuilderSpec extends Specification implements WireMockStub !test.contains("\\u041f") where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue('177') @@ -1038,9 +1041,9 @@ World.''') test.contains(bodyString) where: methodBuilderName | methodBuilder | bodyString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | """'''hello, + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | """'''hello, World.'''""" - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '\\"hello,\\nWorld.\\"' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '\\"hello,\\nWorld.\\"' } @Issue('180') @@ -1074,11 +1077,11 @@ World.'''""" } where: methodBuilderName | methodBuilder | requestStrings - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | ["""'content-type', 'multipart/form-data;boundary=AaB03x'""", + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | ["""'content-type', 'multipart/form-data;boundary=AaB03x'""", """.param('formParameter', '"formParameterValue"'""", """.param('someBooleanParameter', 'true')""", """.multiPart('file', 'filename.csv', 'file content'.bytes)"""] - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | ['"content-type", "multipart/form-data;boundary=AaB03x"', + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | ['"content-type", "multipart/form-data;boundary=AaB03x"', '.param("formParameter", "\\"formParameterValue\\"")', '.param("someBooleanParameter", "true")', '.multiPart("file", "filename.csv", "file content".getBytes());'] @@ -1112,8 +1115,8 @@ World.'''""" test.contains('.multiPart') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue('#216') @@ -1141,7 +1144,7 @@ World.'''""" ) } } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) + MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -1175,7 +1178,7 @@ World.'''""" ) } } - MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl) + MethodBodyBuilder builder = new MockMvcJUnitMethodBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.appendTo(blockBuilder) @@ -1210,8 +1213,8 @@ World.'''""" test.contains('''assertThatRejectionReasonIsNull(''') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue('262') @@ -1236,7 +1239,7 @@ World.'''""" } } } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) + MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.then(blockBuilder) @@ -1275,8 +1278,8 @@ World.'''""" test.contains('assertThatJson(parsedJson).arrayField().contains("SpringBoot").value()') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue('266') @@ -1308,8 +1311,8 @@ World.'''""" test.contains('assertThatJson(parsedJson).array().arrayField().isEqualTo("Boot").value()') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue('47') @@ -1336,8 +1339,8 @@ World.'''""" stubMappingIsValidWireMockStub(contractDsl) where: methodBuilderName | methodBuilder | bodyDefinitionString - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } | '.when().async()' - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } | '.when().async()' + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } | '.when().async()' + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } | '.when().async()' } def "should generate proper test code with array of primitives using #methodBuilderName"() { @@ -1369,8 +1372,8 @@ World.'''""" test.contains('assertThatJson(parsedJson).array("partners").array("payment_methods").arrayField().isEqualTo("CASH").value()') where: methodBuilderName | methodBuilder - "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl) } - "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl) } + "MockMvcSpockMethodBuilder" | { Contract dsl -> new MockMvcSpockMethodRequestProcessingBodyBuilder(dsl, properties) } + "MockMvcJUnitMethodBuilder" | { Contract dsl -> new MockMvcJUnitMethodBodyBuilder(dsl, properties) } } @Issue('#273') @@ -1386,7 +1389,7 @@ World.'''""" body( code: 9, message: $(client('Wrong credentials'), server(regex('^(?!\\s*$).+'))) ) } } - MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl) + MethodBodyBuilder builder = new MockMvcSpockMethodRequestProcessingBodyBuilder(contractDsl, properties) BlockBuilder blockBuilder = new BlockBuilder(" ") when: builder.then(blockBuilder) diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy index 958dddf585..7bbf672dca 100644 --- a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy +++ b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy @@ -32,7 +32,7 @@ class JsonToJsonPathsConverterSpec extends Specification { def 'should convert a json with list as root to a map of path to value'() { when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method() == """.array().field("some").field("nested").field("json").isEqualTo("with value")""" && @@ -125,7 +125,7 @@ class JsonToJsonPathsConverterSpec extends Specification { } ''' when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method() == """.field("some").field("nested").field("json").isEqualTo("with value")""" && @@ -155,7 +155,7 @@ class JsonToJsonPathsConverterSpec extends Specification { } ''' when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method() == """.array("items").arrayField().isEqualTo("HOP").value()""" && @@ -174,7 +174,7 @@ class JsonToJsonPathsConverterSpec extends Specification { } ''' when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method() == """.field("property1").isNull()""" && @@ -193,7 +193,7 @@ class JsonToJsonPathsConverterSpec extends Specification { } ''' when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method() == """.field("extensions").field("7").isEqualTo(28)""" && @@ -222,7 +222,7 @@ class JsonToJsonPathsConverterSpec extends Specification { } ''' when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method() == """.array("errors").contains("property").isEqualTo("email")""" && @@ -273,7 +273,7 @@ class JsonToJsonPathsConverterSpec extends Specification { ] ] when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(json) then: pathAndValues.find { it.method() == """.array().field("some").field("nested").field("json").isEqualTo("with value")""" && @@ -309,7 +309,7 @@ class JsonToJsonPathsConverterSpec extends Specification { "property2": "b" }""" when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method()== """.field("property1").isEqualTo("a")""" && @@ -331,7 +331,7 @@ class JsonToJsonPathsConverterSpec extends Specification { "property3": false }""" when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method()== """.field("property1").isEqualTo("true")""" && @@ -359,7 +359,7 @@ class JsonToJsonPathsConverterSpec extends Specification { ] ] when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(json) then: pathAndValues.find { it.method()== """.field("property1").isEqualTo("a")""" && @@ -390,7 +390,7 @@ class JsonToJsonPathsConverterSpec extends Specification { ] ] when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(json) then: pathAndValues.find { it.method()== """.field("property").field(7).isEqualTo(0.0)""" && @@ -414,7 +414,7 @@ class JsonToJsonPathsConverterSpec extends Specification { "property2": "b" }]""" when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method()== """.array().contains("property1").isEqualTo("a")""" && @@ -441,7 +441,7 @@ class JsonToJsonPathsConverterSpec extends Specification { ] }""" when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method()== """.array("property1").contains("property2").isEqualTo("test1")""" && @@ -466,7 +466,7 @@ class JsonToJsonPathsConverterSpec extends Specification { "property2": {"property3": "b"} }""" when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method()== """.field("property2").field("property3").isEqualTo("b")""" && @@ -487,7 +487,7 @@ class JsonToJsonPathsConverterSpec extends Specification { property2: Pattern.compile('[0-9]{3}') ] when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(json) then: pathAndValues.find { it.method()== """.field("property2").matches("[0-9]{3}")""" && @@ -507,7 +507,7 @@ class JsonToJsonPathsConverterSpec extends Specification { property2: Pattern.compile('\\d+') ] when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(json) then: pathAndValues.find { it.method()== """.field("property2").matches("\\\\d+")""" && @@ -527,7 +527,7 @@ class JsonToJsonPathsConverterSpec extends Specification { ] ] when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(json) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(json) then: pathAndValues.find { it.method()== """.array("errors").contains("property").isEqualTo("bank_account_number")""" && @@ -563,7 +563,7 @@ class JsonToJsonPathsConverterSpec extends Specification { }] ''' when: - JsonPaths pathAndValues = JsonToJsonPathsConverter.transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) + JsonPaths pathAndValues = new JsonToJsonPathsConverter().transformToJsonPathWithTestsSideValues(new JsonSlurper().parseText(json)) then: pathAndValues.find { it.method()== """.array().field("place").field("bounding_box").array("coordinates").array().arrayField().isEqualTo(38.995548)""" && From 7df32f7a45437f078934a197a5bc60e0085f9fc8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 6 Jul 2016 16:05:04 +0200 Subject: [PATCH 715/719] Updated docs --- docs/src/main/asciidoc/contract.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc index 450319ffd9..ab54b6e2d1 100644 --- a/docs/src/main/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -34,7 +34,7 @@ WARNING: Spring Cloud Contract Verifier supports equality check on text response WARNING: The support for the verification of size of JSON arrays is experimental. If you want to turn it on please provide the value of a system property `spring.cloud.contract.verifier.assert.size` equal to `turn`. By default this feature is -`off`. +`off`. You can also provide the `assertJsonSize` property in the DSL configuration. === HTTP Top-Level Elements From 0f2ed2ca00bd47866baa9d12e29b5de0a417a7c8 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 6 Jul 2016 16:06:56 +0200 Subject: [PATCH 716/719] Updated docs --- docs/src/main/asciidoc/contract.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc index ab54b6e2d1..dff21c5ed5 100644 --- a/docs/src/main/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -34,7 +34,7 @@ WARNING: Spring Cloud Contract Verifier supports equality check on text response WARNING: The support for the verification of size of JSON arrays is experimental. If you want to turn it on please provide the value of a system property `spring.cloud.contract.verifier.assert.size` equal to `turn`. By default this feature is -`off`. You can also provide the `assertJsonSize` property in the DSL configuration. +`off`. You can also provide the `assertJsonSize` property in the plugin configuration. === HTTP Top-Level Elements From c9c637ed95c252e76ed6876ab879cee2fec96e52 Mon Sep 17 00:00:00 2001 From: Marcin Grzejszczak Date: Wed, 6 Jul 2016 16:08:19 +0200 Subject: [PATCH 717/719] Updated docs --- docs/src/main/asciidoc/contract.adoc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/src/main/asciidoc/contract.adoc b/docs/src/main/asciidoc/contract.adoc index dff21c5ed5..a846910959 100644 --- a/docs/src/main/asciidoc/contract.adoc +++ b/docs/src/main/asciidoc/contract.adoc @@ -33,8 +33,8 @@ WARNING: Spring Cloud Contract Verifier doesn't support XML properly. Please use WARNING: Spring Cloud Contract Verifier supports equality check on text response. Regular expressions are not yet available. WARNING: The support for the verification of size of JSON arrays is experimental. If you want to turn it on please provide -the value of a system property `spring.cloud.contract.verifier.assert.size` equal to `turn`. By default this feature is -`off`. You can also provide the `assertJsonSize` property in the plugin configuration. +the value of a system property `spring.cloud.contract.verifier.assert.size` equal to `true`. By default this feature is set to +`false`. You can also provide the `assertJsonSize` property in the plugin configuration. === HTTP Top-Level Elements From 6e397a6e5e8c6f0242bc5bb0cf596096b22f2a5c Mon Sep 17 00:00:00 2001 From: marcin Date: Fri, 8 Jul 2016 16:13:26 +0200 Subject: [PATCH 718/719] Moved code a bit --- .../target/stubs/contracts/Sample.groovy | 18 -------------- .../target/stubs/mappings/Sample.json | 22 ------------------ .../.gitignore | 0 .../.mvn}/codesigning.asc.enc | Bin .../.mvn}/wrapper/maven-wrapper.jar | Bin .../.mvn}/wrapper/maven-wrapper.properties | 0 .../.travis.yml | 0 .../LICENSE.md | 0 .../README.adoc | 0 .../docs}/pom.xml | 0 .../docs}/src/main/asciidoc/README.adoc | 0 ...-cloud-contract-verifier-maven-plugin.adoc | 0 .../docs}/src/main/ruby/generate_readme.sh | 0 .../mvnw | 0 .../mvnw.cmd | 0 .../pom.xml | 0 .../publishDocs.sh | 0 .../pom.xml | 0 .../src/etc/header.txt | 0 .../verifier/maven/CopyContracts.groovy | 0 .../verifier/maven/ManifestCreator.groovy | 0 .../AetherStubDownloaderFactory.groovy | 0 .../maven/stubrunner/LocalStubRunner.groovy | 0 .../maven/stubrunner/RemoteStubRunner.groovy | 0 .../contract/verifier/maven/ConvertMojo.java | 0 .../verifier/maven/GenerateStubsMojo.java | 0 .../verifier/maven/GenerateTestsMojo.java | 0 .../contract/verifier/maven/RunMojo.java | 0 .../resources/META-INF/plexus/components.xml | 0 .../src/site/asciidoc/complex-content.adoc | 0 .../src/site/asciidoc/complex.adoc | 0 .../src/site/asciidoc/index.adoc | 0 .../src/site/asciidoc/junit.adoc | 0 .../src/site/asciidoc/spock.adoc | 0 .../src/site/asciidoc/usage.adoc | 0 .../src/site/site.xml | 0 .../contract/verifier/maven/PluginIT.java | 0 .../verifier/maven/PluginUnitTest.java | 0 .../src/test/projects/basic/pom.xml | 0 .../test/resources/contracts/Messaging.groovy | 0 .../test/resources/contracts/Sample.groovy | 0 .../projects/complex-configuration/.gitignore | 0 .../projects/complex-configuration/pom.xml | 0 .../frauddetection/Application.java | 0 .../FraudDetectionController.java | 0 .../frauddetection/model/FraudCheck.java | 0 .../model/FraudCheckResult.java | 0 .../model/FraudCheckStatus.java | 0 .../src/test/contracts/brokenContract.groovy | 0 .../contracts/shouldMarkClientAsFraud.groovy | 0 .../shouldMarkClientAsNotFraud.groovy | 0 .../frauddetection/BaseAccurest.java | 0 .../matchers/CustomMatchers.java | 0 .../src/test/projects/generatedStubs/pom.xml | 0 .../test/projects/plugin-extension/pom.xml | 0 .../src/main/java/hello/Application.java | 0 .../src/main/java/hello/Greeting.java | 0 .../main/java/hello/GreetingController.java | 0 .../src/test/java/hello/BaseAccurest.java | 0 .../resources/contracts/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../src/test/projects/pomless/Sample.groovy | 0 .../test/projects/spring-boot-groovy/pom.xml | 0 .../src/main/java/hello/Application.java | 0 .../src/main/java/hello/Greeting.java | 0 .../main/java/hello/GreetingController.java | 0 .../src/test/groovy/hello/BaseAccurest.groovy | 0 .../resources/contracts/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../test/projects/spring-boot-java/pom.xml | 0 .../src/main/java/hello/Application.java | 0 .../src/main/java/hello/Greeting.java | 0 .../main/java/hello/GreetingController.java | 0 .../src/test/java/hello/BaseAccurest.java | 0 .../resources/contracts/greetings_ok.groovy | 0 .../greetings_with_default_value.groovy | 0 .../src/test/projects/withStubs/pom.xml | 0 .../src/test/resources/stubs/Sample.groovy | 0 78 files changed, 40 deletions(-) delete mode 100644 spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy delete mode 100644 spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/mappings/Sample.json rename .gitignore => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.gitignore (100%) rename {.mvn => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn}/codesigning.asc.enc (100%) rename {.mvn => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn}/wrapper/maven-wrapper.jar (100%) rename {.mvn => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn}/wrapper/maven-wrapper.properties (100%) rename .travis.yml => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.travis.yml (100%) rename LICENSE.md => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/LICENSE.md (100%) rename README.adoc => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/README.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs}/pom.xml (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs}/src/main/asciidoc/README.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs}/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs}/src/main/ruby/generate_readme.sh (100%) rename mvnw => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/mvnw (100%) rename mvnw.cmd => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/mvnw.cmd (100%) rename pom.xml => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/pom.xml (100%) rename publishDocs.sh => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/publishDocs.sh (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/pom.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/etc/header.txt (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/main/resources/META-INF/plexus/components.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/site/asciidoc/complex-content.adoc (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/site/asciidoc/complex.adoc (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/site/asciidoc/index.adoc (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/site/asciidoc/junit.adoc (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/site/asciidoc/spock.adoc (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/site/asciidoc/usage.adoc (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/site/site.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/basic/pom.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/basic/src/test/resources/contracts/Sample.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/.gitignore (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/pom.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/generatedStubs/pom.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/plugin-extension/pom.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/plugin-extension/src/main/java/hello/Application.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/pomless/Sample.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-groovy/pom.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-java/pom.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-java/src/main/java/hello/Application.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/withStubs/pom.xml (100%) rename {spring-cloud-contract-verifier-maven-plugin => spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin}/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy (100%) diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy deleted file mode 100644 index fb8ef5908e..0000000000 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/contracts/Sample.groovy +++ /dev/null @@ -1,18 +0,0 @@ -org.springframework.cloud.contract.spec.Contract.make { - request { - method 'POST' - url('/users') { - - } - headers { - header 'Content-Type': 'application/json' - } - body '''{ "login" : "john", "name": "John The Contract" }''' - } - response { - status 200 - headers { - header 'Location': '/users/john' - } - } -} \ No newline at end of file diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/mappings/Sample.json b/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/mappings/Sample.json deleted file mode 100644 index 6641a7d26f..0000000000 --- a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/target/stubs/mappings/Sample.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "request" : { - "url" : "/users", - "method" : "POST", - "bodyPatterns" : [ { - "matchesJsonPath" : "$[?(@.login == 'john')]" - }, { - "matchesJsonPath" : "$[?(@.name == 'John The Contract')]" - } ], - "headers" : { - "Content-Type" : { - "equalTo" : "application/json" - } - } - }, - "response" : { - "status" : 200, - "headers" : { - "Location" : "/users/john" - } - } -} \ No newline at end of file diff --git a/.gitignore b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.gitignore similarity index 100% rename from .gitignore rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.gitignore diff --git a/.mvn/codesigning.asc.enc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn/codesigning.asc.enc similarity index 100% rename from .mvn/codesigning.asc.enc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn/codesigning.asc.enc diff --git a/.mvn/wrapper/maven-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn/wrapper/maven-wrapper.jar similarity index 100% rename from .mvn/wrapper/maven-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn/wrapper/maven-wrapper.jar diff --git a/.mvn/wrapper/maven-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn/wrapper/maven-wrapper.properties similarity index 100% rename from .mvn/wrapper/maven-wrapper.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.mvn/wrapper/maven-wrapper.properties diff --git a/.travis.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.travis.yml similarity index 100% rename from .travis.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/.travis.yml diff --git a/LICENSE.md b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/LICENSE.md similarity index 100% rename from LICENSE.md rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/LICENSE.md diff --git a/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/README.adoc similarity index 100% rename from README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/README.adoc diff --git a/docs/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs/pom.xml similarity index 100% rename from docs/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs/pom.xml diff --git a/docs/src/main/asciidoc/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs/src/main/asciidoc/README.adoc similarity index 100% rename from docs/src/main/asciidoc/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs/src/main/asciidoc/README.adoc diff --git a/docs/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc similarity index 100% rename from docs/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs/src/main/asciidoc/spring-cloud-contract-verifier-maven-plugin.adoc diff --git a/docs/src/main/ruby/generate_readme.sh b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs/src/main/ruby/generate_readme.sh similarity index 100% rename from docs/src/main/ruby/generate_readme.sh rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/docs/src/main/ruby/generate_readme.sh diff --git a/mvnw b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/mvnw similarity index 100% rename from mvnw rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/mvnw diff --git a/mvnw.cmd b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/mvnw.cmd similarity index 100% rename from mvnw.cmd rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/mvnw.cmd diff --git a/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/pom.xml similarity index 100% rename from pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/pom.xml diff --git a/publishDocs.sh b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/publishDocs.sh similarity index 100% rename from publishDocs.sh rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/publishDocs.sh diff --git a/spring-cloud-contract-verifier-maven-plugin/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/pom.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/pom.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/etc/header.txt b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/etc/header.txt similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/etc/header.txt rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/etc/header.txt diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/CopyContracts.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/ManifestCreator.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/AetherStubDownloaderFactory.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/LocalStubRunner.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/maven/stubrunner/RemoteStubRunner.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/ConvertMojo.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateStubsMojo.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/GenerateTestsMojo.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/java/org/springframework/cloud/contract/verifier/maven/RunMojo.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/main/resources/META-INF/plexus/components.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/resources/META-INF/plexus/components.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/main/resources/META-INF/plexus/components.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/main/resources/META-INF/plexus/components.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex-content.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex-content.adoc similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex-content.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex-content.adoc diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex.adoc similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/complex.adoc diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/index.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/index.adoc similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/index.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/index.adoc diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/junit.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/junit.adoc similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/junit.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/junit.adoc diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/spock.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/spock.adoc similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/spock.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/spock.adoc diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/usage.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/usage.adoc similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/usage.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/asciidoc/usage.adoc diff --git a/spring-cloud-contract-verifier-maven-plugin/src/site/site.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/site.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/site/site.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/site/site.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginIT.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/java/org/springframework/cloud/contract/verifier/maven/PluginUnitTest.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/pom.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/pom.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Messaging.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/basic/src/test/resources/contracts/Sample.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/.gitignore b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/.gitignore similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/.gitignore rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/.gitignore diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/pom.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/pom.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/Application.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/FraudDetectionController.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheck.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckResult.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/main/java/com/blogspot/toomuchcoding/frauddetection/model/FraudCheckStatus.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/brokenContract.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsFraud.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/contracts/shouldMarkClientAsNotFraud.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/BaseAccurest.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/complex-configuration/src/test/java/com/blogspot/toomuchcoding/frauddetection/matchers/CustomMatchers.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/pom.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/generatedStubs/pom.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/pom.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/pom.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Application.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Application.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/Greeting.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/main/java/hello/GreetingController.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/java/hello/BaseAccurest.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_ok.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/plugin-extension/src/test/resources/contracts/greetings_with_default_value.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/pomless/Sample.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/pom.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Application.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/Greeting.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/main/java/hello/GreetingController.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/groovy/hello/BaseAccurest.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_ok.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-groovy/src/test/resources/contracts/greetings_with_default_value.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/pom.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/pom.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Application.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/Greeting.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/main/java/hello/GreetingController.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/java/hello/BaseAccurest.java diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_ok.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/spring-boot-java/src/test/resources/contracts/greetings_with_default_value.groovy diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/pom.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/pom.xml similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/pom.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/pom.xml diff --git a/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy similarity index 100% rename from spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier-maven-plugin/spring-cloud-contract-verifier-maven-plugin/src/test/projects/withStubs/src/test/resources/stubs/Sample.groovy From 4ee555cc32665634515d5d4a126ffac194e83426 Mon Sep 17 00:00:00 2001 From: marcin Date: Fri, 8 Jul 2016 16:11:42 +0200 Subject: [PATCH 719/719] Moved code a bit --- .../spring-cloud-contract-verifier/.gitignore | 0 .../spring-cloud-contract-verifier/.travis.yml | 0 .../spring-cloud-contract-verifier/LICENSE | 0 .../spring-cloud-contract-verifier/README.adoc | 0 .../spring-cloud-contract-verifier/asciidoctor.css | 0 .../spring-cloud-contract-verifier/build.gradle | 0 .../spring-cloud-contract-verifier/build.sh | 0 .../spring-cloud-contract-verifier/deploy.sh | 0 .../docs}/build.gradle | 0 .../docs}/src/main/asciidoc/README.adoc | 0 .../docs}/src/main/asciidoc/contract.adoc | 0 .../src/main/asciidoc/deprecated/contract.html | 0 .../src/main/asciidoc/deprecated/images/Deps.png | Bin .../src/main/asciidoc/deprecated/images/Stubs1.png | Bin .../src/main/asciidoc/deprecated/images/Stubs2.png | Bin .../docs}/src/main/asciidoc/deprecated/index.html | 0 .../src/main/asciidoc/deprecated/introduction.html | 0 .../src/main/asciidoc/deprecated/messaging.html | 0 .../src/main/asciidoc/deprecated/migration.html | 0 .../docs}/src/main/asciidoc/deprecated/rest.html | 0 .../src/main/asciidoc/deprecated/stubrunner.html | 0 .../main/asciidoc/deprecated/stubrunner_msg.html | 0 .../docs}/src/main/asciidoc/images/Deps.png | Bin .../docs}/src/main/asciidoc/images/Stubs1.png | Bin .../docs}/src/main/asciidoc/images/Stubs2.png | Bin .../docs}/src/main/asciidoc/index.adoc | 0 .../docs}/src/main/asciidoc/introduction.adoc | 0 .../docs}/src/main/asciidoc/links.adoc | 0 .../docs}/src/main/asciidoc/messaging.adoc | 0 .../docs}/src/main/asciidoc/rest.adoc | 0 .../asciidoc/spring-cloud-contract-verifier.adoc | 0 .../docs}/src/main/asciidoc/stubrunner.adoc | 0 .../docs}/src/main/asciidoc/stubrunner_msg.adoc | 0 .../docs}/src/main/ruby/generate_readme.sh | 0 .../generateReadme.sh | 0 .../gradle.properties | 0 .../gradle}/release.gradle | 0 .../gradle}/wrapper/gradle-wrapper.jar | Bin .../gradle}/wrapper/gradle-wrapper.properties | 0 .../spring-cloud-contract-verifier/gradlew | 0 .../spring-cloud-contract-verifier/gradlew.bat | 0 .../spring-cloud-contract-verifier/publishDocs.sh | 0 .../samples}/samples-messaging-camel/build.gradle | 0 .../verifier/samples/camel/BookDeleted.groovy | 0 .../verifier/samples/camel/BookDeleter.groovy | 0 .../verifier/samples/camel/BookReturned.groovy | 0 .../samples/camel/BookRouteConfiguration.groovy | 0 .../verifier/samples/camel/BookService.groovy | 0 .../samples/camel/CamelMessagingApplication.groovy | 0 .../camel/CamelMessagingApplicationSpec.groovy | 0 .../samples-messaging-integration/build.gradle | 0 .../verifier/samples/messaging/BookDeleted.groovy | 0 .../verifier/samples/messaging/BookListener.groovy | 0 .../verifier/samples/messaging/BookReturned.groovy | 0 .../verifier/samples/messaging/BookService.groovy | 0 .../IntegrationMessagingApplication.groovy | 0 .../src/main/resources/integration-context.xml | 0 .../IntegrationMessagingApplicationSpec.groovy | 0 .../samples}/samples-messaging-spring/build.gradle | 0 .../verifier/samples/spring/BookDeleted.groovy | 0 .../verifier/samples/spring/BookListener.groovy | 0 .../verifier/samples/spring/BookReturned.groovy | 0 .../verifier/samples/spring/BookService.groovy | 0 .../spring/SpringMessagingApplication.groovy | 0 .../samples/spring/SpringApplicationSpec.groovy | 0 .../ContractVerifierSpringMessageBuilder.groovy | 0 .../config/ContractVerifierSpringMessaging.groovy | 0 .../ManualContractVerifierConfiguration.groovy | 0 .../samples/spring/config/SpringMessage.groovy | 0 .../samples}/samples-messaging-stream/build.gradle | 0 .../verifier/samples/messaging/BookDeleted.groovy | 0 .../verifier/samples/messaging/BookListener.groovy | 0 .../verifier/samples/messaging/BookReturned.groovy | 0 .../verifier/samples/messaging/BookService.groovy | 0 .../verifier/samples/messaging/DeleteSink.groovy | 0 .../messaging/StreamMessagingApplication.groovy | 0 .../src/main/resources/application.yml | 0 .../messaging/StreamMessagingApplicationSpec.groovy | 0 .../scripts}/runTests.sh | 0 .../spring-cloud-contract-verifier/settings.gradle | 0 .../cloud/contract/spec/Contract.groovy | 0 .../contract/spec/ContractVerifierException.groovy | 0 .../cloud/contract/spec/internal/Body.groovy | 0 .../contract/spec/internal/ClientDslProperty.groovy | 0 .../cloud/contract/spec/internal/Common.groovy | 0 .../cloud/contract/spec/internal/DslProperty.groovy | 0 .../contract/spec/internal/ExecutionProperty.groovy | 0 .../cloud/contract/spec/internal/Header.groovy | 0 .../cloud/contract/spec/internal/Headers.groovy | 0 .../cloud/contract/spec/internal/Input.groovy | 0 .../contract/spec/internal/JSONCompareMode.groovy | 0 .../contract/spec/internal/MatchingStrategy.groovy | 0 .../cloud/contract/spec/internal/Multipart.groovy | 0 .../contract/spec/internal/NamedProperty.groovy | 0 .../contract/spec/internal/OptionalProperty.groovy | 0 .../contract/spec/internal/OutputMessage.groovy | 0 .../contract/spec/internal/QueryParameter.groovy | 0 .../contract/spec/internal/QueryParameters.groovy | 0 .../contract/spec/internal/RegexPatterns.groovy | 0 .../cloud/contract/spec/internal/Request.groovy | 0 .../cloud/contract/spec/internal/Response.groovy | 0 .../contract/spec/internal/ServerDslProperty.groovy | 0 .../cloud/contract/spec/internal/Url.groovy | 0 .../cloud/contract/spec/internal/UrlPath.groovy | 0 .../cloud/contract/spec/util/ValidateUtils.groovy | 0 .../spec/internal/ExecutionPropertySpec.groovy | 0 .../contract/spec/internal/RegexPatternsSpec.groovy | 0 .../README.adoc | 0 .../build.gradle | 0 .../stubrunner/boot/HttpStubsController.groovy | 0 .../contract/stubrunner/boot/StubRunnerBoot.groovy | 0 .../stubrunner/boot/TriggerController.groovy | 0 .../src/main/resources/META-INF/spring.factories | 0 .../stubrunner/boot/StubRunnerBootSpec.groovy | 0 .../src/test/resources/application.yml | 0 .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin .../0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom | 0 .../verifier/stubs/streamService/maven-metadata.xml | 0 .../README.adoc | 0 .../build.gradle | 0 .../contract/stubrunner/junit/StubRunnerRule.java | 0 .../junit/StubRunnerRuleCustomPortJUnitTest.java | 0 .../stubrunner/junit/StubRunnerRuleJUnitTest.java | 0 .../stubrunner/junit/StubRunnerRuleSpec.groovy | 0 .../src/test/resources/logback.xml | 0 .../fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 0 .../stubs/fraudDetectionServer/maven-metadata.xml | 0 .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin .../0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom | 0 .../verifier/stubs/loanIssuance/maven-metadata.xml | 0 .../README.adoc | 0 .../build.gradle | 0 .../camel/StubRunnerCamelConfiguration.groovy | 0 .../messaging/camel/StubRunnerCamelPredicate.groovy | 0 .../messaging/camel/StubRunnerCamelProcessor.groovy | 0 .../src/main/resources/META-INF/spring.factories | 0 .../stubrunner/messaging/camel/BookReturned.groovy | 0 .../messaging/camel/CamelStubRunnerSpec.groovy | 0 .../camel/StubRunnerCamelProcessorSpec.groovy | 0 .../src/test/resources/application.yml | 0 .../camelService-0.0.1-SNAPSHOT-stubs.jar | Bin .../0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom | 0 .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 0 .../stubs/camelService/maven-metadata-local.xml | 0 .../verifier/stubs/camelService/maven-metadata.xml | 0 .../README.adoc | 0 .../build.gradle | 0 .../StubRunnerIntegrationConfiguration.groovy | 0 .../StubRunnerIntegrationMessageSelector.groovy | 0 .../StubRunnerIntegrationTransformer.groovy | 0 .../src/main/resources/META-INF/spring.factories | 0 .../messaging/integration/BookReturned.groovy | 0 .../integration/IntegrationStubRunnerSpec.groovy | 0 .../StubRunnerIntegrationTransformerSpec.groovy | 0 .../src/test/resources/application.yml | 0 .../src/test/resources/integration-context.xml | 0 .../integrationService-0.0.1-SNAPSHOT-stubs.jar | Bin .../integrationService-0.0.1-SNAPSHOT.pom | 0 .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 0 .../integrationService/maven-metadata-local.xml | 0 .../stubs/integrationService/maven-metadata.xml | 0 .../README.adoc | 0 .../build.gradle | 0 .../stream/StubRunnerStreamConfiguration.groovy | 0 .../stream/StubRunnerStreamMessageSelector.groovy | 0 .../stream/StubRunnerStreamTransformer.groovy | 0 .../src/main/resources/META-INF/spring.factories | 0 .../stubrunner/messaging/stream/BookReturned.groovy | 0 .../messaging/stream/StreamStubRunnerSpec.groovy | 0 .../stream/StubRunnerStreamTransformerSpec.groovy | 0 .../src/test/resources/application.yml | 0 .../0.0.1-SNAPSHOT/maven-metadata-local.xml | 0 .../streamService-0.0.1-SNAPSHOT-stubs.jar | Bin .../0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom | 0 .../stubs/streamService/maven-metadata-local.xml | 0 .../verifier/stubs/streamService/maven-metadata.xml | 0 .../README.adoc | 0 .../build.gradle | 0 .../spring/cloud/StubMapperProperties.java | 0 .../spring/cloud/StubRunnerDiscoveryClient.java | 0 .../spring/cloud/StubRunnerServiceInstance.java | 0 .../StubRunnerSpringCloudAutoConfiguration.java | 0 .../ribbon/StubRunnerRibbonAutoConfiguration.java | 0 .../ribbon/StubRunnerRibbonBeanPostProcessor.java | 0 .../cloud/ribbon/StubRunnerRibbonConfiguration.java | 0 .../cloud/ribbon/StubRunnerRibbonServerList.java | 0 .../src/main/resources/META-INF/spring.factories | 0 ...tubRunnerSpringCloudAutoConfigurationSpec.groovy | 0 .../src/test/resources/application.yml | 0 .../src/test/resources/logback.xml | 0 .../fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 0 .../stubs/fraudDetectionServer/maven-metadata.xml | 0 .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin .../0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom | 0 .../verifier/stubs/loanIssuance/maven-metadata.xml | 0 .../README.adoc | 0 .../build.gradle | 0 .../stubrunner/spring/StubRunnerConfiguration.java | 0 .../src/main/resources/META-INF/spring.factories | 0 .../spring/StubRunnerConfigurationSpec.groovy | 0 .../src/test/resources/application.yml | 0 .../src/test/resources/logback.xml | 0 .../fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar | Bin .../fraudDetectionServer-0.0.1-SNAPSHOT.pom | 0 .../stubs/fraudDetectionServer/maven-metadata.xml | 0 .../loanIssuance-0.0.1-SNAPSHOT-stubs.jar | Bin .../0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom | 0 .../verifier/stubs/loanIssuance/maven-metadata.xml | 0 .../spring-cloud-contract-stub-runner/README.adoc | 0 .../spring-cloud-contract-stub-runner/build.gradle | 0 .../contract/stubrunner/AetherFactories.groovy | 0 .../contract/stubrunner/AetherStubDownloader.groovy | 0 .../cloud/contract/stubrunner/Arguments.groovy | 0 .../contract/stubrunner/AvailablePortScanner.groovy | 0 .../contract/stubrunner/BatchStubRunner.groovy | 0 .../stubrunner/BatchStubRunnerFactory.groovy | 0 .../contract/stubrunner/GroovyDslWrapper.groovy | 0 .../stubrunner/MessageNotMatchingException.groovy | 0 .../cloud/contract/stubrunner/RunningStubs.groovy | 0 .../contract/stubrunner/StubConfiguration.groovy | 0 .../cloud/contract/stubrunner/StubData.groovy | 0 .../cloud/contract/stubrunner/StubDownloader.groovy | 0 .../cloud/contract/stubrunner/StubFinder.groovy | 0 .../cloud/contract/stubrunner/StubRepository.groovy | 0 .../cloud/contract/stubrunner/StubRunner.groovy | 0 .../contract/stubrunner/StubRunnerExecutor.groovy | 0 .../contract/stubrunner/StubRunnerFactory.groovy | 0 .../cloud/contract/stubrunner/StubRunnerMain.groovy | 0 .../stubrunner/StubRunnerMessagingTrigger.groovy | 0 .../contract/stubrunner/StubRunnerOptions.groovy | 0 .../stubrunner/StubRunnerOptionsBuilder.groovy | 0 .../cloud/contract/stubrunner/StubRunning.groovy | 0 .../cloud/contract/stubrunner/StubServer.groovy | 0 .../cloud/contract/stubrunner/StubTrigger.groovy | 0 .../stubrunner/WiremockMappingDescriptor.groovy | 0 .../contract/stubrunner/util/StringUtils.groovy | 0 .../contract/stubrunner/util/StubsParser.groovy | 0 .../contract/stubrunner/util/ZipCategory.groovy | 0 .../resources/accurestStubrunnerGrapeConfig.xml | 0 .../stubrunner/AvailablePortScannerSpec.groovy | 0 .../contract/stubrunner/BatchStubRunnerSpec.groovy | 0 .../stubrunner/MappingDescriptorSpec.groovy | 0 .../contract/stubrunner/RunningStubsSpec.groovy | 0 .../stubrunner/StubConfigurationSpec.groovy | 0 .../contract/stubrunner/StubRepositorySpec.groovy | 0 .../stubrunner/StubRunnerExecutorSpec.groovy | 0 .../stubrunner/StubRunnerFactorySpec.groovy | 0 .../stubrunner/StubRunnerOptionsBuilderSpec.groovy | 0 .../cloud/contract/stubrunner/StubRunnerSpec.groovy | 0 .../cloud/contract/stubrunner/StubServerSpec.groovy | 0 .../contract/stubrunner/util/ZipCategorySpec.groovy | 0 .../mappings/spring/cloud/bar/bar.json | 0 .../mappings/spring/cloud/foo/bar/foobar.json | 0 .../mappings/spring/cloud/foo/foo.json | 0 .../anotherRepository/projects/brokers/brokers.json | 0 .../projects/brokers/nested/anotherDescriptor.json | 0 .../anotherRepository/projects/descriptor.json | 0 .../src/test/resources/emptyrepo/.gitkeep | 0 .../src/test/resources/file.zip | Bin .../src/test/resources/logback.xml | 0 .../resources/repository/contracts/contract1.groovy | 0 .../mappings/lv/spring/cloud/bye/lv_bye.json | 0 .../mappings/pl/spring/cloud/bye/pl_bye.json | 0 .../pl/spring/cloud/bye/pl_overridden_bye.json | 0 .../mappings/spring/cloud/bye/admin/admin.json | 0 .../repository/mappings/spring/cloud/bye/bye.json | 0 .../mappings/spring/cloud/hello/README.md | 0 .../mappings/spring/cloud/hello/admin/admin.json | 0 .../mappings/spring/cloud/hello/hello.json | 0 .../repository/mappings/spring/cloud/ping/ping.json | 0 .../spring-cloud-contract-verifier}/build.gradle | 0 .../src/main/groovy/nl/flotsam/xeger/Xeger.java | 0 .../verifier/converter/SingleFileConverter.groovy | 0 .../ConversionContractVerifierException.groovy | 0 .../wiremock/DslToWireMockClientConverter.groovy | 0 .../verifier/wiremock/DslToWireMockConverter.groovy | 0 .../wiremock/RecursiveFilesConverter.groovy | 0 .../verifier/wiremock/WireMockToDslConverter.groovy | 0 .../src/test/groovy/nl/flotsam/xeger/XegerTest.java | 0 .../groovy/nl/flotsam/xeger/XegerUtilsTest.java | 0 .../DslToWireMockClientConverterSpec.groovy | 0 .../wiremock/RecursiveFilesConverterSpec.groovy | 0 .../wiremock/WireMockToDslConverterSpec.groovy | 0 .../wiremock/WiremockScenarioConverterSpec.groovy | 0 .../scenario/main_scenario/01_login.groovy | 0 .../scenario/main_scenario/02_showCart.groovy | 0 .../scenario/main_scenario/03_logout.groovy | 0 .../resources/converter/source/dir1/dsl1.groovy | 0 .../resources/converter/source/dir1/dsl1b.groovy | 0 .../resources/converter/source/dir2/dsl2.groovy | 0 .../test/resources/converter/source/dslRoot.groovy | 0 .../cloud/contract/verifier/FileSaver.groovy | 0 .../cloud/contract/verifier/TestGenerator.groovy | 0 .../contract/verifier/builder/BlockBuilder.groovy | 0 .../contract/verifier/builder/ClassBuilder.groovy | 0 .../builder/JUnitMessagingMethodBodyBuilder.groovy | 0 .../verifier/builder/JUnitMethodBodyBuilder.groovy | 0 .../JaxRsClientJUnitMethodBodyBuilder.groovy | 0 ...ntSpockMethodRequestProcessingBodyBuilder.groovy | 0 .../builder/MessagingMethodBodyBuilder.groovy | 0 .../verifier/builder/MethodBodyBuilder.groovy | 0 .../contract/verifier/builder/MethodBuilder.groovy | 0 .../builder/MockMvcJUnitMethodBodyBuilder.groovy | 0 ...vcSpockMethodRequestProcessingBodyBuilder.groovy | 0 .../RequestProcessingMethodBodyBuilder.groovy | 0 .../verifier/builder/SingleTestGenerator.groovy | 0 .../builder/SpockMessagingMethodBodyBuilder.groovy | 0 .../SpockMethodRequestProcessingBodyBuilder.groovy | 0 .../config/ContractVerifierConfigProperties.groovy | 0 .../contract/verifier/config/TestFramework.groovy | 0 .../cloud/contract/verifier/config/TestMode.groovy | 0 .../dsl/wiremock/BaseWireMockStubStrategy.groovy | 0 .../dsl/wiremock/WireMockRequestStubStrategy.groovy | 0 .../wiremock/WireMockResponseStubStrategy.groovy | 0 .../dsl/wiremock/WireMockStubStrategy.groovy | 0 .../verifier/file/ContractFileScanner.groovy | 0 .../contract/verifier/file/ContractMetadata.groovy | 0 .../contract/verifier/util/BodyExtractor.groovy | 0 .../cloud/contract/verifier/util/ContentType.groovy | 0 .../contract/verifier/util/ContentUtils.groovy | 0 .../util/ContractVerifierDslConverter.groovy | 0 .../verifier/util/DelegatingJsonVerifiable.java | 0 .../util/FinishedDelegatingJsonVerifiable.java | 0 .../cloud/contract/verifier/util/JsonPaths.groovy | 0 .../verifier/util/JsonToJsonPathsConverter.groovy | 0 .../contract/verifier/util/MapConverter.groovy | 0 .../contract/verifier/util/MethodBuffering.java | 0 .../util/MethodBufferingJsonVerifiable.java | 0 .../cloud/contract/verifier/util/NamesUtil.groovy | 0 .../contract/verifier/util/RegexpBuilders.groovy | 0 .../contract/verifier/util/ShouldTraverse.java | 0 .../resources/stubs/wiremocks/other/sample.json | 0 .../src/main/resources/stubs/wiremocks/sample.json | 0 .../contract/verifier/GeneratorScannerSpec.groovy | 0 .../cloud/contract/verifier/MainTest.groovy | 0 .../contract/verifier/builder/BookReturned.groovy | 0 .../verifier/builder/ContractHttpDocsSpec.groovy | 0 .../builder/JaxRsClientMethodBuilderSpec.groovy | 0 .../builder/MessagingMethodBodyBuilderSpec.groovy | 0 .../builder/MockMvcMethodBodyBuilderSpec.groovy | 0 .../verifier/builder/SingleTestGeneratorSpec.groovy | 0 .../verifier/dsl/WireMockGroovyDslSpec.groovy | 0 .../verifier/dsl/WireMockStubVerifier.groovy | 0 .../dsl/internal/ExecutionPropertySpec.groovy | 0 .../verifier/dsl/internal/RegexPatternsSpec.groovy | 0 .../verifier/file/ContractFileScannerSpec.groovy | 0 .../util/JsonToJsonPathsConverterSpec.groovy | 0 .../directory/with/scenario/01_login.groovy | 0 .../directory/with/scenario/02_showCart.groovy | 0 .../directory/with/scenario/03_logout.groovy | 0 .../directory/with/stubs/different/diff.groovy | 0 .../with/stubs/other/different/diff.groovy | 0 .../directory/with/stubs/other/other.groovy | 0 .../directory/with/stubs/other/sample.groovy | 0 .../with/stubs/package/exceptions/test.groovy | 0 .../with/stubs/package/v1/exceptions/testv1.groovy | 0 .../with/stubs/package/v2/exceptions/testv2.groovy | 0 .../directory/with/stubs/stubsRepositoryIndicator | 0 .../src/test/resources/dsl/basic/sampleDsl.groovy | 0 .../src/test/resources/main.json | 0 .../strange_[3.3.3]_directory/02_login.groovy | 0 .../strange_[3.3.3]_directory/bar/03_login.groovy | 0 .../strange_[3.3.3]_directory/foo/01_login.groovy | 0 .../verifier/plugin/GenerateServerTestsTask.groovy | 0 .../GenerateWireMockClientStubsFromDslTask.groovy | 0 .../SpringCloudContractVerifierGradlePlugin.groovy | 0 .../gradle-plugins/contract-verifier.properties | 0 .../verifier/plugin/BasicFunctionalSpec.groovy | 0 .../plugin/ContractVerifierIntegrationSpec.groovy | 0 .../verifier/plugin/MessagingProjectSpec.groovy | 0 .../verifier/plugin/SampleJerseyProjectSpec.groovy | 0 .../verifier/plugin/SampleProjectSpec.groovy | 0 .../verifier/plugin/ScenarioProjectSpec.groovy | 0 .../functionalTest/bootSimple/build.gradle | 0 .../functionalTest/bootSimple/gradle.properties | 0 .../bootSimple/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../resources/functionalTest/bootSimple/gradlew | 0 .../resources/functionalTest/bootSimple/gradlew.bat | 0 .../pairId/collerate_PlacesFrom_Tweet.groovy | 0 .../pairId/moreComplexVersion.groovy | 0 .../functionalTest/bootSimple/settings.gradle | 0 .../cloud/twitter/place/PairIdController.groovy | 0 .../springframework/cloud/twitter/place/Tweet.java | 0 .../verifier/twitter/places/AcceptanceSpec.groovy | 0 .../verifier/twitter/places/BaseMockMvcSpec.groovy | 0 .../src/test/resources/logback-test.groovy | 0 .../functionalTest/messagingProject/build.gradle | 0 .../messagingProject/gradle.properties | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../functionalTest/messagingProject/gradlew | 0 .../functionalTest/messagingProject/gradlew.bat | 0 .../repository/mappings/a_foo.groovy | 0 .../repository/mappings/bookDeleted.groovy | 0 .../repository/mappings/bookReturned1.groovy | 0 .../repository/mappings/bookReturned2.groovy | 0 .../functionalTest/messagingProject/settings.gradle | 0 .../cloud/samples/book/BookDeleted.groovy | 0 .../cloud/samples/book/BookListener.groovy | 0 .../cloud/samples/book/BookReturned.groovy | 0 .../cloud/samples/book/BookService.groovy | 0 .../book/IntegrationMessagingApplication.groovy | 0 .../src/main/resources/integration-context.xml | 0 .../cloud/samples/book/MessagingBaseSpec.groovy | 0 .../cloud/samples/book/MessagingBaseTest.java | 0 .../functionalTest/sampleJerseyProject/build.gradle | 0 .../shouldMarkClientAsFraud.groovy | 0 .../shouldMarkClientAsNotFraud.groovy | 0 .../cloud/frauddetection/Application.java | 0 .../frauddetection/FraudDetectionController.java | 0 .../cloud/frauddetection/FraudRestApplication.java | 0 .../cloud/frauddetection/model/FraudCheck.java | 0 .../frauddetection/model/FraudCheckResult.java | 0 .../frauddetection/model/FraudCheckStatus.java | 0 .../src/main/resources/application.yml | 0 .../groovy/org/springframework/cloud/MvcSpec.groovy | 0 .../java/org/springframework/cloud/MvcTest.java | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../functionalTest/sampleJerseyProject/gradlew | 0 .../functionalTest/sampleJerseyProject/gradlew.bat | 0 .../loanApplicationService/mappings/.gitkeep | 0 .../cloud/frauddetection/Application.java | 0 .../frauddetection/LoanApplicationService.java | 0 .../cloud/frauddetection/model/Client.java | 0 .../frauddetection/model/FraudCheckStatus.java | 0 .../frauddetection/model/FraudServiceRequest.java | 0 .../frauddetection/model/FraudServiceResponse.java | 0 .../cloud/frauddetection/model/LoanApplication.java | 0 .../frauddetection/model/LoanApplicationResult.java | 0 .../frauddetection/model/LoanApplicationStatus.java | 0 .../src/main/resources/application.yml | 0 .../cloud/LoanApplicationServiceSpec.groovy | 0 .../shouldMarkClientAsFraud.json | 0 .../shouldMarkClientAsNotFraud.json | 0 .../sampleJerseyProject/settings.gradle | 0 .../functionalTest/sampleProject/build.gradle | 0 .../shouldMarkClientAsFraud.groovy | 0 .../shouldMarkClientAsNotFraud.groovy | 0 .../springframework/frauddetection/Application.java | 0 .../frauddetection/FraudDetectionController.java | 0 .../frauddetection/model/FraudCheck.java | 0 .../frauddetection/model/FraudCheckResult.java | 0 .../frauddetection/model/FraudCheckStatus.java | 0 .../src/main/resources/application.yml | 0 .../groovy/org/springframework/cloud/MvcSpec.groovy | 0 .../java/org/springframework/cloud/MvcTest.java | 0 .../sampleProject/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../resources/functionalTest/sampleProject/gradlew | 0 .../functionalTest/sampleProject/gradlew.bat | 0 .../loanApplicationService/mappings/.gitkeep | 0 .../cloud/frauddetection/Application.java | 0 .../frauddetection/LoanApplicationService.java | 0 .../cloud/frauddetection/model/Client.java | 0 .../frauddetection/model/FraudCheckStatus.java | 0 .../frauddetection/model/FraudServiceRequest.java | 0 .../frauddetection/model/FraudServiceResponse.java | 0 .../cloud/frauddetection/model/LoanApplication.java | 0 .../frauddetection/model/LoanApplicationResult.java | 0 .../frauddetection/model/LoanApplicationStatus.java | 0 .../src/main/resources/application.yml | 0 .../cloud/LoanApplicationServiceSpec.groovy | 0 .../shouldMarkClientAsFraud.json | 0 .../shouldMarkClientAsNotFraud.json | 0 .../functionalTest/sampleProject/settings.gradle | 0 .../functionalTest/scenarioProject/build.gradle | 0 .../1_shouldMarkClientAsNotFraud.groovy | 0 .../2_shouldMarkClientAsFraud.groovy | 0 .../cloud/frauddetection/Application.java | 0 .../frauddetection/FraudDetectionController.java | 0 .../cloud/frauddetection/model/FraudCheck.java | 0 .../frauddetection/model/FraudCheckResult.java | 0 .../frauddetection/model/FraudCheckStatus.java | 0 .../src/main/resources/application.yml | 0 .../groovy/org/springframework/cloud/MvcSpec.groovy | 0 .../java/org/springframework/cloud/MvcTest.java | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../functionalTest/scenarioProject/gradlew | 0 .../functionalTest/scenarioProject/gradlew.bat | 0 .../loanApplicationService/mappings/.gitkeep | 0 .../cloud/frauddetection/Application.java | 0 .../frauddetection/LoanApplicationService.java | 0 .../cloud/frauddetection/model/Client.java | 0 .../frauddetection/model/FraudCheckStatus.java | 0 .../frauddetection/model/FraudServiceRequest.java | 0 .../frauddetection/model/FraudServiceResponse.java | 0 .../cloud/frauddetection/model/LoanApplication.java | 0 .../frauddetection/model/LoanApplicationResult.java | 0 .../frauddetection/model/LoanApplicationStatus.java | 0 .../src/main/resources/application.yml | 0 .../cloud/LoanApplicationServiceSpec.groovy | 0 .../shouldMarkClientAsFraud.json | 0 .../shouldMarkClientAsNotFraud.json | 0 .../functionalTest/scenarioProject/settings.gradle | 0 .../README.adoc | 0 .../build.gradle | 0 .../verifier/messaging/camel/CamelMessage.java | 0 .../camel/ContractVerifierCamelConfiguration.java | 0 .../camel/ContractVerifierCamelMessageBuilder.java | 0 .../camel/ContractVerifierCamelMessaging.java | 0 .../src/main/resources/META-INF/spring.factories | 0 .../build.gradle | 0 .../ContractVerifierIntegrationConfiguration.java | 0 .../ContractVerifierIntegrationMessageBuilder.java | 0 .../ContractVerifierIntegrationMessaging.java | 0 .../messaging/integration/IntegrationMessage.java | 0 .../src/main/resources/META-INF/spring.factories | 0 .../build.gradle | 0 .../verifier/messaging/ContractVerifierFilter.java | 0 .../verifier/messaging/ContractVerifierMessage.java | 0 .../messaging/ContractVerifierMessageBuilder.java | 0 .../messaging/ContractVerifierMessaging.java | 0 .../messaging/ContractVerifierMessagingUtil.java | 0 .../messaging/ContractVerifierObjectMapper.java | 0 .../messaging/noop/NoOpContractVerifierMessage.java | 0 .../noop/NoOpContractVerifierMessageBuilder.java | 0 .../noop/NoOpContractVerifierMessaging.java | 0 .../build.gradle | 0 .../ContractVerifierStreamAutoConfiguration.java | 0 .../ContractVerifierStreamMessageBuilder.java | 0 .../stream/ContractVerifierStreamMessaging.java | 0 .../verifier/messaging/stream/StreamMessage.java | 0 .../src/main/resources/META-INF/spring.factories | 0 .../contract/verifier/util/AssertionUtil.groovy | 0 529 files changed, 0 insertions(+), 0 deletions(-) rename .gitignore => spring-cloud-contract-verifier/spring-cloud-contract-verifier/.gitignore (100%) rename .travis.yml => spring-cloud-contract-verifier/spring-cloud-contract-verifier/.travis.yml (100%) rename LICENSE => spring-cloud-contract-verifier/spring-cloud-contract-verifier/LICENSE (100%) rename README.adoc => spring-cloud-contract-verifier/spring-cloud-contract-verifier/README.adoc (100%) rename asciidoctor.css => spring-cloud-contract-verifier/spring-cloud-contract-verifier/asciidoctor.css (100%) rename build.gradle => spring-cloud-contract-verifier/spring-cloud-contract-verifier/build.gradle (100%) rename build.sh => spring-cloud-contract-verifier/spring-cloud-contract-verifier/build.sh (100%) rename deploy.sh => spring-cloud-contract-verifier/spring-cloud-contract-verifier/deploy.sh (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/build.gradle (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/README.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/contract.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/contract.html (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/images/Deps.png (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/images/Stubs1.png (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/images/Stubs2.png (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/index.html (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/introduction.html (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/messaging.html (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/migration.html (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/rest.html (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/stubrunner.html (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/deprecated/stubrunner_msg.html (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/images/Deps.png (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/images/Stubs1.png (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/images/Stubs2.png (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/index.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/introduction.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/links.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/messaging.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/rest.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/spring-cloud-contract-verifier.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/stubrunner.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/asciidoc/stubrunner_msg.adoc (100%) rename {docs => spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs}/src/main/ruby/generate_readme.sh (100%) rename generateReadme.sh => spring-cloud-contract-verifier/spring-cloud-contract-verifier/generateReadme.sh (100%) rename gradle.properties => spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle.properties (100%) rename {gradle => spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle}/release.gradle (100%) rename {gradle => spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle}/wrapper/gradle-wrapper.jar (100%) rename {gradle => spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle}/wrapper/gradle-wrapper.properties (100%) rename gradlew => spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradlew (100%) rename gradlew.bat => spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradlew.bat (100%) rename publishDocs.sh => spring-cloud-contract-verifier/spring-cloud-contract-verifier/publishDocs.sh (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-camel/build.gradle (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleter.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookRouteConfiguration.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookService.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-integration/build.gradle (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-integration/src/main/resources/integration-context.xml (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/build.gradle (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookListener.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookService.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/SpringMessage.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/build.gradle (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/src/main/resources/application.yml (100%) rename {samples => spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples}/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy (100%) rename {scripts => spring-cloud-contract-verifier/spring-cloud-contract-verifier/scripts}/runTests.sh (100%) rename settings.gradle => spring-cloud-contract-verifier/spring-cloud-contract-verifier/settings.gradle (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/Contract.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/ContractVerifierException.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/ClientDslProperty.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Common.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/ExecutionProperty.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Header.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Headers.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Input.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/JSONCompareMode.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/MatchingStrategy.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Multipart.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/NamedProperty.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameter.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameters.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/RegexPatterns.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/ServerDslProperty.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/internal/UrlPath.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/main/groovy/org/springframework/cloud/contract/spec/util/ValidateUtils.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy (100%) rename {spring-cloud-contract-spec => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec}/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/README.adoc (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/build.gradle (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/HttpStubsController.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/TriggerController.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/main/resources/META-INF/spring.factories (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/README.adoc (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/build.gradle (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/README.adoc (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/build.gradle (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerServiceInstance.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/application.yml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/README.adoc (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/build.gradle (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/main/resources/META-INF/spring.factories (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/README.adoc (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/build.gradle (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherFactories.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScanner.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/RunningStubs.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubConfiguration.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMain.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StringUtils.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StubsParser.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategory.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScannerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/RunningStubsSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRepositorySpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/bar/bar.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/bar/foobar.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/foo.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/emptyrepo/.gitkeep (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/file.zip (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/logback.xml (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/lv/spring/cloud/bye/lv_bye.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_bye.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_overridden_bye.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/admin/admin.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/bye.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/README.md (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/admin/admin.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/hello.json (100%) rename {spring-cloud-contract-stub-runner => spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner}/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/ping/ping.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WiremockScenarioConverterSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/FileSaver.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/BlockBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ClassBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestFramework.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/other/sample.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/sample.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/main.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookListener.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookService.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud/samples/book/MessagingBaseSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud/samples/book/MessagingBaseTest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/README.adoc (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories (100%) rename spring-cloud-contract-verifier/{ => spring-cloud-contract-verifier/spring-cloud-contract-verifier}/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy (100%) diff --git a/.gitignore b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/.gitignore similarity index 100% rename from .gitignore rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/.gitignore diff --git a/.travis.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/.travis.yml similarity index 100% rename from .travis.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/.travis.yml diff --git a/LICENSE b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/LICENSE similarity index 100% rename from LICENSE rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/LICENSE diff --git a/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/README.adoc similarity index 100% rename from README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/README.adoc diff --git a/asciidoctor.css b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/asciidoctor.css similarity index 100% rename from asciidoctor.css rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/asciidoctor.css diff --git a/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/build.gradle similarity index 100% rename from build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/build.gradle diff --git a/build.sh b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/build.sh similarity index 100% rename from build.sh rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/build.sh diff --git a/deploy.sh b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/deploy.sh similarity index 100% rename from deploy.sh rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/deploy.sh diff --git a/docs/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/build.gradle similarity index 100% rename from docs/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/build.gradle diff --git a/docs/src/main/asciidoc/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/README.adoc similarity index 100% rename from docs/src/main/asciidoc/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/README.adoc diff --git a/docs/src/main/asciidoc/contract.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/contract.adoc similarity index 100% rename from docs/src/main/asciidoc/contract.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/contract.adoc diff --git a/docs/src/main/asciidoc/deprecated/contract.html b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/contract.html similarity index 100% rename from docs/src/main/asciidoc/deprecated/contract.html rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/contract.html diff --git a/docs/src/main/asciidoc/deprecated/images/Deps.png b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/images/Deps.png similarity index 100% rename from docs/src/main/asciidoc/deprecated/images/Deps.png rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/images/Deps.png diff --git a/docs/src/main/asciidoc/deprecated/images/Stubs1.png b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/images/Stubs1.png similarity index 100% rename from docs/src/main/asciidoc/deprecated/images/Stubs1.png rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/images/Stubs1.png diff --git a/docs/src/main/asciidoc/deprecated/images/Stubs2.png b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/images/Stubs2.png similarity index 100% rename from docs/src/main/asciidoc/deprecated/images/Stubs2.png rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/images/Stubs2.png diff --git a/docs/src/main/asciidoc/deprecated/index.html b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/index.html similarity index 100% rename from docs/src/main/asciidoc/deprecated/index.html rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/index.html diff --git a/docs/src/main/asciidoc/deprecated/introduction.html b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/introduction.html similarity index 100% rename from docs/src/main/asciidoc/deprecated/introduction.html rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/introduction.html diff --git a/docs/src/main/asciidoc/deprecated/messaging.html b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/messaging.html similarity index 100% rename from docs/src/main/asciidoc/deprecated/messaging.html rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/messaging.html diff --git a/docs/src/main/asciidoc/deprecated/migration.html b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/migration.html similarity index 100% rename from docs/src/main/asciidoc/deprecated/migration.html rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/migration.html diff --git a/docs/src/main/asciidoc/deprecated/rest.html b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/rest.html similarity index 100% rename from docs/src/main/asciidoc/deprecated/rest.html rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/rest.html diff --git a/docs/src/main/asciidoc/deprecated/stubrunner.html b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/stubrunner.html similarity index 100% rename from docs/src/main/asciidoc/deprecated/stubrunner.html rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/stubrunner.html diff --git a/docs/src/main/asciidoc/deprecated/stubrunner_msg.html b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/stubrunner_msg.html similarity index 100% rename from docs/src/main/asciidoc/deprecated/stubrunner_msg.html rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/deprecated/stubrunner_msg.html diff --git a/docs/src/main/asciidoc/images/Deps.png b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/images/Deps.png similarity index 100% rename from docs/src/main/asciidoc/images/Deps.png rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/images/Deps.png diff --git a/docs/src/main/asciidoc/images/Stubs1.png b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/images/Stubs1.png similarity index 100% rename from docs/src/main/asciidoc/images/Stubs1.png rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/images/Stubs1.png diff --git a/docs/src/main/asciidoc/images/Stubs2.png b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/images/Stubs2.png similarity index 100% rename from docs/src/main/asciidoc/images/Stubs2.png rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/images/Stubs2.png diff --git a/docs/src/main/asciidoc/index.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/index.adoc similarity index 100% rename from docs/src/main/asciidoc/index.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/index.adoc diff --git a/docs/src/main/asciidoc/introduction.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/introduction.adoc similarity index 100% rename from docs/src/main/asciidoc/introduction.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/introduction.adoc diff --git a/docs/src/main/asciidoc/links.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/links.adoc similarity index 100% rename from docs/src/main/asciidoc/links.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/links.adoc diff --git a/docs/src/main/asciidoc/messaging.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/messaging.adoc similarity index 100% rename from docs/src/main/asciidoc/messaging.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/messaging.adoc diff --git a/docs/src/main/asciidoc/rest.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/rest.adoc similarity index 100% rename from docs/src/main/asciidoc/rest.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/rest.adoc diff --git a/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc similarity index 100% rename from docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/spring-cloud-contract-verifier.adoc diff --git a/docs/src/main/asciidoc/stubrunner.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/stubrunner.adoc similarity index 100% rename from docs/src/main/asciidoc/stubrunner.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/stubrunner.adoc diff --git a/docs/src/main/asciidoc/stubrunner_msg.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/stubrunner_msg.adoc similarity index 100% rename from docs/src/main/asciidoc/stubrunner_msg.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/asciidoc/stubrunner_msg.adoc diff --git a/docs/src/main/ruby/generate_readme.sh b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/ruby/generate_readme.sh similarity index 100% rename from docs/src/main/ruby/generate_readme.sh rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/docs/src/main/ruby/generate_readme.sh diff --git a/generateReadme.sh b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/generateReadme.sh similarity index 100% rename from generateReadme.sh rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/generateReadme.sh diff --git a/gradle.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle.properties similarity index 100% rename from gradle.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle.properties diff --git a/gradle/release.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle/release.gradle similarity index 100% rename from gradle/release.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle/release.gradle diff --git a/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle/wrapper/gradle-wrapper.jar diff --git a/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from gradle/wrapper/gradle-wrapper.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradle/wrapper/gradle-wrapper.properties diff --git a/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradlew similarity index 100% rename from gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradlew diff --git a/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradlew.bat similarity index 100% rename from gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/gradlew.bat diff --git a/publishDocs.sh b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/publishDocs.sh similarity index 100% rename from publishDocs.sh rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/publishDocs.sh diff --git a/samples/samples-messaging-camel/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/build.gradle similarity index 100% rename from samples/samples-messaging-camel/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/build.gradle diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy similarity index 100% rename from samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleted.groovy diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleter.groovy similarity index 100% rename from samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookDeleter.groovy diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy similarity index 100% rename from samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookReturned.groovy diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookRouteConfiguration.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookRouteConfiguration.groovy similarity index 100% rename from samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookRouteConfiguration.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookRouteConfiguration.groovy diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookService.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookService.groovy similarity index 100% rename from samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookService.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/BookService.groovy diff --git a/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy similarity index 100% rename from samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/main/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplication.groovy diff --git a/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy similarity index 100% rename from samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-camel/src/test/groovy/org/springframework/cloud/contract/verifier/samples/camel/CamelMessagingApplicationSpec.groovy diff --git a/samples/samples-messaging-integration/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/build.gradle similarity index 100% rename from samples/samples-messaging-integration/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/build.gradle diff --git a/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy similarity index 100% rename from samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy diff --git a/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy similarity index 100% rename from samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy diff --git a/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy similarity index 100% rename from samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy diff --git a/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy similarity index 100% rename from samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy diff --git a/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy similarity index 100% rename from samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplication.groovy diff --git a/samples/samples-messaging-integration/src/main/resources/integration-context.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/resources/integration-context.xml similarity index 100% rename from samples/samples-messaging-integration/src/main/resources/integration-context.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/main/resources/integration-context.xml diff --git a/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy similarity index 100% rename from samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-integration/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/IntegrationMessagingApplicationSpec.groovy diff --git a/samples/samples-messaging-spring/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/build.gradle similarity index 100% rename from samples/samples-messaging-spring/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/build.gradle diff --git a/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy similarity index 100% rename from samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookDeleted.groovy diff --git a/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookListener.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookListener.groovy similarity index 100% rename from samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookListener.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookListener.groovy diff --git a/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy similarity index 100% rename from samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookReturned.groovy diff --git a/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookService.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookService.groovy similarity index 100% rename from samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookService.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/BookService.groovy diff --git a/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy similarity index 100% rename from samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/main/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringMessagingApplication.groovy diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy similarity index 100% rename from samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/SpringApplicationSpec.groovy diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy similarity index 100% rename from samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessageBuilder.groovy diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy similarity index 100% rename from samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ContractVerifierSpringMessaging.groovy diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy similarity index 100% rename from samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/ManualContractVerifierConfiguration.groovy diff --git a/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/SpringMessage.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/SpringMessage.groovy similarity index 100% rename from samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/SpringMessage.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-spring/src/test/groovy/org/springframework/cloud/contract/verifier/samples/spring/config/SpringMessage.groovy diff --git a/samples/samples-messaging-stream/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/build.gradle similarity index 100% rename from samples/samples-messaging-stream/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/build.gradle diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy similarity index 100% rename from samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookDeleted.groovy diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy similarity index 100% rename from samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookListener.groovy diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy similarity index 100% rename from samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookReturned.groovy diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy similarity index 100% rename from samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/BookService.groovy diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy similarity index 100% rename from samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/DeleteSink.groovy diff --git a/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy similarity index 100% rename from samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplication.groovy diff --git a/samples/samples-messaging-stream/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/resources/application.yml similarity index 100% rename from samples/samples-messaging-stream/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/main/resources/application.yml diff --git a/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy similarity index 100% rename from samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/samples/samples-messaging-stream/src/test/groovy/org/springframework/cloud/contract/verifier/samples/messaging/StreamMessagingApplicationSpec.groovy diff --git a/scripts/runTests.sh b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/scripts/runTests.sh similarity index 100% rename from scripts/runTests.sh rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/scripts/runTests.sh diff --git a/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/settings.gradle similarity index 100% rename from settings.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/settings.gradle diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/Contract.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/Contract.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/Contract.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/Contract.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/ContractVerifierException.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/ContractVerifierException.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/ContractVerifierException.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/ContractVerifierException.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Body.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ClientDslProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ClientDslProperty.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ClientDslProperty.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ClientDslProperty.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Common.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Common.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Common.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Common.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/DslProperty.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ExecutionProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ExecutionProperty.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ExecutionProperty.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ExecutionProperty.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Header.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Header.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Header.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Header.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Headers.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Headers.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Headers.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Headers.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Input.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Input.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Input.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Input.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/JSONCompareMode.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/JSONCompareMode.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/JSONCompareMode.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/JSONCompareMode.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/MatchingStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/MatchingStrategy.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/MatchingStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/MatchingStrategy.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Multipart.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Multipart.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Multipart.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Multipart.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/NamedProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/NamedProperty.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/NamedProperty.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/NamedProperty.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OptionalProperty.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/OutputMessage.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameter.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameter.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameters.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameters.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameters.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/QueryParameters.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/RegexPatterns.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/RegexPatterns.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/RegexPatterns.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/RegexPatterns.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Request.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Response.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ServerDslProperty.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ServerDslProperty.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ServerDslProperty.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/ServerDslProperty.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/Url.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/UrlPath.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/UrlPath.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/UrlPath.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/internal/UrlPath.groovy diff --git a/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/util/ValidateUtils.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/util/ValidateUtils.groovy similarity index 100% rename from spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/util/ValidateUtils.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/main/groovy/org/springframework/cloud/contract/spec/util/ValidateUtils.groovy diff --git a/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy similarity index 100% rename from spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/ExecutionPropertySpec.groovy diff --git a/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy similarity index 100% rename from spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-spec/src/test/groovy/org/springframework/cloud/contract/spec/internal/RegexPatternsSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/README.adoc diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/build.gradle similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/build.gradle diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/HttpStubsController.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/HttpStubsController.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/HttpStubsController.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/HttpStubsController.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBoot.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/TriggerController.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/TriggerController.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/TriggerController.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/groovy/org/springframework/cloud/contract/stubrunner/boot/TriggerController.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/groovy/org/springframework/cloud/contract/stubrunner/boot/StubRunnerBootSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/application.yml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-boot/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/README.adoc similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/README.adoc diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/build.gradle similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/build.gradle diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/main/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRule.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/logback.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-junit/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/README.adoc diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/build.gradle diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelConfiguration.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelPredicate.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessor.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/BookReturned.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/CamelStubRunnerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/camel/StubRunnerCamelProcessorSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/application.yml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/camelService-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/0.0.1-SNAPSHOT/maven-metadata-local.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata-local.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-camel/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/camelService/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/README.adoc diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/build.gradle diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationConfiguration.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationMessageSelector.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformer.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/BookReturned.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/IntegrationStubRunnerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/integration/StubRunnerIntegrationTransformerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/application.yml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/integration-context.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/integrationService-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/0.0.1-SNAPSHOT/maven-metadata-local.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata-local.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-integration/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/integrationService/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/README.adoc diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/build.gradle diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamConfiguration.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamMessageSelector.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformer.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/BookReturned.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StreamStubRunnerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/groovy/org/springframework/cloud/contract/stubrunner/messaging/stream/StubRunnerStreamTransformerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/application.yml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/maven-metadata-local.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/0.0.1-SNAPSHOT/streamService-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata-local.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-messaging/spring-cloud-contract-stub-runner-stream/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/streamService/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/README.adoc similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/README.adoc diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/build.gradle diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubMapperProperties.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerDiscoveryClient.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerServiceInstance.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerServiceInstance.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerServiceInstance.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerServiceInstance.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfiguration.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonAutoConfiguration.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonBeanPostProcessor.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonConfiguration.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/ribbon/StubRunnerRibbonServerList.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/application.yml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/application.yml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/logback.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring-cloud/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/README.adoc similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/README.adoc diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/build.gradle similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/build.gradle diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfiguration.java diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/application.yml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/logback.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/0.0.1-SNAPSHOT/fraudDetectionServer-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/fraudDetectionServer/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT-stubs.jar diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/0.0.1-SNAPSHOT/loanIssuance-0.0.1-SNAPSHOT.pom diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner-spring/src/test/resources/m2repo/repository/org/springframework/cloud/contract/verifier/stubs/loanIssuance/maven-metadata.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/README.adoc similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/README.adoc diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/build.gradle similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/build.gradle diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherFactories.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherFactories.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherFactories.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherFactories.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AetherStubDownloader.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/Arguments.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScanner.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScanner.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScanner.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScanner.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunner.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerFactory.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/GroovyDslWrapper.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/MessageNotMatchingException.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/RunningStubs.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/RunningStubs.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/RunningStubs.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/RunningStubs.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubConfiguration.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubConfiguration.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubConfiguration.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubConfiguration.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubData.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubDownloader.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubFinder.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRepository.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunner.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutor.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactory.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMain.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMain.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMain.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMain.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerMessagingTrigger.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptions.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilder.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubRunning.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubServer.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/StubTrigger.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/WiremockMappingDescriptor.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StringUtils.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StringUtils.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StringUtils.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StringUtils.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StubsParser.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StubsParser.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StubsParser.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/StubsParser.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategory.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategory.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategory.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategory.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/main/resources/accurestStubrunnerGrapeConfig.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScannerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScannerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScannerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/AvailablePortScannerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/BatchStubRunnerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/MappingDescriptorSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/RunningStubsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/RunningStubsSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/RunningStubsSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/RunningStubsSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubConfigurationSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRepositorySpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRepositorySpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRepositorySpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRepositorySpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerExecutorSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerFactorySpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerOptionsBuilderSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubRunnerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/StubServerSpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/groovy/org/springframework/cloud/contract/stubrunner/util/ZipCategorySpec.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/bar/bar.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/bar/bar.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/bar/bar.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/bar/bar.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/bar/foobar.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/bar/foobar.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/bar/foobar.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/bar/foobar.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/foo.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/foo.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/foo.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/mappings/spring/cloud/foo/foo.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/brokers.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/brokers/nested/anotherDescriptor.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/anotherRepository/projects/descriptor.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/emptyrepo/.gitkeep b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/emptyrepo/.gitkeep similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/emptyrepo/.gitkeep rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/emptyrepo/.gitkeep diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/file.zip b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/file.zip similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/file.zip rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/file.zip diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/logback.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/logback.xml similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/logback.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/logback.xml diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/contracts/contract1.groovy diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/lv/spring/cloud/bye/lv_bye.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/lv/spring/cloud/bye/lv_bye.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/lv/spring/cloud/bye/lv_bye.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/lv/spring/cloud/bye/lv_bye.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_bye.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_bye.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_bye.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_bye.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_overridden_bye.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_overridden_bye.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_overridden_bye.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/pl/spring/cloud/bye/pl_overridden_bye.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/admin/admin.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/admin/admin.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/admin/admin.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/admin/admin.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/bye.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/bye.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/bye.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/bye/bye.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/README.md b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/README.md similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/README.md rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/README.md diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/admin/admin.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/admin/admin.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/admin/admin.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/admin/admin.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/hello.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/hello.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/hello.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/hello/hello.json diff --git a/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/ping/ping.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/ping/ping.json similarity index 100% rename from spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/ping/ping.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-stub-runner/spring-cloud-contract-stub-runner/src/test/resources/repository/mappings/spring/cloud/ping/ping.json diff --git a/spring-cloud-contract-verifier/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/nl/flotsam/xeger/Xeger.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/converter/SingleFileConverter.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/ConversionContractVerifierException.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverter.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockConverter.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverter.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/main/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverter.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerTest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/nl/flotsam/xeger/XegerUtilsTest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/DslToWireMockClientConverterSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/RecursiveFilesConverterSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WireMockToDslConverterSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WiremockScenarioConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WiremockScenarioConverterSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WiremockScenarioConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/groovy/org/springframework/cloud/contract/verifier/wiremock/WiremockScenarioConverterSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/01_login.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/02_showCart.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/scenario/main_scenario/03_logout.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir1/dsl1b.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dir2/dsl2.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-converters/src/test/resources/converter/source/dslRoot.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/FileSaver.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/FileSaver.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/FileSaver.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/FileSaver.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/TestGenerator.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/BlockBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/BlockBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/BlockBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/BlockBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ClassBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ClassBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ClassBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/ClassBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMessagingMethodBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JUnitMethodBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientJUnitMethodBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientSpockMethodRequestProcessingBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MethodBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcJUnitMethodBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcSpockMethodRequestProcessingBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/RequestProcessingMethodBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGenerator.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMessagingMethodBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/builder/SpockMethodRequestProcessingBodyBuilder.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/ContractVerifierConfigProperties.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestFramework.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestFramework.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestFramework.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestFramework.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/config/TestMode.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/BaseWireMockStubStrategy.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockRequestStubStrategy.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockResponseStubStrategy.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/dsl/wiremock/WireMockStubStrategy.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScanner.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/file/ContractMetadata.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/BodyExtractor.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentType.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContentUtils.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ContractVerifierDslConverter.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/DelegatingJsonVerifiable.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/FinishedDelegatingJsonVerifiable.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonPaths.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverter.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MapConverter.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBuffering.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/MethodBufferingJsonVerifiable.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/NamesUtil.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/RegexpBuilders.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/groovy/org/springframework/cloud/contract/verifier/util/ShouldTraverse.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/other/sample.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/other/sample.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/other/sample.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/other/sample.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/sample.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/sample.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/sample.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/main/resources/stubs/wiremocks/sample.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/GeneratorScannerSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/MainTest.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/BookReturned.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/ContractHttpDocsSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/JaxRsClientMethodBuilderSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MessagingMethodBodyBuilderSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/MockMvcMethodBodyBuilderSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/builder/SingleTestGeneratorSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockGroovyDslSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/WireMockStubVerifier.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/ExecutionPropertySpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/dsl/internal/RegexPatternsSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/file/ContractFileScannerSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/groovy/org/springframework/cloud/contract/verifier/util/JsonToJsonPathsConverterSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/01_login.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/02_showCart.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/scenario/03_logout.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/different/diff.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/different/diff.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/other.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/other/sample.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/exceptions/test.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v1/exceptions/testv1.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/package/v2/exceptions/testv2.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/directory/with/stubs/stubsRepositoryIndicator diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/dsl/basic/sampleDsl.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/main.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/main.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/main.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/main.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/02_login.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/bar/03_login.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-core/src/test/resources/strange_[3.3.3]_directory/foo/01_login.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateServerTestsTask.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/GenerateWireMockClientStubsFromDslTask.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/groovy/org/springframework/cloud/contract/verifier/plugin/SpringCloudContractVerifierGradlePlugin.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/main/resources/META-INF/gradle-plugins/contract-verifier.properties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/BasicFunctionalSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ContractVerifierIntegrationSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/MessagingProjectSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleJerseyProjectSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/SampleProjectSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/groovy/org/springframework/cloud/contract/verifier/plugin/ScenarioProjectSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle.properties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradle/wrapper/gradle-wrapper.properties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/gradlew.bat diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/collerate_PlacesFrom_Tweet.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/repository/mappings/spring/cloud/twitter-places-analyzer/pairId/moreComplexVersion.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/settings.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/PairIdController.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/main/groovy/org/springframework/cloud/twitter/place/Tweet.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/AcceptanceSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/groovy/org/springframework/cloud/contract/verifier/twitter/places/BaseMockMvcSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/bootSimple/src/test/resources/logback-test.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle.properties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradle/wrapper/gradle-wrapper.properties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/gradlew.bat diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/a_foo.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookDeleted.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned1.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/repository/mappings/bookReturned2.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/settings.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookDeleted.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookListener.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookListener.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookListener.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookListener.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookReturned.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookService.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookService.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookService.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/BookService.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/groovy/org/springframework/cloud/samples/book/IntegrationMessagingApplication.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/main/resources/integration-context.xml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud/samples/book/MessagingBaseSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud/samples/book/MessagingBaseSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud/samples/book/MessagingBaseSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/groovy/org/springframework/cloud/samples/book/MessagingBaseSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud/samples/book/MessagingBaseTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud/samples/book/MessagingBaseTest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud/samples/book/MessagingBaseTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/messagingProject/src/test/java/org/springframework/cloud/samples/book/MessagingBaseTest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudRestApplication.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/main/resources/application.yml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradle/wrapper/gradle-wrapper.properties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/gradlew.bat diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/mappings/.gitkeep diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/main/resources/application.yml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleJerseyProject/settings.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsFraud.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/Application.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/FraudDetectionController.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheck.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckResult.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/java/org/springframework/frauddetection/model/FraudCheckStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/main/resources/application.yml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradle/wrapper/gradle-wrapper.properties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/gradlew.bat diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/mappings/.gitkeep diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/main/resources/application.yml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/sampleProject/settings.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/1_shouldMarkClientAsNotFraud.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/mappings/fraudDetectionService/2_shouldMarkClientAsFraud.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/Application.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/FraudDetectionController.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheck.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckResult.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/main/resources/application.yml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/groovy/org/springframework/cloud/MvcSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/fraudDetectionService/src/test/java/org/springframework/cloud/MvcTest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.jar diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradle/wrapper/gradle-wrapper.properties diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/gradlew.bat diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/mappings/.gitkeep diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/Application.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/LoanApplicationService.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/Client.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudCheckStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceRequest.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/FraudServiceResponse.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplication.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationResult.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/java/org/springframework/cloud/frauddetection/model/LoanApplicationStatus.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/main/resources/application.yml diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/groovy/org/springframework/cloud/LoanApplicationServiceSpec.groovy diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/loanApplicationService/src/test/resources/mappings/fraudDetectionService/shouldMarkClientAsNotFraud.json diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-gradle-plugin/src/test/resources/functionalTest/scenarioProject/settings.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/README.adoc b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/README.adoc similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/README.adoc rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/README.adoc diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/CamelMessage.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelConfiguration.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessageBuilder.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/java/org/springframework/cloud/contract/verifier/messaging/camel/ContractVerifierCamelMessaging.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-camel/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationConfiguration.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessageBuilder.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/ContractVerifierIntegrationMessaging.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/java/org/springframework/cloud/contract/verifier/messaging/integration/IntegrationMessage.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-integration/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierFilter.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessage.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessageBuilder.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessaging.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierMessagingUtil.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/ContractVerifierObjectMapper.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessage.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessageBuilder.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-messaging-core/src/main/java/org/springframework/cloud/contract/verifier/messaging/noop/NoOpContractVerifierMessaging.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/build.gradle diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamAutoConfiguration.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessageBuilder.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/ContractVerifierStreamMessaging.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/java/org/springframework/cloud/contract/verifier/messaging/stream/StreamMessage.java diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-messaging/spring-cloud-contract-verifier-stream/src/main/resources/META-INF/spring.factories diff --git a/spring-cloud-contract-verifier/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy b/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy similarity index 100% rename from spring-cloud-contract-verifier/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy rename to spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier/spring-cloud-contract-verifier-testing-utils/src/main/groovy/org/springframework/cloud/contract/verifier/util/AssertionUtil.groovy