All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.searls.jasmine.mojo.AbstractJasmineMojo Maven / Gradle / Ivy

Go to download

A JavaScript unit test plugin that processes JavaScript sources and Jasmine specs, prepares test runner HTML files, executes Jasmine specs headlessly with HtmlUnit, and produces JUnit XML reports

There is a newer version: 3.0-beta-02
Show newest version
/*-
 * #%L
 * jasmine-maven-plugin
 * %%
 * Copyright (C) 2010 - 2017 Justin Searls
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.github.searls.jasmine.mojo;

import com.github.searls.jasmine.config.ImmutableJasmineConfiguration;
import com.github.searls.jasmine.config.ImmutableServerConfiguration;
import com.github.searls.jasmine.config.JasmineConfiguration;
import com.github.searls.jasmine.config.ServerConfiguration;
import com.github.searls.jasmine.io.ScansDirectory;
import com.github.searls.jasmine.model.FileSystemReporter;
import com.github.searls.jasmine.model.ImmutableScriptSearch;
import com.github.searls.jasmine.model.Reporter;
import com.github.searls.jasmine.model.ScriptSearch;
import com.github.searls.jasmine.runner.ReporterType;
import com.github.searls.jasmine.runner.SpecRunnerTemplate;
import com.github.searls.jasmine.thirdpartylibs.ProjectClassLoaderFactory;
import com.google.common.annotations.VisibleForTesting;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;

public abstract class AbstractJasmineMojo extends AbstractMojo {

  protected static final String CUSTOM_RUNNER_CONFIGURATION_PARAM = "customRunnerConfiguration";
  protected static final String CUSTOM_RUNNER_TEMPLATE_PARAM = "customRunnerTemplate";

  // 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 = null;

  /**
   * 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 = null;

  /**
   * 

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 private List preloadSources = Collections.emptyList(); /** *

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 private String customRunnerTemplate = null; /** *

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 private String customRunnerConfiguration = null; /** *

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 private 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 private List fileSystemReporters = new ArrayList<>(); /** * Target directory for files created by the plugin. * * @since 1.1.0 */ @Parameter(defaultValue = "${project.build.directory}${file.separator}jasmine") private File jasmineTargetDir = null; /** * The name of the Spec Runner file. * * @since 1.1.0 */ @Parameter(defaultValue = "SpecRunner.html") private String specRunnerHtmlFileName = "SpecRunner.html"; /** * The name of the directory the specs will be deployed to on the server. * * @since 1.1.0 */ @Parameter(defaultValue = "spec") private String specDirectoryName = "spec"; /** * The name of the directory the sources will be deployed to on the server. * * @since 1.1.0 */ @Parameter(defaultValue = "src") private String srcDirectoryName = "src"; /** * The source encoding. * * @since 1.1.0 */ @Parameter(defaultValue = "${project.build.sourceEncoding}") private String sourceEncoding = StandardCharsets.UTF_8.name(); /** *

Allows specifying which source files should be included and in what order.

*
   * <sourceIncludes>
   *   <include>vendor/**/*.js</include>
   *   <include>myBootstrapFile.js</include>
   *   <include>**/*.js</include>
   * </sourceIncludes>
   * 
*
*

Default sourceIncludes:

*
   * <sourceIncludes>
   *   <include>**/*.js</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>
   * </specIncludes>
   * 
*
*

Default specIncludes:

