diff --git a/README.md b/README.md index b681574..53d457e 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,101 @@ # utPLSQL-maven-plugin A maven plugin for running Unit Tests with utPLSQL v3+ + +### Compatibility + +This plugin is compatible with the Java-API 3.0.4. + +### Prerequisites +You have to be a fully utPLSQL environment available compatible with the Java API. + + +### Plugin Parameters + +* `url` + * URL of the Connection to the database + * Default: `${dbURL}` +* `user` + * Credential of the connection to the database + * Default: `${dbUser}` +* `password` + * Password of the connection to the database + * Default: `${dbPass}` +* `ignoreFailure` + * Ignore or continue when a test fail + * Default: `${maven.test.failure.ignore}` +* `skipCompatibilityCheck` + * Skip the Compatibility Checks + * `true` | `false` (default: `false`) +* `reporters` + * List of the Reporters (Check the example below). + * You can pass the name of the reporter and/or the output file of the reporter and/or if the report is logged to the console + * This is a current list of the names of the reporters (See UtPLSQL documentation in order to check the final list): `UT_DOCUMENTATION_REPORTER`, `UT_COVERAGE_HTML_REPORTER`, `UT_TEAMCITY_REPORTER`, `UT_XUNIT_REPORTER`, `UT_COVERALLS_REPORTER`, `UT_COVERAGE_SONAR_REPORTER`, `UT_SONAR_TEST_REPORTER` + * Check the example below + +* `paths` + * Paths of the resources +* `sources` + * Sources of the scripts at the style of the maven resources +* `tests` + * Test fo the scripts at the style of the maven resources +* `targetDir` + * Target dir, this is a readonly property + * Default: `${project.build.directory}` +* `includeObject` + * Include Object +* `excludeObject` + * Exclude Objects + + + +### Sample of use +The next snippet is a sample of declaration of the pom +```xml + + org.utplsql + utplsql-maven-plugin + 1.0.0-SNAPSHOT + + test + + + url_of_connection + user + password + false + + + UT_COVERAGE_SONAR_REPORTER + utplsql/coverage-sonar-reporter.xml + true + + + UT_SONAR_TEST_REPORTER + utplsql/sonar-test-reporter.xml + false + + + UT_TEAMCITY_REPORTER + + + + + src/test/resources/scripts/sources + + **/*pkg + **/*pkb + + + + + + src/test/resources/scripts/test + + **/*pkg + **/*pkb + + + + + +``` diff --git a/utplsql-maven-plugin/pom.xml b/utplsql-maven-plugin/pom.xml index 4354875..c11545f 100644 --- a/utplsql-maven-plugin/pom.xml +++ b/utplsql-maven-plugin/pom.xml @@ -1,110 +1,126 @@ - 4.0.0 - - - org.utplsql - utplsql-maven-plugin-build - 1.0-SNAPSHOT - - - utplsql-maven-plugin - maven-plugin - - utplsql-maven-plugin Maven Plugin - - - http://maven.apache.org - - - - - - - org.utplsql - java-api - 1.0-SNAPSHOT - compile - - - - org.apache.maven - maven-plugin-api - ${maven.version} - - - - org.apache.maven - maven-core - ${maven.version} - - - - org.apache.maven.plugin-tools - maven-plugin-annotations - 3.5 - provided - - - - - - org.apache.maven.plugin-testing - maven-plugin-testing-harness - 3.3.0 - test - - - - org.apache.maven - maven-compat - ${maven.version} - test - - - - junit - junit - 4.12 - test - - - - org.assertj - assertj-core - 3.8.0 - test - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.7.0 - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-plugin-plugin - 3.5 - - - default-descriptor - process-classes - - - help-goal - - helpmojo - - - - - - + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + 4.0.0 + + org.utplsql + utplsql-maven-plugin + maven-plugin + + 1.0.0-SNAPSHOT + + utplsql-maven-plugin Maven Plugin + + + http://maven.apache.org + + + UTF-8 + 1.8 + + + + + + org.utplsql + java-api + 3.0.4 + + + + org.apache.maven + maven-model + 3.0.2 + + + + org.apache.maven + maven-plugin-api + 3.5.2 + + + + org.codehaus.plexus + plexus-utils + 3.0.8 + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.5 + provided + + + + + + org.apache.maven.plugin-testing + maven-plugin-testing-harness + 3.3.0 + test + + + + org.apache.maven + maven-compat + 3.5.2 + test + + + + junit + junit + 4.12 + test + + + + org.assertj + assertj-core + 3.8.0 + test + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.7.0 + + ${java.version} + ${java.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.5 + + utplsql + true + + + + mojo-descriptor + + descriptor + + + + help-goal + + helpmojo + + + + + + + + diff --git a/utplsql-maven-plugin/src/main/java/org/utplsql/UtPLSQLMojo.java b/utplsql-maven-plugin/src/main/java/org/utplsql/UtPLSQLMojo.java index f49ac79..8ddd083 100644 --- a/utplsql-maven-plugin/src/main/java/org/utplsql/UtPLSQLMojo.java +++ b/utplsql-maven-plugin/src/main/java/org/utplsql/UtPLSQLMojo.java @@ -1,104 +1,233 @@ package org.utplsql; +import static java.lang.String.format; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +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.plugin.logging.Log; +import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.utplsql.api.FileMapperOptions; -import org.utplsql.api.OutputBuffer; import org.utplsql.api.TestRunner; import org.utplsql.api.exception.SomeTestsFailedException; import org.utplsql.api.reporter.Reporter; import org.utplsql.api.reporter.ReporterFactory; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import static org.utplsql.api.CustomTypes.UT_DOCUMENTATION_REPORTER; - -@Mojo(name = "test") -public class UtPLSQLMojo extends AbstractMojo { - - - /** - * List of paths with test suites. - */ - @Parameter(name = "suitePaths", required = true, property = "utplsql.suite_paths") - private List suitePaths; - - /** - * List of paths with source files. - */ - @Parameter(name = "sourcePaths", required = true, property = "utplsql.source_paths") - private List sourcePaths; - - /** - * List of paths with test files. - */ - @Parameter(name = "testPaths", required = true, property = "utplsql.test_paths") - private List testPaths; - - public void execute() throws MojoExecutionException, MojoFailureException { - - List reporterList = new ArrayList<>(); - reporterList.add(ReporterFactory.createReporter(UT_DOCUMENTATION_REPORTER)); - List testPaths = listOfStrings("tests"); - FileMapperOptions sourceMappingOptions = new FileMapperOptions(listOfStrings( - "source/award_bonus/award_bonus.prc" -// "/Users/kamil.berdychowski/workspaces/utPLSQL/utPLSQL-demo-project/source/between_string/betwnstr.fnc" - )); - FileMapperOptions testMappingOptions = new FileMapperOptions(listOfStrings( - "/Users/kamil.berdychowski/workspaces/utPLSQL/utPLSQL-demo-project/test/award_bonus/test_award_bonus.pkb", - "/Users/kamil.berdychowski/workspaces/utPLSQL/utPLSQL-demo-project/test/award_bonus/test_award_bonus.pks" -// "/Users/kamil.berdychowski/workspaces/utPLSQL/utPLSQL-demo-project/test/between_string/test_betwnstr.pkb", -// "/Users/kamil.berdychowski/workspaces/utPLSQL/utPLSQL-demo-project/test/between_string/test_betwnstr.pks" - )); - - Connection connection = null; - - try { - connection = DriverManager.getConnection("jdbc:oracle:thin:@//localhost:1521/XE", "tests", "tests"); - - for (Reporter reporter : reporterList) { - reporter.init(connection); - } - - new TestRunner() - .addPathList(testPaths) - .addReporterList(reporterList) - .sourceMappingOptions(sourceMappingOptions) - .testMappingOptions(testMappingOptions) - .colorConsole(true) - .failOnErrors(true) - .run(connection); - } catch (SomeTestsFailedException e) { - getLog().error(e); - throw new MojoExecutionException("Tests failed", e); - } catch (SQLException e) { - getLog().error(e); - throw new MojoFailureException("SQL error occured", e); - } finally { - //TODO: add more security checking, what happens when connection is broken - try { - new OutputBuffer(reporterList.get(0)).printAvailable(connection, System.out); - if (connection != null) { - connection.close(); - } - } catch (SQLException e) { - getLog().error("Error", e); - } - } - - } - - private List listOfStrings(String... values) { - List result = new ArrayList<>(); - Collections.addAll(result, values); - return result; - } +import org.utplsql.helper.PluginDefault; +import org.utplsql.helper.SQLScannerHelper; +import org.utplsql.model.ReporterParameter; +import org.utplsql.reporter.ReporterWriter; + +/** + * This class expose the {@link TestRunner} interface to Maven. + * + * @author Alberto Hernández + * + */ +@Mojo(name = "test", defaultPhase = LifecyclePhase.TEST) +public class UtPLSQLMojo extends AbstractMojo +{ + @Parameter(defaultValue = "${dbUrl}") + private String url; + + @Parameter(defaultValue = "${dbUser}") + private String user; + + @Parameter(defaultValue = "${dbPass}") + private String password; + + @Parameter + private String includeObject; + + @Parameter + private String excludeObject; + + @Parameter(defaultValue = "false") + private boolean skipCompatibilityCheck; + + @Parameter + private List reporters; + + @Parameter(defaultValue = "") + private List paths; + + @Parameter + private List sources = new ArrayList<>(); + + @Parameter + private List tests = new ArrayList<>(); + + @Parameter(defaultValue = "${project.build.directory}", readonly = true) + private String targetDir; + + @Parameter(defaultValue = "${maven.test.failure.ignore}") + private boolean ignoreFailure; + + // Color in the console, loaded by environment variables + private boolean colorConsole = PluginDefault.resolveColor(); + + // Reporter Writer + private ReporterWriter reporterWriter; + + /** + * + * Execute the plugin + * + */ + @Override + public void execute() throws MojoExecutionException + { + Connection connection = null; + try + { + FileMapperOptions sourceMappingOptions = buildOptions(sources, PluginDefault.buildDefaultSource(), "sources"); + FileMapperOptions testMappingOptions = buildOptions(tests, PluginDefault.buildDefaultTest(), "test"); + + // Create the Connection to the Database + connection = DriverManager.getConnection(url, user, password); + List reporterList = initReporters(connection); + + logParameters(sourceMappingOptions, testMappingOptions, reporterList); + + TestRunner runner = new TestRunner() + .addPathList(paths) + .addReporterList(reporterList) + .sourceMappingOptions(sourceMappingOptions) + .testMappingOptions(testMappingOptions) + .skipCompatibilityCheck(skipCompatibilityCheck) + .colorConsole(colorConsole) + .failOnErrors(!ignoreFailure); + + // Setting Optional Parameters + if (StringUtils.isNotBlank(excludeObject)) + { + runner.excludeObject(excludeObject); + } + if (StringUtils.isNotBlank(includeObject)) + { + runner.includeObject(includeObject); + } + + runner.run(connection); + + } + catch (SomeTestsFailedException e) + { + getLog().error(e); + throw new MojoExecutionException(e.getMessage()); + } + catch (SQLException e) + { + getLog().error(e); + throw new MojoExecutionException(e.getMessage(), e); + } + finally + { + try + { + // Write Reporters + reporterWriter.writeReporters(connection); + + if (connection != null) + { + connection.close(); + } + } + catch (Exception e) + { + getLog().error(e.getMessage(), e); + } + } + } + + /** + * + * @param resources + * @return + * @throws MojoExecutionException + */ + private FileMapperOptions buildOptions(List resources, Resource defaultResource, String msg) throws MojoExecutionException + { + try + { + // Check if this element is empty + if (resources.isEmpty()) + { + resources.add(defaultResource); + } + + List scripts = SQLScannerHelper.findSQLs(resources); + return new FileMapperOptions(scripts); + + } + catch (Exception e) + { + throw new MojoExecutionException(format("Invalid <%s> in your pom.xml: %s", msg, e.getMessage())); + } + } + + /** + * Init all the reporters + * + * @param connection + * @return + * @throws SQLException + */ + private List initReporters(Connection connection) throws SQLException + { + List reporterList = new ArrayList<>(); + + // Initializate Reporters + reporterWriter = new ReporterWriter(targetDir); + + for (ReporterParameter reporterParameter : reporters) + { + Reporter reporter = ReporterFactory.createReporter(reporterParameter.getName()); + reporter.init(connection); + reporterList.add(reporter); + + // Only added the reporter if at least one of the output is required + if (StringUtils.isNotBlank(reporterParameter.getFileOutput()) || reporterParameter.isConsoleOutput()) + { + reporterWriter.addReporter(reporterParameter, reporter); + } + } + + return reporterList; + } + + /** + * + * @param sourceMappingOptions + * @param testMappingOptions + * @param reporterList + */ + private void logParameters(FileMapperOptions sourceMappingOptions, FileMapperOptions testMappingOptions, + List reporterList) + { + Log log = getLog(); + log.info("Invoking TestRunner with: " + targetDir); + + // Do nothing when the debug is disabled + if (!log.isDebugEnabled()) + { + return; + } + + log.debug("Invoking TestRunner with: "); + log.debug("reporters="); + reporterList.forEach((Reporter r) -> log.debug(r.getSelfType())); + log.debug("sources="); + sourceMappingOptions.getFilePaths().forEach(log::debug); + log.debug("tests="); + testMappingOptions.getFilePaths().forEach(log::debug); + } } \ No newline at end of file diff --git a/utplsql-maven-plugin/src/main/java/org/utplsql/helper/PluginDefault.java b/utplsql-maven-plugin/src/main/java/org/utplsql/helper/PluginDefault.java new file mode 100644 index 0000000..252e80c --- /dev/null +++ b/utplsql-maven-plugin/src/main/java/org/utplsql/helper/PluginDefault.java @@ -0,0 +1,89 @@ +package org.utplsql.helper; + +import java.util.Arrays; +import java.util.Map; + +import org.apache.maven.model.Resource; + +/** + * This class provides methods to retrieve the list of resources in the default and directories. + * + * @author Alberto Hernández + * + */ +public class PluginDefault +{ + + private static final String STYLE_COLOR_PROPERTY = "style.color"; + + private static final String BATCH_MODE = "B"; + + private static final String LOG_FILE = "l"; + + // Source Directory + private static final String SOURCE_DIRECTORY = "src/main/plsql"; + + // Test Directory + private static final String TEST_DIRECTORY = "src/test/plsql"; + + private PluginDefault() + { + // NA + } + + /** + * This method returns {@link Resource} for the default {@code source} directory + * + * @return a {@link Resource} + */ + public static Resource buildDefaultSource() + { + return buildDirectory(SOURCE_DIRECTORY, "**/*.*"); + } + + /** + * This method returns {@link Resource} for the default {@code test} directory + * + * @return a {@link Resource} + */ + public static Resource buildDefaultTest() + { + return buildDirectory(TEST_DIRECTORY, "**/*.pkg"); + } + + private static Resource buildDirectory(String directory, String includes) + { + Resource resource = new Resource(); + resource.setDirectory(directory); + resource.setIncludes(Arrays.asList(includes)); + return resource; + } + + /** + * + * @return + */ + public static boolean resolveColor() + { + final Map env = System.getenv(); + String color = env.get(STYLE_COLOR_PROPERTY); + + if ("always".equals(color)) + { + return true; + } + + if ("never".equals(color)) + { + return false; + } + + if (env.containsKey(BATCH_MODE) || env.containsKey(LOG_FILE)) + { + return false; + } + + return false; + } + +} diff --git a/utplsql-maven-plugin/src/main/java/org/utplsql/helper/ReporterDefault.java b/utplsql-maven-plugin/src/main/java/org/utplsql/helper/ReporterDefault.java new file mode 100644 index 0000000..3fe204d --- /dev/null +++ b/utplsql-maven-plugin/src/main/java/org/utplsql/helper/ReporterDefault.java @@ -0,0 +1,31 @@ +package org.utplsql.helper; + +import org.utplsql.api.reporter.Reporter; + +/** + * This class is an enumeration of all the known reporter in {@code utPLSQL}. It further more defines the default output + * file for each {@link Reporter}. In case the output file is set to {@code -}, it will mean the stdout of the process. + * + * @author Alberto Hernández + * + */ +public enum ReporterDefault { + + UT_DOCUMENTATION_REPORTER("-"), + UT_COVERAGE_HTML_REPORTER("utplsql/coverage-html-reporter.html"), + UT_TEAMCITY_REPORTER("utplsql/teamcity-reporter.txt"), + UT_XUNIT_REPORTER("utplsql/xunit-reporter.xml"), + UT_COVERALLS_REPORTER("utplsql/coveralls-reporter.json"), + UT_COVERAGE_SONAR_REPORTER("utplsql/coverage-sonar-reporter.xml"), + UT_SONAR_TEST_REPORTER("utplsql/sonar-test-reporter.xml"); + + private String outputFile; + + private ReporterDefault(String outputFile) { + this.outputFile = outputFile; + } + + public String getOutputFile() { + return outputFile; + } +} diff --git a/utplsql-maven-plugin/src/main/java/org/utplsql/helper/SQLScannerHelper.java b/utplsql-maven-plugin/src/main/java/org/utplsql/helper/SQLScannerHelper.java new file mode 100644 index 0000000..6be7baa --- /dev/null +++ b/utplsql-maven-plugin/src/main/java/org/utplsql/helper/SQLScannerHelper.java @@ -0,0 +1,71 @@ +package org.utplsql.helper; + +import static java.lang.String.format; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.maven.model.Resource; +import org.codehaus.plexus.util.DirectoryScanner; + +/** + * Utility to Scan all resources + * + * @author Alberto Hernández + * + */ +public class SQLScannerHelper { + + private SQLScannerHelper() { + // NA + } + + /** + * + * @param resouces + * @return + */ + public static List findSQLs(List resources) { + List founds = new ArrayList<>(); + + for (Resource resource : resources) { + // Build Scanner + DirectoryScanner scanner = buildScanner(resource); + scanner.scan(); + for (String basename : scanner.getIncludedFiles()) { + founds.add(new File(scanner.getBasedir(), basename).getAbsolutePath()); + } + + // Append all scanned objects + founds.addAll(Arrays.asList()); + } + + return founds; + } + + /** + * Build a scanner in forder to Find all Resource files + * + * @param resource + * @return + */ + private static DirectoryScanner buildScanner(Resource resource) { + if (resource != null) { + File baseDir = new File(resource.getDirectory()); + if (!baseDir.exists() || !baseDir.isDirectory() || !baseDir.canRead()) { + throw new IllegalArgumentException( + format("Invalid %s in resource. Check your pom.xml", resource.getDirectory())); + } + + DirectoryScanner scanner = new DirectoryScanner(); + scanner.setBasedir(resource.getDirectory()); + scanner.setIncludes(resource.getIncludes().toArray(new String[0])); + scanner.setExcludes(resource.getExcludes().toArray(new String[0])); + return scanner; + } + throw new IllegalArgumentException(); + } + +} diff --git a/utplsql-maven-plugin/src/main/java/org/utplsql/model/ReporterParameter.java b/utplsql-maven-plugin/src/main/java/org/utplsql/model/ReporterParameter.java new file mode 100644 index 0000000..56ebc60 --- /dev/null +++ b/utplsql-maven-plugin/src/main/java/org/utplsql/model/ReporterParameter.java @@ -0,0 +1,84 @@ +package org.utplsql.model; + +import org.codehaus.plexus.util.StringUtils; + +public class ReporterParameter +{ + + // Name of the registered reported in UtPLSQL + private String name; + + // File Output of the reporter + private String fileOutput; + + // Writes the report to console + private boolean consoleOutput; + + /** + * + */ + public ReporterParameter() + { + super(); + } + + /** + * @return the name + */ + public String getName() + { + return name; + } + + /** + * @param name + * the name to set + */ + public void setName(String name) + { + this.name = name; + } + + /** + * @return the fileOutput + */ + public String getFileOutput() + { + return fileOutput; + } + + /** + * @param fileOutput + * the fileOutput to set + */ + public void setFileOutput(String fileOutput) + { + this.fileOutput = fileOutput; + } + + /** + * @return the consoleOutput + */ + public boolean isConsoleOutput() + { + return consoleOutput; + } + + /** + * @param consoleOutput + * the consoleOutput to set + */ + public void setConsoleOutput(boolean consoleOutput) + { + this.consoleOutput = consoleOutput; + } + + /** + * @return the consoleOutput + */ + public boolean isFileOutput() + { + return StringUtils.isNotBlank(fileOutput); + } + +} diff --git a/utplsql-maven-plugin/src/main/java/org/utplsql/reporter/ReporterWriter.java b/utplsql-maven-plugin/src/main/java/org/utplsql/reporter/ReporterWriter.java new file mode 100644 index 0000000..2673480 --- /dev/null +++ b/utplsql-maven-plugin/src/main/java/org/utplsql/reporter/ReporterWriter.java @@ -0,0 +1,127 @@ +package org.utplsql.reporter; + +import static java.lang.String.format; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.sql.Connection; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.tuple.Pair; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugin.logging.SystemStreamLog; +import org.utplsql.api.OutputBuffer; +import org.utplsql.api.reporter.Reporter; +import org.utplsql.model.ReporterParameter; + +public class ReporterWriter +{ + private static final Log LOG = new SystemStreamLog(); + + // Reporter Parameters + private List> listReporters; + + // Output Directory + private String outputDirectory; + + /** + * + */ + public ReporterWriter(String outputDirectory) + { + listReporters = new ArrayList<>(); + this.outputDirectory = outputDirectory; + } + + /** + * + * @param connection + * @throws MojoExecutionException + */ + public void writeReporters(Connection connection) throws MojoExecutionException + { + for (Pair pair : listReporters) + { + writeReports(connection, pair.getLeft(), pair.getRight()); + } + } + + /** + * + * @param id + * @throws MojoExecutionException + */ + private void writeReports(Connection connection, Reporter reporter, ReporterParameter reporterParameter) + throws MojoExecutionException + { + List printStreams = new ArrayList<>(); + FileOutputStream fout = null; + + // + try + { + OutputBuffer buffer = new OutputBuffer(reporter); + + if (reporterParameter.isFileOutput()) + { + + File file = new File(reporterParameter.getFileOutput()); + if (!file.isAbsolute()) + { + file = new File(outputDirectory, reporterParameter.getFileOutput()); + } + + if (!file.getParentFile().exists()) + { + LOG.debug("Creating directory for reporter file " + file.getAbsolutePath()); + file.getParentFile().mkdirs(); + } + + fout = new FileOutputStream(file); + LOG.info(format("Writing report %s to %s", reporter.getSelfType(), file.getAbsolutePath())); + + // Added to the Report + printStreams.add(new PrintStream(fout)); + } + + if (reporterParameter.isConsoleOutput()) + { + LOG.info(format("Writing report %s to Console", reporter.getSelfType())); + printStreams.add(System.out); + } + buffer.printAvailable(connection, printStreams); + } + catch (Exception e) + { + throw new MojoExecutionException("Unexpected error opening file ouput ", e); + } + finally + { + if (fout != null) + { + try + { + fout.close(); + } + catch (IOException e) + { + LOG.info(format("Failed to closing the reporting %s", reporterParameter.getClass())); + } + } + } + + } + + /** + * + */ + public void addReporter(ReporterParameter parameter, Reporter reporter) + { + listReporters.add(Pair.of(reporter, parameter)); + } + +} diff --git a/utplsql-maven-plugin/src/main/java/org/utplsql/tools/FileWalker.java b/utplsql-maven-plugin/src/main/java/org/utplsql/tools/FileWalker.java deleted file mode 100644 index bc57c45..0000000 --- a/utplsql-maven-plugin/src/main/java/org/utplsql/tools/FileWalker.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.utplsql.tools; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by Vinicius on 18/06/2017. - taken from API - */ -public class FileWalker { - - public static List getFileList(File baseDir, String inspectPath) { - return getFileList(baseDir, inspectPath, true); - } - - public static List getFileList(File baseDir, String inspectPath, boolean relative) { - File inspectDir = new File(baseDir, inspectPath); - - if (!inspectDir.isDirectory()) - throw new IllegalArgumentException(inspectPath + " is not a directory."); - - List fileList = new ArrayList<>(); - listDirFiles(baseDir, inspectDir, fileList, relative); - - return fileList; - } - - private static void listDirFiles(File baseDir, File directory, List fileList, boolean relative) { - File[] directoryFiles = directory.listFiles(); - - if (directoryFiles == null) - return; - - for (File file : directoryFiles) { - if (file.isFile()) { - String absolutePath = file.getAbsolutePath(); - - if (relative) - absolutePath = absolutePath.substring(baseDir.getAbsolutePath().length() + 1); - - fileList.add(absolutePath); - } else { - listDirFiles(baseDir, file, fileList, relative); - } - } - } - -} diff --git a/utplsql-maven-plugin/src/test/java/UtPLSQLMojoTest.java b/utplsql-maven-plugin/src/test/java/UtPLSQLMojoTest.java deleted file mode 100644 index e79de39..0000000 --- a/utplsql-maven-plugin/src/test/java/UtPLSQLMojoTest.java +++ /dev/null @@ -1,58 +0,0 @@ -import org.apache.maven.plugin.Mojo; -import org.apache.maven.plugin.testing.AbstractMojoTestCase; -import org.assertj.core.api.Assertions; - -import java.io.File; -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -public class UtPLSQLMojoTest extends AbstractMojoTestCase { - - public static final String POM_PATH = "src/test/resources/pom.xml"; - - @Override - public void setUp() throws Exception { - super.setUp(); - } - - @Override - public void tearDown() throws Exception { - super.tearDown(); - } - - public void test_mojo_definition() throws Exception { - File pom = getTestFile(POM_PATH); - assertThat(pom.exists()).isTrue(); - - Mojo testMojo = lookupMojo("test", pom); - assertThat(testMojo).isNotNull(); - } - - public void test_mapping_suite_paths() throws Exception { - File pom = getTestFile("src/test/resources/pom.xml"); - Mojo testMojo = lookupMojo("test", pom); - - List paths = (List) getVariableValueFromObject(testMojo, "suitePaths"); - - assertThat(paths).containsExactly("suite_path1", "suite_path2"); - } - - public void test_mapping_source_paths() throws Exception { - File pom = getTestFile("src/test/resources/pom.xml"); - Mojo testMojo = lookupMojo("test", pom); - - List paths = (List) getVariableValueFromObject(testMojo, "sourcePaths"); - - assertThat(paths).containsExactly("source_path1", "source_path2", "source_path3"); - } - - public void test_mapping_test_paths() throws Exception { - File pom = getTestFile("src/test/resources/pom.xml"); - Mojo testMojo = lookupMojo("test", pom); - - List paths = (List) getVariableValueFromObject(testMojo, "testPaths"); - - assertThat(paths).containsExactly("test_path1", "test_path2"); - } -} diff --git a/utplsql-maven-plugin/src/test/java/org/utpsql/test/UtPLSQLMojoTest.java b/utplsql-maven-plugin/src/test/java/org/utpsql/test/UtPLSQLMojoTest.java new file mode 100644 index 0000000..dc891a2 --- /dev/null +++ b/utplsql-maven-plugin/src/test/java/org/utpsql/test/UtPLSQLMojoTest.java @@ -0,0 +1,53 @@ +package org.utpsql.test; + +import java.io.File; + +import org.apache.maven.plugin.testing.MojoRule; +import org.junit.Assert; +import org.junit.Rule; +import org.junit.Test; +import org.utplsql.UtPLSQLMojo; + +public class UtPLSQLMojoTest +{ + public static final String POM_PATH = "src/test/resources/"; + + public static final String OUTPUT_DIRECTORY = "target/test-classes"; + + @Rule + public MojoRule rule = new MojoRule(); + + @Test + public void testDefinition() throws Exception + { + + try + { + UtPLSQLMojo myMojo = (UtPLSQLMojo) rule.lookupConfiguredMojo(new File(POM_PATH), "test"); + + Assert.assertNotNull(myMojo); + myMojo.execute(); + + checkCoverReportsGenerated("utplsql/coverage-sonar-reporter.xml", "utplsql/sonar-test-reporter.xml"); + } + catch (Exception e) + { + e.printStackTrace(); + Assert.fail("Unexpected Exception running the test of Definition"); + } + } + + /** + * + * @param files + */ + private void checkCoverReportsGenerated(String... files) + { + for (String filename : files) + { + File file = new File(OUTPUT_DIRECTORY, filename); + Assert.assertTrue("The reporter for " + filename + " was not generated", file.exists()); + } + } + +} diff --git a/utplsql-maven-plugin/src/test/resources/pom.xml b/utplsql-maven-plugin/src/test/resources/pom.xml index 41a1498..3eeae3d 100644 --- a/utplsql-maven-plugin/src/test/resources/pom.xml +++ b/utplsql-maven-plugin/src/test/resources/pom.xml @@ -4,12 +4,21 @@ org.utplsql utplsql-maven-plugin-test - 1.0-SNAPSHOT + 1.0.0-SNAPSHOT maven-plugin utplsql-maven-plugin Maven Plugin Test - + + + + jdbc:oracle:thin:@180.129.3.101:1521:xe + ut3 + XNtxj8eEgA6X6b6f + + + ../../../target/test-classes + ${pom.groupId} @@ -19,19 +28,47 @@ test - - suite_path1 - suite_path2 - - - source_path1 - source_path2 - source_path3 - - - test_path1 - test_path2 - + + + false + + + :plsql + + + + + UT_COVERAGE_SONAR_REPORTER + utplsql/coverage-sonar-reporter.xml + true + + + UT_SONAR_TEST_REPORTER + utplsql/sonar-test-reporter.xml + true + + + + + + src/test/resources/scripts/sources + + **/*pkg + **/*pkb + + + + + + + src/test/resources/scripts/test + + **/*pkg + **/*pkb + + + + diff --git a/utplsql-maven-plugin/src/test/resources/scripts/sources/PKG_TEST_ME.bdy b/utplsql-maven-plugin/src/test/resources/scripts/sources/PKG_TEST_ME.bdy new file mode 100644 index 0000000..a2ff185 --- /dev/null +++ b/utplsql-maven-plugin/src/test/resources/scripts/sources/PKG_TEST_ME.bdy @@ -0,0 +1,28 @@ +CREATE OR REPLACE PACKAGE BODY PKG_TEST_ME IS + + -- + -- This + -- + FUNCTION FC_TEST_ME(PPARAM1 IN VARCHAR2) RETURN NUMBER IS + BEGIN + IF PPARAM1 IS NULL THEN + RETURN NULL; + ELSIF PPARAM1 = '1' THEN + RETURN 1; + ELSE + RETURN 0; + END IF; + END FC_TEST_ME; + + PROCEDURE PR_TEST_ME(PSNAME IN VARCHAR2) IS + BEGIN + IF PSNAME IS NULL THEN + NULL; + ELSE + INSERT INTO TO_TEST_ME (SNAME) VALUES (PSNAME); + COMMIT; + END IF; + END PR_TEST_ME; + +END PKG_TEST_ME; +/ \ No newline at end of file diff --git a/utplsql-maven-plugin/src/test/resources/scripts/sources/PKG_TEST_ME.spc b/utplsql-maven-plugin/src/test/resources/scripts/sources/PKG_TEST_ME.spc new file mode 100644 index 0000000..67fe1f8 --- /dev/null +++ b/utplsql-maven-plugin/src/test/resources/scripts/sources/PKG_TEST_ME.spc @@ -0,0 +1,8 @@ +-- +-- This package is used TO demonstrate the utPL/SQL possibilities +-- +CREATE OR REPLACE PACKAGE PKG_TEST_ME AS + FUNCTION FC_TEST_ME(PPARAM1 IN VARCHAR2) RETURN NUMBER; + PROCEDURE PR_TEST_ME(PSNAME IN VARCHAR2); +END PKG_TEST_ME; +/ \ No newline at end of file diff --git a/utplsql-maven-plugin/src/test/resources/scripts/sources/TO_TEST_ME.tab b/utplsql-maven-plugin/src/test/resources/scripts/sources/TO_TEST_ME.tab new file mode 100644 index 0000000..1cd6f12 --- /dev/null +++ b/utplsql-maven-plugin/src/test/resources/scripts/sources/TO_TEST_ME.tab @@ -0,0 +1,8 @@ +-- +-- This is a table used to demonstrate the UNIT test framework. +-- +CREATE TABLE TO_TEST_ME +( + SNAME VARCHAR2(10) +) +/ diff --git a/utplsql-maven-plugin/src/test/resources/scripts/test/TEST_PKG_TEST_ME.bdy b/utplsql-maven-plugin/src/test/resources/scripts/test/TEST_PKG_TEST_ME.bdy new file mode 100644 index 0000000..6f347b6 --- /dev/null +++ b/utplsql-maven-plugin/src/test/resources/scripts/test/TEST_PKG_TEST_ME.bdy @@ -0,0 +1,126 @@ +CREATE OR REPLACE PACKAGE BODY TEST_PKG_TEST_ME AS + + --------------------------------------------------------------------------- + PROCEDURE SETUP_GLOBAL IS + BEGIN + -- Put here the code which is valid for all tests and that should be + -- executed once. + NULL; + END SETUP_GLOBAL; + + --------------------------------------------------------------------------- + PROCEDURE TEARDOWN_GLOBAL IS + BEGIN + -- Put here the code that should be called only once after all the test + -- have executed + NULL; + END TEARDOWN_GLOBAL; + + --------------------------------------------------------------------------- + PROCEDURE SETUP_TEST IS + BEGIN + -- Nothing to clean up globally + NULL; + END SETUP_TEST; + + PROCEDURE TEARDOWN_TEST IS + BEGIN + -- Nothing to clean up globally + NULL; + END TEARDOWN_TEST; + + PROCEDURE TEST_FC_INPUT_1 IS + BEGIN + -- Ok this is a real test where I check that the function return 1 + -- when called with a '1' parameter + UT.EXPECT(PKG_TEST_ME.FC_TEST_ME('1')).TO_EQUAL(1); + END; + + PROCEDURE SETUP_TEST_FC_INPUT_1 IS + BEGIN + -- Nothing to be done really + NULL; + END; + + PROCEDURE TEARDOWN_TEST_FC_INPUT_1 IS + BEGIN + -- Nothing to be done really + NULL; + END; + + PROCEDURE TEST_FC_INPUT_0 IS + BEGIN + -- Ok this is a real test where I check that the function return 0 + -- when called with a '0' parameter + UT.EXPECT(PKG_TEST_ME.FC_TEST_ME('0')).TO_EQUAL(0); + END; + + PROCEDURE TEST_FC_INPUT_NULL IS + BEGIN + -- Ok I check that the function return NULL + -- when called with a NULL parameter + UT.EXPECT(PKG_TEST_ME.FC_TEST_ME(NULL)).TO_BE_NULL; + END TEST_FC_INPUT_NULL; + + PROCEDURE TEST_PR_TEST_ME_NULL IS + VNCOUNT1 PLS_INTEGER; + VNCOUNT2 PLS_INTEGER; + BEGIN + -- In this example I check that the procedure does + -- not insert anything when passing it a NULL parameter + SELECT COUNT(1) INTO VNCOUNT1 FROM TO_TEST_ME; + PKG_TEST_ME.PR_TEST_ME(NULL); + SELECT COUNT(1) INTO VNCOUNT2 FROM TO_TEST_ME; + UT.EXPECT(VNCOUNT1).TO_EQUAL(VNCOUNT2); + END; + + PROCEDURE TEST_PR_TEST_ME_NOT_NULL IS + VNCOUNT1 PLS_INTEGER; + VNCOUNT2 PLS_INTEGER; + VSNAME TO_TEST_ME.SNAME%TYPE; + BEGIN + -- In this test I will check that I do insert a value + -- when the parameter is not null. I futher check that + -- the procedure has inserted the value I specified. + SELECT COUNT(1) INTO VNCOUNT1 FROM TO_TEST_ME; + VSNAME := TO_CHAR(VNCOUNT1); + PKG_TEST_ME.PR_TEST_ME(VSNAME); + SELECT COUNT(1) INTO VNCOUNT2 FROM TO_TEST_ME; + + -- Check that I have inserted the value + UT.EXPECT(VNCOUNT1 + 1).TO_EQUAL(VNCOUNT2); + SELECT COUNT(1) INTO VNCOUNT2 FROM TO_TEST_ME T WHERE T.SNAME = VSNAME; + + -- Check that I inserted the one I said I would insert + UT.EXPECT(VNCOUNT2).TO_EQUAL(1); + DELETE FROM TO_TEST_ME T WHERE T.SNAME = VSNAME; + COMMIT; + END; + + PROCEDURE TEST_PR_TEST_ME_EXISTS IS + BEGIN + -- In case the value exists the procedure should fail with an exception. + BEGIN + PKG_TEST_ME.PR_TEST_ME('EXISTS'); + PKG_TEST_ME.PR_TEST_ME('EXISTS'); + EXCEPTION + WHEN OTHERS THEN + UT.FAIL('Unexpected exception raised'); + END; + END; + + PROCEDURE TEST_PR_TEST_ME_CURSOR IS + TYPE REF_CURSOR IS REF CURSOR; + VEXPECTED REF_CURSOR; + VACTUAL REF_CURSOR; + BEGIN + EXECUTE IMMEDIATE 'TRUNCATE TABLE TO_TEST_ME'; + OPEN VEXPECTED FOR + SELECT T.SNAME FROM TO_TEST_ME T; + OPEN VACTUAL FOR + SELECT T.SNAME FROM TO_TEST_ME T; + UT.EXPECT(VEXPECTED).TO_(EQUAL(VACTUAL)); + END; + +END; +/ diff --git a/utplsql-maven-plugin/src/test/resources/scripts/test/TEST_PKG_TEST_ME.spc b/utplsql-maven-plugin/src/test/resources/scripts/test/TEST_PKG_TEST_ME.spc new file mode 100644 index 0000000..a2b5f6d --- /dev/null +++ b/utplsql-maven-plugin/src/test/resources/scripts/test/TEST_PKG_TEST_ME.spc @@ -0,0 +1,86 @@ +CREATE OR REPLACE PACKAGE TEST_PKG_TEST_ME AS + -- + -- This package shows all the possibilities to unit test + -- your PL/SQL package. NOTE that it is not limited to + -- testing your package. You can do that on all your + -- procedure/functions... + -- + + /** + * This two parameters are used by the test framework in + * order to identify the test suite to run + */ + -- %suite(TEST_PKG_TEST_ME) + -- %suitepath(plsql.examples) + + /* + * This method is invoked once before any other method. + * It should contain all the setup code that is relevant + * for all your test. It might be inserting a register, + * creating a type, etc... + */ + -- %beforeall + PROCEDURE SETUP_GLOBAL; + + /* + * This method is invoked once after all other method. + * It can be used to clean up all the resources that + * you created in your script + */ + -- %afterall + PROCEDURE TEARDOWN_GLOBAL; + + /* + * This method is called once before each test. + */ + -- %beforeeach + PROCEDURE SETUP_TEST; + + /* + * This method is called once after each test. + */ + -- %aftereach + PROCEDURE TEARDOWN_TEST; + + /** + * This is a real test. The main test can declare a setup + * and teardown method in order to setup and cleanup things + * for that specific test. + */ + -- %test + -- %displayname(Checking if function ('1') returns 1) + -- %beforetest(SETUP_TEST_FC_INPUT_1) + -- %aftertest(TEARDOWN_TEST_FC_INPUT_1) + PROCEDURE TEST_FC_INPUT_1; + PROCEDURE SETUP_TEST_FC_INPUT_1; + PROCEDURE TEARDOWN_TEST_FC_INPUT_1; + + -- %test + -- %displayname(Checking if function ('0') returns 0) + PROCEDURE TEST_FC_INPUT_0; + + -- %test + -- %displayname(Checking if function (NULL) returns NULL) + PROCEDURE TEST_FC_INPUT_NULL; + + -- %test + -- %displayname(Checking if procedure (NULL) insert) + PROCEDURE TEST_PR_TEST_ME_NULL; + + -- %test + -- %displayname(Checking if procedure (NOT NULL) insert) + -- %rollback(manual) + PROCEDURE TEST_PR_TEST_ME_NOT_NULL; + + -- %test + -- %displayname(Checking if procedure (NOT NULL) insert while existing) + -- %rollback(manual) + PROCEDURE TEST_PR_TEST_ME_EXISTS; + + -- %test + -- %displayname(Demonstrating the use of cursor) + -- %rollback(manual) + PROCEDURE TEST_PR_TEST_ME_CURSOR; + +END; +/