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') {