*
   * <specIncludes>
   *   <include>**/*.js</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") private int serverPort = 8234; /** *

Specify the URI scheme in which to access the SpecRunner.

* * @since 1.3.1.4 */ @Parameter(property = "jasmine.uriScheme", defaultValue = "http") private String uriScheme = "http"; /** *

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") private String serverHostname = "localhost"; /** *

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") private SpecRunnerTemplate specRunnerTemplate = SpecRunnerTemplate.DEFAULT; /** *

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") private int autoRefreshInterval = 0; /** *

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(); private final MavenProject mavenProject; private final ReporterType reporterType; private final ResourceRetriever resourceRetriever; private final ReporterRetriever reporterRetriever; AbstractJasmineMojo(MavenProject mavenProject, ReporterType reporterType, ResourceRetriever resourceRetriever, ReporterRetriever reporterRetriever) { this.mavenProject = mavenProject; this.reporterType = reporterType; this.resourceRetriever = resourceRetriever; this.reporterRetriever = reporterRetriever; } @Override public void execute() throws MojoExecutionException, MojoFailureException { try { this.run(getServerConfiguration(), getJasmineConfiguration()); } catch (MojoFailureException e) { throw e; } catch (Exception e) { throw new MojoExecutionException("The jasmine-maven-plugin encountered an exception:", e); } } protected final MavenProject getMavenProject() { return mavenProject; } protected abstract void run(ServerConfiguration serverConfiguration, JasmineConfiguration jasmineConfiguration) throws Exception; private ServerConfiguration getServerConfiguration() { return ImmutableServerConfiguration.builder() .uriScheme(this.uriScheme) .serverHostname(this.serverHostname) .serverPort(this.serverPort) .build(); } private JasmineConfiguration getJasmineConfiguration() throws MojoExecutionException { return ImmutableJasmineConfiguration.builder() .customRunnerConfiguration(getCustomRunnerConfigurationFile()) .customRunnerTemplate(getCustomRunnerTemplateFile()) .contexts(getContexts()) .projectClassLoader(getProjectClassLoader()) .autoRefreshInterval(this.autoRefreshInterval) .preloadSources(this.preloadSources) .basedir(this.mavenProject.getBasedir()) .srcDirectoryName(this.srcDirectoryName) .sources(this.getSources()) .specDirectoryName(this.specDirectoryName) .specs(this.getSpecs()) .specRunnerHtmlFileName(this.specRunnerHtmlFileName) .specRunnerTemplate(this.specRunnerTemplate) .reporters(getReporters()) .fileSystemReporters(getFileSystemReporters()) .reporterType(this.reporterType) .jasmineTargetDir(this.jasmineTargetDir) .sourceEncoding(this.sourceEncoding) .build(); } private List getFileSystemReporters() throws MojoExecutionException { return reporterRetriever.retrieveFileSystemReporters( this.fileSystemReporters, this.jasmineTargetDir, this.mavenProject ); } private Optional getCustomRunnerTemplateFile() throws MojoExecutionException { return resourceRetriever.getResourceAsFile( CUSTOM_RUNNER_TEMPLATE_PARAM, this.customRunnerTemplate, this.mavenProject ); } private Optional getCustomRunnerConfigurationFile() throws MojoExecutionException { return resourceRetriever.getResourceAsFile( CUSTOM_RUNNER_CONFIGURATION_PARAM, this.customRunnerConfiguration, this.mavenProject ); } private List getReporters() throws MojoExecutionException { return reporterRetriever.retrieveReporters(this.reporters, this.mavenProject); } private ClassLoader getProjectClassLoader() { return new ProjectClassLoaderFactory(mavenProject.getArtifacts()).create(); } private 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; } private ScriptSearch getSpecs() { return ImmutableScriptSearch.builder() .directory(this.jsTestSrcDir) .includes(this.specIncludes) .excludes(this.specExcludes) .build(); } private ScriptSearch getSources() { return ImmutableScriptSearch.builder() .directory(this.jsSrcDir) .includes(this.sourceIncludes) .excludes(this.sourceExcludes) .build(); } @VisibleForTesting void setJsSrcDir(File jsSrcDir) { this.jsSrcDir = jsSrcDir; } @VisibleForTesting void setJsTestSrcDir(File jsTestSrcDir) { this.jsTestSrcDir = jsTestSrcDir; } @VisibleForTesting void setJasmineTargetDir(File jasmineTargetDir) { this.jasmineTargetDir = jasmineTargetDir; } @VisibleForTesting void setSourceEncoding(String sourceEncoding) { this.sourceEncoding = sourceEncoding; } @VisibleForTesting void setCustomRunnerConfiguration(String customRunnerConfiguration) { this.customRunnerConfiguration = customRunnerConfiguration; } @VisibleForTesting void setCustomRunnerTemplate(String customRunnerTemplate) { this.customRunnerTemplate = customRunnerTemplate; } @VisibleForTesting void setReporters(List reporters) { this.reporters = reporters; } @VisibleForTesting void setFileSystemReporters(List fileSystemReporters) { this.fileSystemReporters = fileSystemReporters; } void setAutoRefreshInterval(int autoRefreshInterval) { this.autoRefreshInterval = autoRefreshInterval; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy