Spock basic generation strategy
This commit is contained in:
12
pom.xml
12
pom.xml
@@ -31,6 +31,18 @@
|
||||
<version>2.4.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spockframework</groupId>
|
||||
<artifactId>spock-core</artifactId>
|
||||
<version>0.7-groovy-2.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.github.tomakehurst</groupId>
|
||||
<artifactId>wiremock</artifactId>
|
||||
<version>1.53</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -14,22 +14,33 @@ class ClassBuilder {
|
||||
private final List<String> staticImports = []
|
||||
private final List<String> rules = []
|
||||
private final List<MethodBuilder> 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)
|
||||
|
||||
@@ -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();*/
|
||||
}
|
||||
10
src/main/groovy/eu/coderate/accurest/builder/Lang.groovy
Normal file
10
src/main/groovy/eu/coderate/accurest/builder/Lang.groovy
Normal file
@@ -0,0 +1,10 @@
|
||||
package eu.coderate.accurest.builder
|
||||
|
||||
/**
|
||||
* @author Jakub Kubrynski
|
||||
*/
|
||||
enum Lang {
|
||||
|
||||
JAVA, GROOVY
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -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('}')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"url": "/some/thing"
|
||||
"url": "/some"
|
||||
},
|
||||
"response": {
|
||||
"status": 200,
|
||||
17
src/main/resources/stubs/wiremocks/shouldFail.json
Normal file
17
src/main/resources/stubs/wiremocks/shouldFail.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "/some/thing",
|
||||
"headers": {
|
||||
"Accept": {
|
||||
"equalTo": "text/plain"
|
||||
}
|
||||
},
|
||||
"bodyPatterns" : [ {
|
||||
"matches" : "{\"client\":\"1234\"}"
|
||||
} ]
|
||||
},
|
||||
"response": {
|
||||
"status": 400
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"url": "/some/thing"
|
||||
},
|
||||
"response": {
|
||||
"status": 400
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user