Coverage Report - org.jbehave.mojo.AbstractEmbedderMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractEmbedderMojo
93%
58/62
86%
19/22
1.439
AbstractEmbedderMojo$MavenEmbedderMonitor
47%
29/61
25%
1/4
1.439
 
 1  
 package org.jbehave.mojo;
 2  
 
 3  
 import org.apache.maven.plugin.AbstractMojo;
 4  
 import org.jbehave.core.ConfigurableEmbedder;
 5  
 import org.jbehave.core.InjectableEmbedder;
 6  
 import org.jbehave.core.embedder.Embedder;
 7  
 import org.jbehave.core.embedder.EmbedderClassLoader;
 8  
 import org.jbehave.core.embedder.EmbedderControls;
 9  
 import org.jbehave.core.embedder.EmbedderMonitor;
 10  
 import org.jbehave.core.embedder.MetaFilter;
 11  
 import org.jbehave.core.embedder.UnmodifiableEmbedderControls;
 12  
 import org.jbehave.core.failures.BatchFailures;
 13  
 import org.jbehave.core.io.StoryFinder;
 14  
 import org.jbehave.core.junit.AnnotatedEmbedderRunner;
 15  
 import org.jbehave.core.model.Meta;
 16  
 import org.jbehave.core.model.Story;
 17  
 import org.jbehave.core.model.StoryMaps;
 18  
 import org.jbehave.core.reporters.ReportsCount;
 19  
 
 20  
 import java.io.File;
 21  
 import java.net.MalformedURLException;
 22  
 import java.net.URL;
 23  
 import java.util.ArrayList;
 24  
 import java.util.List;
 25  
 import java.util.Properties;
 26  
 import java.util.concurrent.ExecutorService;
 27  
 
 28  
 import static org.apache.commons.lang.ArrayUtils.isNotEmpty;
 29  
 
 30  
 /**
 31  
  * Abstract mojo that holds all the configuration parameters to specify and load
 32  
  * stories.
 33  
  * 
 34  
  * @requiresDependencyResolution
 35  
  */
 36  27
 public abstract class AbstractEmbedderMojo extends AbstractMojo {
 37  
 
 38  
     static final String TEST_SCOPE = "test";
 39  
 
 40  
     /**
 41  
      * @parameter expression="${project.build.sourceDirectory}"
 42  
      * @required
 43  
      */
 44  
     String sourceDirectory;
 45  
 
 46  
     /**
 47  
      * @parameter expression="${project.build.testSourceDirectory}"
 48  
      * @required
 49  
      */
 50  
     String testSourceDirectory;
 51  
 
 52  
     /**
 53  
      * @parameter expression="${project.build.outputDirectory}"
 54  
      * @required
 55  
      */
 56  
     String outputDirectory;
 57  
 
 58  
     /**
 59  
      * @parameter expression="${project.build.testOutputDirectory}"
 60  
      * @required
 61  
      */
 62  
     String testOutputDirectory;
 63  
 
 64  
     /**
 65  
      * The scope of the mojo classpath, either "compile" or "test"
 66  
      * 
 67  
      * @parameter default-value="compile"
 68  
      */
 69  
     String scope;
 70  
 
 71  
     /**
 72  
      * Include filters, relative to the root source directory determined by the
 73  
      * scope
 74  
      * 
 75  
      * @parameter
 76  
      */
 77  
     List<String> includes;
 78  
 
 79  
     /**
 80  
      * Exclude filters, relative to the root source directory determined by the
 81  
      * scope
 82  
      * 
 83  
      * @parameter
 84  
      */
 85  
     List<String> excludes;
 86  
 
 87  
     /**
 88  
      * Compile classpath.
 89  
      * 
 90  
      * @parameter expression="${project.compileClasspathElements}"
 91  
      * @required
 92  
      * @readonly
 93  
      */
 94  
     List<String> compileClasspathElements;
 95  
 
 96  
     /**
 97  
      * Test classpath.
 98  
      * 
 99  
      * @parameter expression="${project.testClasspathElements}"
 100  
      * @required
 101  
      * @readonly
 102  
      */
 103  
     List<String> testClasspathElements;
 104  
 
 105  
     /**
 106  
      * The boolean flag to skip stories
 107  
      * 
 108  
      * @parameter default-value="false"
 109  
      */
 110  27
     boolean skip = false;
 111  
 
 112  
     /**
 113  
      * The boolean flag to run in batch mode
 114  
      * 
 115  
      * @parameter default-value="false"
 116  
      */
 117  27
     boolean batch = false;
 118  
 
 119  
     /**
 120  
      * The boolean flag to ignore failure in stories
 121  
      * 
 122  
      * @parameter default-value="false"
 123  
      */
 124  27
     boolean ignoreFailureInStories = false;
 125  
 
 126  
     /**
 127  
      * The boolean flag to ignore failure in view
 128  
      * 
 129  
      * @parameter default-value="false"
 130  
      */
 131  27
     boolean ignoreFailureInView = false;
 132  
 
 133  
     /**
 134  
      * The boolean flag to generate view after stories are run
 135  
      * 
 136  
      * @parameter default-value="true"
 137  
      */
 138  27
     boolean generateViewAfterStories = true;
 139  
 
 140  
     /**
 141  
      * The story timeout in secs
 142  
      * 
 143  
      * @parameter default-value="300"
 144  
      */
 145  27
     long storyTimeoutInSecs = 300;
 146  
 
 147  
     /**
 148  
      * The number of threads
 149  
      * 
 150  
      * @parameter default-value="1"
 151  
      */
 152  27
     int threads = 1;
 153  
 
 154  
     /**
 155  
      * The embedder class
 156  
      * 
 157  
      * @parameter default-value="org.jbehave.core.embedder.Embedder"
 158  
      */
 159  27
     String embedderClass = Embedder.class.getName();
 160  
 
 161  
     /**
 162  
      * The class that is injected with the embedder
 163  
      * 
 164  
      * @parameter
 165  
      */
 166  
     String injectableEmbedderClass;
 167  
 
 168  
     /**
 169  
      * The annotated embedder runner class
 170  
      * 
 171  
      * @parameter default-value="org.jbehave.core.junit.AnnotatedEmbedderRunner"
 172  
      * @deprecated Obsolete
 173  
      */
 174  27
     String annotatedEmbedderRunnerClass = AnnotatedEmbedderRunner.class.getName();
 175  
 
 176  
     /**
 177  
      * Used to find story paths and class names
 178  
      * 
 179  
      * @parameter
 180  
      */
 181  27
     String storyFinderClass = StoryFinder.class.getName();
 182  
 
 183  
     /**
 184  
      * The meta filter
 185  
      * 
 186  
      * @parameter
 187  
      */
 188  
     String[] metaFilters;
 189  
 
 190  
     /**
 191  
      * The system properties
 192  
      * 
 193  
      * @parameter
 194  
      */
 195  27
     Properties systemProperties = new Properties();
 196  
 
 197  
     /**
 198  
      * The class loader
 199  
      */
 200  
     private EmbedderClassLoader classLoader;
 201  
 
 202  
     /**
 203  
      * Determines if the scope of the mojo classpath is "test"
 204  
      * 
 205  
      * @return A boolean <code>true</code> if test scoped
 206  
      */
 207  
     boolean isTestScope() {
 208  30
         return TEST_SCOPE.equals(scope);
 209  
     }
 210  
 
 211  
     String searchDirectory() {
 212  11
         if (isTestScope()) {
 213  1
             return testSourceDirectory;
 214  
         }
 215  10
         return sourceDirectory;
 216  
     }
 217  
 
 218  
     String outputDirectory() {
 219  9
       if (isTestScope()) {
 220  0
           return testOutputDirectory;
 221  
       }
 222  9
       return outputDirectory;
 223  
     }
 224  
 
 225  
     URL codeLocation() {
 226  9
         String outputDirectory = outputDirectory();
 227  
         try {
 228  9
             return outputDirectory != null ? new File(outputDirectory).toURI().toURL() : null;
 229  0
         } catch (MalformedURLException e) {
 230  0
             throw new IllegalArgumentException("Failed to create code location from "+outputDirectory, e);
 231  
         }
 232  
     }
 233  
 
 234  
     /**
 235  
      * Returns the EmbedderClassLoader with the classpath element of the
 236  
      * selected scope.
 237  
      * 
 238  
      * @return An EmbedderClassLoader
 239  
      */
 240  
     protected EmbedderClassLoader classLoader() {
 241  9
         if (classLoader == null) {
 242  9
             classLoader = new EmbedderClassLoader(classpathElements());
 243  
         }
 244  9
         return classLoader;
 245  
     }
 246  
 
 247  
     List<String> classpathElements() {
 248  10
         List<String> classpathElements = compileClasspathElements;
 249  10
         if (isTestScope()) {
 250  1
             classpathElements = testClasspathElements;
 251  
         }
 252  10
         return classpathElements;
 253  
     }
 254  
 
 255  
     /**
 256  
      * Finds story paths, using the {@link #newStoryFinder()}, in the
 257  
      * {@link #searchDirectory()} given specified {@link #includes} and
 258  
      * {@link #excludes}.
 259  
      * 
 260  
      * @return A List of story paths found
 261  
      */
 262  
     protected List<String> storyPaths() {
 263  4
         getLog().debug("Searching for story paths including " + includes + " and excluding " + excludes);
 264  4
         List<String> storyPaths = newStoryFinder().findPaths(searchDirectory(), includes, excludes);
 265  4
         getLog().info("Found story paths: " + storyPaths);
 266  4
         return storyPaths;
 267  
     }
 268  
 
 269  
     /**
 270  
      * Finds class names, using the {@link #newStoryFinder()}, in the
 271  
      * {@link #searchDirectory()} given specified {@link #includes} and
 272  
      * {@link #excludes}.
 273  
      * 
 274  
      * @return A List of class names found
 275  
      */
 276  
     protected List<String> classNames() {
 277  6
         getLog().debug("Searching for class names including " + includes + " and excluding " + excludes);
 278  6
         List<String> classNames = newStoryFinder().findClassNames(searchDirectory(), includes, excludes);
 279  6
         getLog().info("Found class names: " + classNames);
 280  6
         return classNames;
 281  
     }
 282  
 
 283  
     /**
 284  
      * Creates an instance of StoryFinder, using the {@link #storyFinderClass}
 285  
      * 
 286  
      * @return A StoryFinder
 287  
      */
 288  
     protected StoryFinder newStoryFinder() {
 289  11
         return classLoader().newInstance(StoryFinder.class, storyFinderClass);
 290  
     }
 291  
 
 292  
     /**
 293  
      * Creates an instance of Embedder, either using
 294  
      * {@link #injectableEmbedderClass} (if set) or defaulting to
 295  
      * {@link #embedderClass}.
 296  
      * 
 297  
      * @return An Embedder
 298  
      */
 299  
     protected Embedder newEmbedder() {
 300  8
         Embedder embedder = null;
 301  8
         EmbedderClassLoader classLoader = classLoader();
 302  8
         if (injectableEmbedderClass != null) {
 303  1
             embedder = classLoader.newInstance(InjectableEmbedder.class, injectableEmbedderClass).injectedEmbedder();
 304  
         } else {
 305  7
             embedder = classLoader.newInstance(Embedder.class, embedderClass);
 306  
         }
 307  
 
 308  8
         URL codeLocation = codeLocation();
 309  8
         if (codeLocation != null) {
 310  0
           embedder.configuration().storyReporterBuilder().withCodeLocation(codeLocation);
 311  
         }
 312  
 
 313  8
         embedder.useClassLoader(classLoader);
 314  8
         embedder.useEmbedderControls(embedderControls());
 315  8
         embedder.useEmbedderMonitor(embedderMonitor());
 316  8
         if (isNotEmpty(metaFilters)) {
 317  2
             List<String> filters = new ArrayList<String>();
 318  6
             for ( String filter : metaFilters ){                
 319  4
                 if ( filter != null ){
 320  3
                     filters.add(filter);
 321  
                 }
 322  
             }
 323  2
             embedder.useMetaFilters(filters);
 324  
         }
 325  8
         if ( !systemProperties.isEmpty() ){
 326  1
             embedder.useSystemProperties(systemProperties);
 327  
         }
 328  8
         return embedder;
 329  
     }
 330  
 
 331  
     protected EmbedderMonitor embedderMonitor() {
 332  8
         return new MavenEmbedderMonitor();
 333  
     }
 334  
 
 335  
     protected EmbedderControls embedderControls() {
 336  8
         return new UnmodifiableEmbedderControls(new EmbedderControls().doBatch(batch).doSkip(skip)
 337  
                 .doGenerateViewAfterStories(generateViewAfterStories).doIgnoreFailureInStories(ignoreFailureInStories)
 338  
                 .doIgnoreFailureInView(ignoreFailureInView).useStoryTimeoutInSecs(storyTimeoutInSecs)
 339  
                 .useThreads(threads));
 340  
     }
 341  
 
 342  27
     protected class MavenEmbedderMonitor implements EmbedderMonitor {
 343  
 
 344  
         public void batchFailed(BatchFailures failures) {
 345  1
             getLog().warn("Failed to run batch " + failures);
 346  1
         }
 347  
         
 348  
         public void beforeOrAfterStoriesFailed() {
 349  0
             getLog().warn("Failed to run before or after stories steps");
 350  0
         }
 351  
 
 352  
         public void embeddableFailed(String name, Throwable cause) {
 353  1
             getLog().warn("Failed to run embeddable " + name, cause);
 354  1
         }
 355  
 
 356  
         public void embeddableNotConfigurable(String name) {
 357  0
             getLog().warn("Embeddable " + name + " must be an instance of " + ConfigurableEmbedder.class);
 358  0
         }
 359  
 
 360  
         public void embeddablesSkipped(List<String> classNames) {
 361  1
             getLog().info("Skipped embeddables " + classNames);
 362  1
         }
 363  
 
 364  
         public void metaNotAllowed(Meta meta, MetaFilter filter) {
 365  0
             getLog().info(meta + " excluded by filter '" + filter.asString() + "'");
 366  0
         }
 367  
 
 368  
         public void runningEmbeddable(String name) {
 369  1
             getLog().info("Running embeddable " + name);
 370  1
         }
 371  
 
 372  
         public void runningStory(String path) {
 373  1
             getLog().info("Running story " + path);
 374  1
         }
 375  
 
 376  
         public void storiesSkipped(List<String> storyPaths) {
 377  1
             getLog().info("Skipped stories " + storyPaths);
 378  1
         }
 379  
 
 380  
         public void storyFailed(String path, Throwable cause) {
 381  1
             getLog().warn("Failed to run story " + path, cause);
 382  1
         }
 383  
 
 384  
         public void runningWithAnnotatedEmbedderRunner(String className) {
 385  0
             getLog().info("Running with AnnotatedEmbedderRunner '" + className + "'");
 386  0
         }
 387  
 
 388  
         public void annotatedInstanceNotOfType(Object annotatedInstance, Class<?> type) {
 389  1
             getLog().warn("Annotated instance " + annotatedInstance + " not of type " + type);
 390  1
         }
 391  
 
 392  
         public void generatingReportsView(File outputDirectory, List<String> formats, Properties viewProperties) {
 393  1
             getLog().info(
 394  
                     "Generating reports view to '" + outputDirectory + "' using formats '" + formats + "'"
 395  
                             + " and view properties '" + viewProperties + "'");
 396  1
         }
 397  
 
 398  
         public void reportsViewGenerationFailed(File outputDirectory, List<String> formats, Properties viewProperties,
 399  
                 Throwable cause) {
 400  1
             String message = "Failed to generate reports view to '" + outputDirectory + "' using formats '" + formats
 401  
                     + "'" + " and view properties '" + viewProperties + "'";
 402  1
             getLog().warn(message, cause);
 403  1
         }
 404  
 
 405  
         public void reportsViewGenerated(ReportsCount count) {
 406  1
             getLog().info(
 407  
                     "Reports view generated with " + count.getStories() + " stories (of which "
 408  
                             + count.getStoriesPending() + " pending) containing " + count.getScenarios()
 409  
                             + " scenarios (of which " + count.getScenariosFailed() + " failed and "
 410  
                             + count.getScenariosPending() + " pending)");
 411  1
             if (count.getStoriesNotAllowed() > 0 || count.getScenariosNotAllowed() > 0) {
 412  1
                 getLog().info(
 413  
                         "Meta filters did not allow " + count.getStoriesNotAllowed() + " stories and  "
 414  
                                 + count.getScenariosNotAllowed() + " scenarios");
 415  
             }
 416  1
         }
 417  
 
 418  
         public void reportsViewNotGenerated() {
 419  1
             getLog().info("Reports view not generated");
 420  1
         }
 421  
 
 422  
         public void mappingStory(String storyPath, List<String> metaFilters) {
 423  0
             getLog().info("Mapping story " + storyPath + " with meta filters " + metaFilters);
 424  0
         }
 425  
 
 426  
         public void generatingMapsView(File outputDirectory, StoryMaps storyMaps, Properties viewProperties) {
 427  0
             getLog().info(
 428  
                     "Generating maps view to '" + outputDirectory + "' using story maps '" + storyMaps + "'"
 429  
                             + " and view properties '" + viewProperties + "'");
 430  0
         }
 431  
 
 432  
         public void mapsViewGenerationFailed(File outputDirectory, StoryMaps storyMaps, Properties viewProperties,
 433  
                 Throwable cause) {
 434  0
             getLog().warn(
 435  
                     "Failed to generate maps view to '" + outputDirectory + "' using story maps '" + storyMaps + "'"
 436  
                             + " and view properties '" + viewProperties + "'", cause);
 437  0
         }
 438  
 
 439  
         public void generatingNavigatorView(File outputDirectory, Properties viewProperties) {
 440  0
             getLog().info(
 441  
                     "Generating navigator view to '" + outputDirectory + "' using view properties '" + viewProperties
 442  
                             + "'");
 443  0
         }
 444  
 
 445  
         public void navigatorViewGenerationFailed(File outputDirectory, Properties viewProperties, Throwable cause) {
 446  0
             getLog().warn(
 447  
                     "Failed to generate navigator view to '" + outputDirectory + "' using view properties '"
 448  
                             + viewProperties + "'", cause);
 449  0
         }
 450  
 
 451  
         public void navigatorViewNotGenerated() {
 452  0
             getLog().warn(
 453  
                     "Navigator view not generated, as the CrossReference has not been declared in the StoryReporterBuilder");
 454  0
         }
 455  
 
 456  
         public void processingSystemProperties(Properties properties) {
 457  0
             getLog().info("Processing system properties " + properties);
 458  0
         }
 459  
 
 460  
         public void systemPropertySet(String name, String value) {
 461  0
             getLog().info("System property '" + name + "' set to '" + value + "'");
 462  0
         }
 463  
 
 464  
         public void storyTimeout(Story story, long durationInSecs, long timeoutInSecs) {
 465  0
             getLog().warn("Story " + story.getPath() + " duration of " + durationInSecs + " seconds has exceeded timeout of "+timeoutInSecs+" seconds");
 466  0
         }
 467  
 
 468  
         public void usingThreads(int threads) {
 469  0
             getLog().info("Using " + threads + " threads");
 470  0
         }
 471  
 
 472  
         public void usingExecutorService(ExecutorService executorService) {
 473  0
             getLog().info("Using executor service " + executorService);
 474  0
         }
 475  
 
 476  
         public void usingControls(EmbedderControls embedderControls) {
 477  0
             getLog().info("Using controls "+embedderControls);
 478  0
         }
 479  
 
 480  
         @Override
 481  
         public String toString() {
 482  1
             return this.getClass().getSimpleName();
 483  
         }
 484  
 
 485  
     }
 486  
 }