Coverage Report - org.jbehave.core.embedder.Embedder
 
Classes in this File Line Coverage Branch Coverage Complexity
Embedder
88%
149/168
88%
48/54
2.333
Embedder$AnnotatedEmbedderRunFailed
100%
2/2
N/A
2.333
Embedder$AnnotatedEmbedderRunnerInstantiationFailed
100%
2/2
N/A
2.333
Embedder$ClassLoadingFailed
100%
2/2
N/A
2.333
Embedder$RunningStoriesFailed
100%
6/6
N/A
2.333
Embedder$ViewGenerationFailed
100%
2/2
N/A
2.333
 
 1  
 package org.jbehave.core.embedder;
 2  
 
 3  
 import java.io.File;
 4  
 import java.util.ArrayList;
 5  
 import java.util.Arrays;
 6  
 import java.util.List;
 7  
 import java.util.Properties;
 8  
 
 9  
 import org.apache.commons.lang.StringUtils;
 10  
 import org.apache.commons.lang.builder.ToStringBuilder;
 11  
 import org.apache.commons.lang.builder.ToStringStyle;
 12  
 import org.jbehave.core.Embeddable;
 13  
 import org.jbehave.core.configuration.Configuration;
 14  
 import org.jbehave.core.configuration.MostUsefulConfiguration;
 15  
 import org.jbehave.core.failures.BatchFailures;
 16  
 import org.jbehave.core.junit.AnnotatedEmbedderRunner;
 17  
 import org.jbehave.core.model.Story;
 18  
 import org.jbehave.core.model.StoryMap;
 19  
 import org.jbehave.core.reporters.ReportsCount;
 20  
 import org.jbehave.core.reporters.StepdocReporter;
 21  
 import org.jbehave.core.reporters.StoryReporterBuilder;
 22  
 import org.jbehave.core.reporters.ViewGenerator;
 23  
 import org.jbehave.core.steps.CandidateSteps;
 24  
 import org.jbehave.core.steps.StepFinder;
 25  
 import org.jbehave.core.steps.Stepdoc;
 26  
 import org.jbehave.core.steps.StepCollector.Stage;
 27  
 
 28  
 /**
 29  
  * Represents an entry point to all of JBehave's functionality that is
 30  
  * embeddable into other launchers, such as IDEs or CLIs.
 31  
  */
 32  
 public class Embedder {
 33  
 
 34  70
     private Configuration configuration = new MostUsefulConfiguration();
 35  70
     private List<CandidateSteps> candidateSteps = new ArrayList<CandidateSteps>();
 36  70
     private EmbedderControls embedderControls = new EmbedderControls();
 37  
     private StoryRunner storyRunner;
 38  
     private EmbedderMonitor embedderMonitor;
 39  70
     private List<String> metaFilters = Arrays.asList();
 40  
 
 41  
     public Embedder() {
 42  46
         this(new StoryRunner(), new PrintStreamEmbedderMonitor());
 43  46
     }
 44  
 
 45  70
     public Embedder(StoryRunner storyRunner, EmbedderMonitor embedderMonitor) {
 46  70
         this.storyRunner = storyRunner;
 47  70
         this.embedderMonitor = embedderMonitor;
 48  70
     }
 49  
 
 50  
     public void mapStoriesAsPaths(List<String> storyPaths) {
 51  0
         EmbedderControls embedderControls = embedderControls();
 52  0
         if (embedderControls.skip()) {
 53  0
             embedderMonitor.storiesSkipped(storyPaths);
 54  0
             return;
 55  
         }
 56  
 
 57  0
         StoryMapper storyMapper = new StoryMapper();
 58  0
         for (String storyPath : storyPaths) {
 59  0
             Story story = storyRunner.storyOfPath(configuration, storyPath);
 60  0
             embedderMonitor.mappingStory(storyPath, metaFilters);
 61  0
             storyMapper.map(story, new MetaFilter(""));
 62  0
             for (String filter : metaFilters) {
 63  0
                 storyMapper.map(story, new MetaFilter(filter));
 64  
             }
 65  0
         }
 66  
 
 67  0
         generateStoryMapsView(storyMapper.getStoryMaps());
 68  
 
 69  0
     }
 70  
 
 71  
     private void generateStoryMapsView(List<StoryMap> storyMaps) {
 72  0
         StoryReporterBuilder builder = configuration().storyReporterBuilder();
 73  0
         File outputDirectory = builder.outputDirectory();
 74  0
         ViewGenerator viewGenerator = configuration().viewGenerator();
 75  0
         viewGenerator.generateStoryMapsView(outputDirectory, storyMaps, builder.viewResources());
 76  0
     }
 77  
 
 78  
     public void runStoriesAsEmbeddables(List<String> classNames, EmbedderClassLoader classLoader) {
 79  9
         EmbedderControls embedderControls = embedderControls();
 80  9
         if (embedderControls.skip()) {
 81  1
             embedderMonitor.embeddablesSkipped(classNames);
 82  1
             return;
 83  
         }
 84  
 
 85  8
         BatchFailures batchFailures = new BatchFailures();
 86  8
         for (Embeddable embeddable : embeddables(classNames, classLoader)) {
 87  14
             String name = embeddable.getClass().getName();
 88  
             try {
 89  14
                 embedderMonitor.runningEmbeddable(name);
 90  14
                 embeddable.useEmbedder(this);
 91  14
                 embeddable.run();
 92  4
             } catch (Throwable e) {
 93  4
                 if (embedderControls.batch()) {
 94  
                     // collect and postpone decision to throw exception
 95  2
                     batchFailures.put(name, e);
 96  
                 } else {
 97  2
                     if (embedderControls.ignoreFailureInStories()) {
 98  1
                         embedderMonitor.embeddableFailed(name, e);
 99  
                     } else {
 100  1
                         throw new RunningStoriesFailed(name, e);
 101  
                     }
 102  
                 }
 103  10
             }
 104  13
         }
 105  
 
 106  7
         if (embedderControls.batch() && batchFailures.size() > 0) {
 107  2
             if (embedderControls.ignoreFailureInStories()) {
 108  1
                 embedderMonitor.batchFailed(batchFailures);
 109  
             } else {
 110  1
                 throw new RunningStoriesFailed(batchFailures);
 111  
             }
 112  
         }
 113  
 
 114  6
         if (embedderControls.generateViewAfterStories()) {
 115  5
             generateStoriesView();
 116  
         }
 117  
 
 118  6
     }
 119  
 
 120  
     private List<Embeddable> embeddables(List<String> classNames, EmbedderClassLoader classLoader) {
 121  8
         List<Embeddable> embeddables = new ArrayList<Embeddable>();
 122  8
         for (String className : classNames) {
 123  16
             if (!classLoader.isAbstract(className)) {
 124  15
                 embeddables.add(classLoader.newInstance(Embeddable.class, className));
 125  
             }
 126  
         }
 127  8
         return embeddables;
 128  
     }
 129  
 
 130  
     public void runStoriesWithAnnotatedEmbedderRunner(String runnerClass, List<String> classNames,
 131  
             EmbedderClassLoader classLoader) {
 132  4
         List<AnnotatedEmbedderRunner> runners = annotatedEmbedderRunners(runnerClass, classNames, classLoader);
 133  3
         for (AnnotatedEmbedderRunner runner : runners) {
 134  
             try {
 135  3
                 Object annotatedInstance = runner.createTest();
 136  3
                 if (annotatedInstance instanceof Embeddable) {
 137  2
                     ((Embeddable) annotatedInstance).run();
 138  
                 } else {
 139  1
                     embedderMonitor.annotatedInstanceNotOfType(annotatedInstance, Embeddable.class);
 140  
                 }
 141  1
             } catch (Throwable e) {
 142  1
                 throw new AnnotatedEmbedderRunFailed(runner, e);
 143  2
             }
 144  
         }
 145  2
     }
 146  
 
 147  
     private List<AnnotatedEmbedderRunner> annotatedEmbedderRunners(String runnerClassName, List<String> classNames,
 148  
             EmbedderClassLoader classLoader) {
 149  4
         Class<?> runnerClass = loadClass(runnerClassName, classLoader);
 150  4
         List<AnnotatedEmbedderRunner> runners = new ArrayList<AnnotatedEmbedderRunner>();
 151  4
         for (String annotatedClassName : classNames) {
 152  4
             runners.add(newAnnotatedEmbedderRunner(runnerClass, annotatedClassName, classLoader));
 153  
         }
 154  3
         return runners;
 155  
     }
 156  
 
 157  
     private AnnotatedEmbedderRunner newAnnotatedEmbedderRunner(Class<?> runnerClass, String annotatedClassName,
 158  
             EmbedderClassLoader classLoader) {
 159  
         try {
 160  4
             Class<?> annotatedClass = loadClass(annotatedClassName, classLoader);
 161  3
             return (AnnotatedEmbedderRunner) runnerClass.getConstructor(Class.class).newInstance(annotatedClass);
 162  1
         } catch (Exception e) {
 163  1
             throw new AnnotatedEmbedderRunnerInstantiationFailed(runnerClass, annotatedClassName, classLoader, e);
 164  
         }
 165  
     }
 166  
 
 167  
     private Class<?> loadClass(String className, EmbedderClassLoader classLoader) {
 168  
         try {
 169  8
             return classLoader.loadClass(className);
 170  1
         } catch (ClassNotFoundException e) {
 171  1
             throw new ClassLoadingFailed(className, classLoader, e);
 172  
         }
 173  
     }
 174  
 
 175  
     public void runStoriesAsPaths(List<String> storyPaths) {
 176  19
         EmbedderControls embedderControls = embedderControls();
 177  19
         if (embedderControls.skip()) {
 178  1
             embedderMonitor.storiesSkipped(storyPaths);
 179  1
             return;
 180  
         }
 181  
 
 182  18
         Configuration configuration = configuration();
 183  18
         List<CandidateSteps> candidateSteps = candidateSteps();
 184  
 
 185  18
         storyRunner.runBeforeOrAfterStories(configuration, candidateSteps, Stage.BEFORE);
 186  
 
 187  18
         BatchFailures batchFailures = new BatchFailures();
 188  18
         buildReporters(configuration, storyPaths);
 189  18
         MetaFilter filter = new MetaFilter(StringUtils.join(metaFilters, " "), embedderMonitor);
 190  18
         for (String storyPath : storyPaths) {
 191  
             try {
 192  25
                 embedderMonitor.runningStory(storyPath);
 193  25
                 Story story = storyRunner.storyOfPath(configuration, storyPath);
 194  25
                 storyRunner.run(configuration, candidateSteps, story, filter);
 195  7
             } catch (Throwable e) {
 196  7
                 if (embedderControls.batch()) {
 197  
                     // collect and postpone decision to throw exception
 198  4
                     batchFailures.put(storyPath, e);
 199  
                 } else {
 200  3
                     if (embedderControls.ignoreFailureInStories()) {
 201  2
                         embedderMonitor.storyFailed(storyPath, e);
 202  
                     } else {
 203  1
                         throw new RunningStoriesFailed(storyPath, e);
 204  
                     }
 205  
                 }
 206  42
             }
 207  
         }
 208  
 
 209  17
         storyRunner.runBeforeOrAfterStories(configuration, candidateSteps, Stage.AFTER);
 210  
 
 211  17
         if (embedderControls.batch() && batchFailures.size() > 0) {
 212  2
             if (embedderControls.ignoreFailureInStories()) {
 213  1
                 embedderMonitor.batchFailed(batchFailures);
 214  
             } else {
 215  1
                 throw new RunningStoriesFailed(batchFailures);
 216  
             }
 217  
         }
 218  
 
 219  16
         if (embedderControls.generateViewAfterStories()) {
 220  13
             generateStoriesView();
 221  
         }
 222  
 
 223  16
     }
 224  
 
 225  
     private void buildReporters(Configuration configuration, List<String> storyPaths) {
 226  18
         StoryReporterBuilder reporterBuilder = configuration.storyReporterBuilder();
 227  18
         configuration.useStoryReporters(reporterBuilder.build(storyPaths));
 228  18
     }
 229  
 
 230  
     public void generateStoriesView() {
 231  18
         StoryReporterBuilder builder = configuration().storyReporterBuilder();
 232  18
         File outputDirectory = builder.outputDirectory();
 233  18
         List<String> formatNames = builder.formatNames(true);
 234  18
         generateStoriesView(outputDirectory, formatNames, builder.viewResources());
 235  18
     }
 236  
 
 237  
     public void generateStoriesView(File outputDirectory, List<String> formats, Properties viewResources) {
 238  23
         EmbedderControls embedderControls = embedderControls();
 239  
 
 240  23
         if (embedderControls.skip()) {
 241  1
             embedderMonitor.storiesViewNotGenerated();
 242  1
             return;
 243  
         }
 244  22
         ViewGenerator viewGenerator = configuration().viewGenerator();
 245  
         try {
 246  22
             embedderMonitor.generatingStoriesView(outputDirectory, formats, viewResources);
 247  22
             viewGenerator.generateReportsView(outputDirectory, formats, viewResources);
 248  1
         } catch (RuntimeException e) {
 249  1
             embedderMonitor.storiesViewGenerationFailed(outputDirectory, formats, viewResources, e);
 250  1
             throw new ViewGenerationFailed(outputDirectory, formats, viewResources, e);
 251  21
         }
 252  21
         ReportsCount count = viewGenerator.getReportsCount(); // countStories();
 253  21
         embedderMonitor.storiesViewGenerated(count.getStories(), count.getScenarios(), count.getFailedScenarios());
 254  21
         if (!embedderControls.ignoreFailureInView() && count.getFailedScenarios() > 0) {
 255  1
             throw new RunningStoriesFailed(count.getStories(), count.getScenarios(), count.getFailedScenarios());
 256  
         }
 257  
 
 258  20
     }
 259  
 
 260  
     public void reportStepdocs() {
 261  1
         Configuration configuration = configuration();
 262  1
         List<CandidateSteps> candidateSteps = candidateSteps();
 263  1
         StepFinder finder = configuration.stepFinder();
 264  1
         StepdocReporter reporter = configuration.stepdocReporter();
 265  1
         List<Object> stepsInstances = finder.stepsInstances(candidateSteps);
 266  1
         reporter.stepdocs(finder.stepdocs(candidateSteps), stepsInstances);
 267  1
     }
 268  
 
 269  
     public void reportMatchingStepdocs(String stepAsString) {
 270  3
         Configuration configuration = configuration();
 271  3
         List<CandidateSteps> candidateSteps = candidateSteps();
 272  3
         StepFinder finder = configuration.stepFinder();
 273  3
         StepdocReporter reporter = configuration.stepdocReporter();
 274  3
         List<Stepdoc> matching = finder.findMatching(stepAsString, candidateSteps);
 275  3
         List<Object> stepsInstances = finder.stepsInstances(candidateSteps);
 276  3
         reporter.stepdocsMatching(stepAsString, matching, stepsInstances);
 277  3
     }
 278  
 
 279  
     public Configuration configuration() {
 280  100
         return configuration;
 281  
     }
 282  
 
 283  
     public List<CandidateSteps> candidateSteps() {
 284  34
         return candidateSteps;
 285  
     }
 286  
 
 287  
     public EmbedderControls embedderControls() {
 288  58
         return embedderControls;
 289  
     }
 290  
 
 291  
     public EmbedderMonitor embedderMonitor() {
 292  2
         return embedderMonitor;
 293  
     }
 294  
 
 295  
     public List<String> metaFilters() {
 296  2
         return metaFilters;
 297  
     }
 298  
 
 299  
     public StoryRunner storyRunner() {
 300  2
         return storyRunner;
 301  
     }
 302  
 
 303  
     public void useConfiguration(Configuration configuration) {
 304  18
         this.configuration = configuration;
 305  18
     }
 306  
 
 307  
     public void useCandidateSteps(List<CandidateSteps> candidateSteps) {
 308  22
         this.candidateSteps = candidateSteps;
 309  22
     }
 310  
 
 311  
     public void useEmbedderControls(EmbedderControls embedderControls) {
 312  24
         this.embedderControls = embedderControls;
 313  24
     }
 314  
 
 315  
     public void useEmbedderMonitor(EmbedderMonitor embedderMonitor) {
 316  1
         this.embedderMonitor = embedderMonitor;
 317  1
     }
 318  
 
 319  
     public void useMetaFilters(List<String> metaFilters) {
 320  2
         this.metaFilters = metaFilters;
 321  2
     }
 322  
 
 323  
     public void useStoryRunner(StoryRunner storyRunner) {
 324  1
         this.storyRunner = storyRunner;
 325  1
     }
 326  
 
 327  
     @Override
 328  
     public String toString() {
 329  1
         return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
 330  
     }
 331  
 
 332  
     @SuppressWarnings("serial")
 333  
     public static class ClassLoadingFailed extends RuntimeException {
 334  
 
 335  
         public ClassLoadingFailed(String className, EmbedderClassLoader classLoader, Throwable cause) {
 336  1
             super("Failed to load class " + className + " with classLoader " + classLoader, cause);
 337  1
         }
 338  
 
 339  
     }
 340  
 
 341  
     @SuppressWarnings("serial")
 342  
     public static class AnnotatedEmbedderRunnerInstantiationFailed extends RuntimeException {
 343  
 
 344  
         public AnnotatedEmbedderRunnerInstantiationFailed(Class<?> runnerClass, String annotatedClassName,
 345  
                 EmbedderClassLoader classLoader, Throwable cause) {
 346  1
             super("Failed to instantiate annotated embedder runner " + runnerClass + " with annotatedClassName "
 347  
                     + annotatedClassName + " and classLoader " + classLoader, cause);
 348  1
         }
 349  
 
 350  
     }
 351  
 
 352  
     @SuppressWarnings("serial")
 353  
     public static class AnnotatedEmbedderRunFailed extends RuntimeException {
 354  
 
 355  
         public AnnotatedEmbedderRunFailed(AnnotatedEmbedderRunner runner, Throwable cause) {
 356  1
             super("Annotated embedder run failed with runner " + runner.toString(), cause);
 357  1
         }
 358  
 
 359  
     }
 360  
 
 361  
     @SuppressWarnings("serial")
 362  
     public static class RunningStoriesFailed extends RuntimeException {
 363  
 
 364  
         public RunningStoriesFailed(int stories, int scenarios, int failedScenarios) {
 365  1
             super("Failures in running " + stories + " stories containing " + scenarios + " scenarios (of which "
 366  
                     + failedScenarios + " failed)");
 367  1
         }
 368  
 
 369  
         public RunningStoriesFailed(BatchFailures failures) {
 370  2
             super("Failures in running stories in batch: " + failures);
 371  2
         }
 372  
 
 373  
         public RunningStoriesFailed(String name, Throwable cause) {
 374  2
             super("Failures in running story " + name, cause);
 375  2
         }
 376  
     }
 377  
 
 378  
     @SuppressWarnings("serial")
 379  
     public static class ViewGenerationFailed extends RuntimeException {
 380  
         public ViewGenerationFailed(File outputDirectory, List<String> formats, Properties viewResources,
 381  
                 RuntimeException cause) {
 382  1
             super("View generation failed to " + outputDirectory + " for formats " + formats + " and resources "
 383  
                     + viewResources, cause);
 384  1
         }
 385  
     }
 386  
 }