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