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