com.github.searls.jasmine.mojo.AbstractJasmineMojo Maven / Gradle / Ivy
Show all versions of jasmine-maven-plugin Show documentation
package com.github.searls.jasmine.mojo;
import com.github.searls.jasmine.config.JasmineConfiguration;
import com.github.searls.jasmine.exception.StringifiesStackTraces;
import com.github.searls.jasmine.io.ScansDirectory;
import com.github.searls.jasmine.model.FileSystemReporter;
import com.github.searls.jasmine.model.Reporter;
import com.github.searls.jasmine.model.ScriptSearch;
import com.github.searls.jasmine.runner.SpecRunnerTemplate;
import com.github.searls.jasmine.thirdpartylibs.ProjectClassLoaderFactory;
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.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.resource.ResourceManager;
import org.eclipse.jetty.server.Connector;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public abstract class AbstractJasmineMojo extends AbstractMojo implements JasmineConfiguration {
// Properties in order of most-to-least interesting for client projects to override
/**
* Directory storing your JavaScript.
*
* @since 1.1.0
*/
@Parameter(
property = "jsSrcDir",
defaultValue = "${project.basedir}${file.separator}src${file.separator}main${file.separator}javascript")
private File jsSrcDir;
/**
* Directory storing your Jasmine Specs.
*
* @since 1.1.0
*/
@Parameter(
property = "jsTestSrcDir",
defaultValue = "${project.basedir}${file.separator}src${file.separator}test${file.separator}javascript")
private File jsTestSrcDir;
/**
* JavaScript sources (typically vendor/lib dependencies) that need to be loaded
* before other sources (and specs) in a particular order. Each source will first be
* searched for relative to ${jsSrcDir}
, then ${jsTestSrcDir}
,
* then (if it's not found in either) it will be included exactly as it appears in your POM.
*
* Therefore, if jquery.js is in ${jsSrcDir}/vendor
, you would configure:
*
* <preloadSources>
* <source>vendor/jquery.js</source>
* </preloadSources>
*
*
* And jquery.js would load before all the other sources and specs.
*
* @since 1.1.0
*/
@Parameter
protected List preloadSources;
/**
* It may be the case that the jasmine-maven-plugin doesn't currently suit all of your needs,
* and as a result the generated SpecRunner HTML files are set up in a way that you can't run
* your specs. Have no fear! Simply specify a custom spec runner template in the plugin configuration
* and make the changes you need.
*
* Potential values are a filesystem path, a URL, or a classpath resource. The default template is
* stored in src/main/resources/jasmine-templates/SpecRunner.htmltemplate
, and the
* required template strings are tokenized in "$*$" patterns.
*
* Example usage:
*
* <customRunnerTemplate>${project.basedir}/src/test/resources/myCustomRunner.template</customRunnerTemplate>
*
*
* @since 1.1.0
*/
@Parameter
protected String customRunnerTemplate;
/**
* Sometimes you want to have full control over how scriptloaders are configured. In order to
* interpolate custom configuration into the generated runnerTemplate, specify a file containing
* the additional config. Potential values are a filesystem path, a URL, or a classpath resource.
*
* Example usage:
*
* <customRunnerConfiguration>${project.basedir}/src/test/resources/myCustomConfig.txt</customRunnerConfiguration>
*
*
* @since 1.1.0
*/
@Parameter
protected String customRunnerConfiguration;
/**
* Specify a custom reporter to be used to print the test report.
* Example usage:
*
* <reporters>
* <reporter>
* <reporterName>${project.basedir}/src/test/resources/myCustomReporter.js</reporterName>
* </reporter>
* <reporter>
* <reporterName>STANDARD</reporterName>
* </reporter>
* </reporters>
*
*/
@Parameter
protected List reporters = new ArrayList();
/**
* Specify a custom file system reporter to be used to store the test report.
* Example usage:
*
* <fileSystemReporters>
* <reporter>
* <fileName>MyFile.log</fileName>
* <reporterName>${project.basedir}/src/test/resources/myCustomReporter.js</reporterName>
* </reporter>
* <reporter>
* <fileName>Test-jasmine.xml</fileName>
* <reporterName>JUNIT_XML</reporterName>
* </reporter>
* </fileSystemReporters>
*
*/
@Parameter
protected List fileSystemReporters = new ArrayList();
/**
* Target directory for files created by the plugin.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "${project.build.directory}${file.separator}jasmine")
protected File jasmineTargetDir;
/**
* Skip execution of tests.
*
* @see http://maven.apache.org/general.html#skip-test
* @since 1.1.0
*/
@Parameter(property = "skipTests")
protected boolean skipTests;
/**
* Skip compilation and execution of tests.
*
* @see http://maven.apache.org/general.html#skip-test
* @since 1.3.1.3
*/
@Parameter(property = "maven.test.skip")
protected boolean mvnTestSkip;
/**
* Skip only jasmine tests
*
* @since 1.3.1.3
*/
@Parameter(property = "skipJasmineTests")
protected boolean skipJasmineTests;
/**
* Halt the build on test failure.
*
* @since 1.1.0
*/
@Parameter(property = "haltOnFailure", defaultValue = "true")
protected boolean haltOnFailure;
/**
* Timeout for spec execution in seconds.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "300")
protected int timeout;
/**
* True to increase HtmlUnit output and attempt reporting on specs even if a timeout occurred.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "false")
protected boolean debug;
/**
* The name of the Spec Runner file.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "SpecRunner.html")
protected String specRunnerHtmlFileName;
/**
* The name of the Manual Spec Runner.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "ManualSpecRunner.html")
protected String manualSpecRunnerHtmlFileName;
/**
* The name of the directory the specs will be deployed to on the server.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "spec")
protected String specDirectoryName;
/**
* The name of the directory the sources will be deployed to on the server.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "src")
protected String srcDirectoryName;
/**
* The source encoding.
*
* @since 1.1.0
*/
@Parameter(defaultValue = "${project.build.sourceEncoding}")
protected String sourceEncoding;
/**
* Allows specifying which source files should be included and in what order.
*
* <sourceIncludes>
* <include>vendor/**/*.js</include>
* <include>myBootstrapFile.js</include>
* <include>**/*.js</include>
* <include>**/*.coffee</include>
* </sourceIncludes>
*
*
* Default sourceIncludes
:
*
* <sourceIncludes>
* <include>**/*.js</include>
* <include>**/*.coffee</include>
* </sourceIncludes>
*
*
* @since 1.1.0
*/
@Parameter
private final List sourceIncludes = ScansDirectory.DEFAULT_INCLUDES;
/**
* Just like sourceIncludes
, but will exclude anything matching the provided patterns.
* There are no sourceExcludes
by default.
*
* @since 1.1.0
*/
@Parameter
private final List sourceExcludes = Collections.emptyList();
/**
* I often find myself needing control of the spec include order
* when I have some global spec helpers or spec-scoped dependencies, like:
*
* <specIncludes>
* <include>jasmine-jquery.js</include>
* <include>spec-helper.js</include>
* <include>**/*.js</include>
* <include>**/*.coffee</include>
* </specIncludes>
*
*
* Default specIncludes
:
*
* <specIncludes>
* <include>**/*.js</include>
* <include>**/*.coffee</include>
* </specIncludes>
*
*
* @since 1.1.0
*/
@Parameter
private final List specIncludes = ScansDirectory.DEFAULT_INCLUDES;
/**
* Just like specIncludes
, but will exclude anything matching the provided patterns.
* There are no specExcludes
by default.
*
* @since 1.1.0
*/
@Parameter
private final List specExcludes = Collections.emptyList();
/**
* Used by the jasmine:bdd
goal to specify port to run the server under.
*
* The jasmine:test
goal always uses a random available port so this property is ignored.
*
* @since 1.1.0
*/
@Parameter(property = "jasmine.serverPort", defaultValue = "8234")
protected int serverPort;
/**
* Specify the URI scheme in which to access the SpecRunner.
*
* @since 1.3.1.4
*/
@Parameter(property = "jasmine.uriScheme", defaultValue = "http")
protected String uriScheme;
/**
* Not used by the jasmine:bdd
goal.
*
* The jasmine:test
goal to specify hostname where the server is running. Useful when using
* the RemoteWebDriver.
*
* @since 1.3.1.4
*/
@Parameter(property = "jasmine.serverHostname", defaultValue = "localhost")
protected String serverHostname;
/**
* Determines the strategy to use when generation the JasmineSpecRunner. This feature allows for custom
* implementation of the runner generator. Typically this is used when using different script runners.
*
* Some valid examples: DEFAULT, REQUIRE_JS
*
* @since 1.1.0
*/
@Parameter(property = "jasmine.specRunnerTemplate", defaultValue = "DEFAULT")
protected SpecRunnerTemplate specRunnerTemplate;
/**
* Automatically refresh the test runner at the given interval (specified in seconds) when using the jasmine:bdd
goal.
* A value of 0
disables the automatic refresh (which is the default).
*
* @since 1.3.1.1
*/
@Parameter(property = "jasmine.autoRefreshInterval", defaultValue = "0")
protected int autoRefreshInterval;
/**
* Control the Coffee Script compilation. e.g. When using RequireJS the compilation
* happens within the Coffee Script AMD loader plugin; we therefore need to disable the
* compilation here.
*
* @since 1.3.1.4
*/
@Parameter(property = "coffeeScriptCompilationEnabled", defaultValue = "true")
protected boolean coffeeScriptCompilationEnabled;
/**
* Type of {@link org.eclipse.jetty.server.Connector} to use on the jetty server.
*
* Most users won't need to change this from the default value. It should only be used
* by advanced users.
*
* @since 1.3.1.4
*/
@Parameter(
property = "jasmine.connectorClass",
defaultValue = "org.eclipse.jetty.server.nio.SelectChannelConnector"
)
protected String connectorClass;
/**
* Specify additional contexts to make available.
*
* <additionalContexts>
* <context>
* <contextRoot>lib</contextRoot>
* <directory>${project.basedir}/src/main/lib</directory>
* </context>
* <context>
* <contextRoot>test/lib</contextRoot>
* <directory>${project.basedir}/src/test/lib</directory>
* </context>
* </additionalContexts>
*
*
* @since 1.3.1.5
*/
@Parameter
private List additionalContexts = Collections.emptyList();
@Parameter(defaultValue = "${project}", readonly = true)
protected MavenProject mavenProject;
@Component
ResourceManager resourceManager;
protected ResourceRetriever resourceRetriever;
protected ReporterRetriever reporterRetriever;
protected StringifiesStackTraces stringifiesStackTraces = new StringifiesStackTraces();
protected ScriptSearch sources;
protected ScriptSearch specs;
private File customRunnerTemplateFile;
private File customRunnerConfigurationFile;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
this.loadResources();
this.sources = new ScriptSearch(this.jsSrcDir, this.sourceIncludes, this.sourceExcludes);
this.specs = new ScriptSearch(this.jsTestSrcDir, this.specIncludes, this.specExcludes);
try {
this.run();
} catch (MojoFailureException e) {
throw e;
} catch (Exception e) {
throw new MojoExecutionException("The jasmine-maven-plugin encountered an exception: \n" + this.stringifiesStackTraces.stringify(e), e);
}
}
public abstract void run() throws Exception;
@Override
public String getSourceEncoding() {
return this.sourceEncoding;
}
@Override
public File getCustomRunnerTemplate() {
return this.customRunnerTemplateFile;
}
@Override
public SpecRunnerTemplate getSpecRunnerTemplate() {
return this.specRunnerTemplate;
}
@Override
public File getJasmineTargetDir() {
return this.jasmineTargetDir;
}
@Override
public String getSrcDirectoryName() {
return this.srcDirectoryName;
}
@Override
public ScriptSearch getSources() {
return this.sources;
}
@Override
public ScriptSearch getSpecs() {
return this.specs;
}
@Override
public String getSpecDirectoryName() {
return this.specDirectoryName;
}
@Override
public List getPreloadSources() {
return this.preloadSources;
}
@Override
public int getAutoRefreshInterval() {
return this.autoRefreshInterval;
}
@Override
public boolean isCoffeeScriptCompilationEnabled() {
return this.coffeeScriptCompilationEnabled;
}
public MavenProject getMavenProject() {
return this.mavenProject;
}
@Override
public File getCustomRunnerConfiguration() {
return this.customRunnerConfigurationFile;
}
@Override
public List getReporters() {
return this.reporters;
}
@Override
public List getFileSystemReporters() {
return this.fileSystemReporters;
}
@Override
public File getBasedir() {
return this.mavenProject.getBasedir();
}
@Override
public ClassLoader getProjectClassLoader() {
return new ProjectClassLoaderFactory(mavenProject.getArtifacts()).create();
}
@Override
public List getContexts() {
List contexts = new ArrayList();
contexts.add(new Context(this.srcDirectoryName, this.jsSrcDir));
contexts.add(new Context(this.specDirectoryName, this.jsTestSrcDir));
contexts.addAll(additionalContexts);
return contexts;
}
protected Connector getConnector() throws MojoExecutionException {
try {
@SuppressWarnings("unchecked")
Class extends Connector> c = (Class extends Connector>) Class.forName(connectorClass);
return c.newInstance();
} catch (InstantiationException e) {
throw new MojoExecutionException("Unable to instantiate.", e);
} catch (IllegalAccessException e) {
throw new MojoExecutionException("Unable to instantiate.", e);
} catch (ClassNotFoundException e) {
throw new MojoExecutionException("Unable to instantiate.", e);
}
}
protected boolean isSkipTests() {
return this.skipTests || this.mvnTestSkip || this.skipJasmineTests;
}
private void loadResources() throws MojoExecutionException {
this.customRunnerTemplateFile = getResourceRetriever().getResourceAsFile("customRunnerTemplate", this.customRunnerTemplate, this.mavenProject);
this.customRunnerConfigurationFile = getResourceRetriever().getResourceAsFile("customRunnerConfiguration", this.customRunnerConfiguration, this.mavenProject);
this.reporters = getReporterRetriever().retrieveReporters(this.reporters, this.mavenProject);
this.fileSystemReporters = getReporterRetriever().retrieveFileSystemReporters(this.fileSystemReporters, this.getJasmineTargetDir(), this.mavenProject);
}
private ResourceRetriever getResourceRetriever() {
if (resourceRetriever == null) {
resourceRetriever = new ResourceRetriever(resourceManager);
}
return resourceRetriever;
}
private ReporterRetriever getReporterRetriever() {
if (reporterRetriever == null) {
reporterRetriever = new ReporterRetriever(getResourceRetriever());
}
return reporterRetriever;
}
}