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