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