Coverage Report - org.jbehave.core.reporters.StoryReporterBuilder
 
Classes in this File Line Coverage Branch Coverage Complexity
StoryReporterBuilder
87%
70/80
77%
14/18
1.222
StoryReporterBuilder$Format
100%
10/10
N/A
1.222
StoryReporterBuilder$ProvidedFormat
100%
4/4
N/A
1.222
 
 1  
 package org.jbehave.core.reporters;
 2  
 
 3  
 import java.io.File;
 4  
 import java.net.URL;
 5  
 import java.util.ArrayList;
 6  
 import java.util.HashMap;
 7  
 import java.util.List;
 8  
 import java.util.Locale;
 9  
 import java.util.Map;
 10  
 import java.util.Properties;
 11  
 
 12  
 import org.jbehave.core.configuration.Keywords;
 13  
 import org.jbehave.core.i18n.LocalizedKeywords;
 14  
 import org.jbehave.core.io.CodeLocations;
 15  
 import org.jbehave.core.io.StoryLocation;
 16  
 import org.jbehave.core.reporters.FilePrintStreamFactory.FileConfiguration;
 17  
 import org.jbehave.core.reporters.FilePrintStreamFactory.FilePathResolver;
 18  
 
 19  
 import static java.util.Arrays.asList;
 20  
 
 21  
 /**
 22  
  * <p>
 23  
  * A <a href="http://en.wikipedia.org/wiki/Builder_pattern">Builder</a> for
 24  
  * {@link StoryReporter}s. It builds a {@link DelegatingStoryReporter} with
 25  
  * delegates for a number of formats - mostly file-based ones except
 26  
  * {@Format.CONSOLE}. It requires a
 27  
  * {@link FilePrintStreamFactory} and provides default delegate instances for
 28  
  * each format.
 29  
  * </p>
 30  
  * <p>
 31  
  * To build a reporter for a single story path with default and given formats:
 32  
  * 
 33  
  * <pre>
 34  
  * Class&lt;MyStory&gt; storyClass = MyStory.class;
 35  
  * StoryPathResolver resolver = new UnderscoredCamelCaseResolver();
 36  
  * String storyPath = resolver.resolve(storyClass);
 37  
  * StoryReporter reporter = new StoryReporterBuilder().withCodeLocation(CodeLocations.codeLocationFromClass(storyClass))
 38  
  *         .withDefaultFormats().withFormats(TXT, HTML, XML).build(storyPath);
 39  
  * </pre>
 40  
  * 
 41  
  * </p>
 42  
  * <p>
 43  
  * The builder is configured to build with the {@link Format#STATS} as default
 44  
  * format. To change the default formats the user can override the method:
 45  
  * 
 46  
  * <pre>
 47  
  * new StoryReporterBuilder() {
 48  
  *     protected StoryReporterBuilder withDefaultFormats() {
 49  
  *         return withFormats(STATS);
 50  
  *     }
 51  
  * }
 52  
  * </pre>
 53  
  * 
 54  
  * </p>
 55  
  * <p>
 56  
  * The builder configures the file-based reporters to output to the default file
 57  
  * directory {@link FileConfiguration#DIRECTORY} as relative to the code
 58  
  * location. In some case, e.g. with Ant class loader, the code source location
 59  
  * from class may not be properly set. In this case, we may specify it from a
 60  
  * file:
 61  
  * 
 62  
  * <pre>
 63  
  * new StoryReporterBuilder().withCodeLocation(CodeLocations.codeLocationFromFile(new File(&quot;target/classes&quot;)))
 64  
  *         .withDefaultFormats().withFormats(TXT, HTML, XML).build(storyPath);
 65  
  * </pre>
 66  
  * 
 67  
  * </p>
 68  
  * <p>
 69  
  * By default, the reporters will output minimal failure information, the single
 70  
  * line describing the failure cause and the outcomes if failures occur. To
 71  
  * configure the failure trace to be reported as well:
 72  
  * 
 73  
  * <pre>
 74  
  * new StoryReporterBuilder().withFailureTrace(true)
 75  
  * </pre>
 76  
  * 
 77  
  * </p>
 78  
  * <p>
 79  
  * If failure trace is reported, it is with the full stack trace. In some cases,
 80  
  * it's useful to have it compressed, eliminating unnecessary lines that are not
 81  
  * very informative:
 82  
  * 
 83  
  * <pre>
 84  
  * new StoryReporterBuilder().withFailureTraceCompression(true)
 85  
  * </pre>
 86  
  * 
 87  
  * </p>
 88  
  * 
 89  
  * <p>
 90  
  * To specify the use of keywords for a given locale:
 91  
  * 
 92  
  * <pre>
 93  
  * new StoryReporterBuilder().withKeywords(new LocalisedKeywords(Locale.IT)
 94  
  * </pre>
 95  
  * 
 96  
  * </p>
 97  
  * 
 98  
  * <p>
 99  
  * The builder provides default instances for all reporters, using the default
 100  
  * output patterns. To change the reporter for a specific instance, e.g. to
 101  
  * report format <b>TXT</b> to <b>.text</b> files and to inject other
 102  
  * non-default parameters, such as the custom output patterns:
 103  
  * 
 104  
  * <pre>
 105  
  * new StoryReporterBuilder(){
 106  
  *   public StoryReporter reporterFor(String storyPath, Format format){
 107  
  *       FilePrintStreamFactory factory = new FilePrintStreamFactory(new StoryLocation(storyPath, codeLocation));
 108  
  *       switch (format) {
 109  
  *           case TXT:
 110  
  *               factory.useConfiguration(new FileConfiguration("text"));
 111  
  *               Properties customPatterns = new Properties();
 112  
  *               customPatterns.setProperty("successful", "{0}(YEAH!!!)\n");
 113  
  *               return new TxtOutput(factory.createPrintStream(), customPatterns, keywords);
 114  
  *            default:
 115  
  *               return super.reporterFor(format);
 116  
  *   }
 117  
  * }
 118  
  * </pre>
 119  
  * 
 120  
  * </p>
 121  
  */
 122  
 public class StoryReporterBuilder {
 123  
 
 124  8
     public enum Format {
 125  1
         CONSOLE(org.jbehave.core.reporters.Format.CONSOLE),
 126  1
         IDE_CONSOLE(org.jbehave.core.reporters.Format.IDE_CONSOLE),
 127  1
         TXT(org.jbehave.core.reporters.Format.TXT),
 128  1
         HTML(org.jbehave.core.reporters.Format.HTML),
 129  1
         XML(org.jbehave.core.reporters.Format.XML),
 130  1
         STATS(org.jbehave.core.reporters.Format.STATS);
 131  
 
 132  
         private org.jbehave.core.reporters.Format realFormat;
 133  
 
 134  6
         Format(org.jbehave.core.reporters.Format realFormat) {
 135  6
             this.realFormat = realFormat;
 136  6
         }
 137  
 
 138  
     }
 139  
 
 140  300
     private List<org.jbehave.core.reporters.Format> formats = new ArrayList<org.jbehave.core.reporters.Format>();
 141  
     private String relativeDirectory;
 142  
     private FilePathResolver pathResolver;
 143  
     private URL codeLocation;
 144  
     private Properties viewResources;
 145  300
     private boolean reportFailureTrace = false;
 146  300
     private boolean compressFailureTrace = false;
 147  
     private Keywords keywords;
 148  
     private CrossReference crossReference;
 149  
     private boolean multiThreading;
 150  
     
 151  300
     public StoryReporterBuilder() {
 152  300
             relativeDirectory = new FileConfiguration().getRelativeDirectory();
 153  300
             pathResolver = new FileConfiguration().getPathResolver();
 154  300
             codeLocation = CodeLocations.codeLocationFromPath("target/classes");
 155  300
             viewResources = new FreemarkerViewGenerator().defaultViewProperties();
 156  300
             keywords = new LocalizedKeywords();
 157  300
     }
 158  
 
 159  
     public File outputDirectory() {
 160  17
         return filePrintStreamFactory("").outputDirectory();
 161  
     }
 162  
 
 163  
     public String relativeDirectory() {
 164  1
         return relativeDirectory;
 165  
     }
 166  
 
 167  
     public FilePathResolver pathResolver() {
 168  2
         return pathResolver;
 169  
     }
 170  
 
 171  
     public URL codeLocation() {
 172  1
         return codeLocation;
 173  
     }
 174  
 
 175  
     public List<org.jbehave.core.reporters.Format> formats() {
 176  2
         return formats;
 177  
     }
 178  
 
 179  
     public List<String> formatNames(boolean toLowerCase) {
 180  16
         Locale locale = Locale.getDefault();
 181  16
         if (keywords instanceof LocalizedKeywords) {
 182  16
             locale = ((LocalizedKeywords) keywords).getLocale();
 183  
         }
 184  16
         List<String> names = new ArrayList<String>();
 185  16
         for (org.jbehave.core.reporters.Format format : formats) {
 186  33
             String name = format.name();
 187  33
             if (toLowerCase) {
 188  19
                 name = name.toLowerCase(locale);
 189  
             }
 190  33
             names.add(name);
 191  33
         }
 192  16
         return names;
 193  
     }
 194  
 
 195  
     public Keywords keywords() {
 196  31
         return keywords;
 197  
     }
 198  
 
 199  
     public boolean multiThreading(){
 200  0
         return multiThreading;
 201  
     }
 202  
     
 203  
     public boolean reportFailureTrace() {
 204  31
         return reportFailureTrace;
 205  
     }
 206  
 
 207  
     public boolean compressFailureTrace() {
 208  30
         return compressFailureTrace;
 209  
     }
 210  
 
 211  
     public Properties viewResources() {
 212  14
         return viewResources;
 213  
     }
 214  
 
 215  
     public StoryReporterBuilder withRelativeDirectory(String relativeDirectory) {
 216  3
         this.relativeDirectory = relativeDirectory;
 217  3
         return this;
 218  
     }
 219  
 
 220  
     public StoryReporterBuilder withPathResolver(FilePathResolver pathResolver) {
 221  1
         this.pathResolver = pathResolver;
 222  1
         return this;
 223  
     }
 224  
 
 225  
     public StoryReporterBuilder withCodeLocation(URL codeLocation) {
 226  1
         this.codeLocation = codeLocation;
 227  1
         return this;
 228  
     }
 229  
 
 230  
     public CrossReference crossReference() {
 231  1
         return crossReference;
 232  
     }
 233  
 
 234  
     public boolean hasCrossReference() {
 235  17
         return crossReference != null;
 236  
     }
 237  
 
 238  
     public StoryReporterBuilder withCrossReference(CrossReference crossReference) {
 239  1
         this.crossReference = crossReference;
 240  1
         return this;
 241  
     }
 242  
 
 243  
     public StoryReporterBuilder withDefaultFormats() {
 244  7
         return withFormats(Format.STATS);
 245  
     }
 246  
 
 247  
     /**
 248  
      * @deprecated Use {@link withFormats(org.jbehave.core.reporters.Format... formats)}
 249  
      */
 250  
     @Deprecated
 251  
     public StoryReporterBuilder withFormats(Format... formats) {
 252  7
         List<org.jbehave.core.reporters.Format> formatz = new ArrayList<org.jbehave.core.reporters.Format>();
 253  14
         for (Format format : formats) {
 254  7
             formatz.add(format.realFormat);
 255  
         }
 256  7
         this.formats.addAll(formatz);
 257  7
         return this;
 258  
     }
 259  
 
 260  
     public StoryReporterBuilder withFormats(org.jbehave.core.reporters.Format... formats) {
 261  16
         this.formats.addAll(asList(formats));
 262  16
         return this;
 263  
     }
 264  
 
 265  
     public StoryReporterBuilder withReporters(StoryReporter... reporters) {
 266  3
         for (StoryReporter reporter : reporters) {
 267  2
             this.formats.add(new ProvidedFormat(reporter));
 268  
         }
 269  1
         return this;
 270  
     }
 271  
 
 272  
     public StoryReporterBuilder withFailureTrace(boolean reportFailureTrace) {
 273  1
         this.reportFailureTrace = reportFailureTrace;
 274  1
         return this;
 275  
     }
 276  
 
 277  
     public StoryReporterBuilder withFailureTraceCompression(boolean compressFailureTrace) {
 278  0
         this.compressFailureTrace = compressFailureTrace;
 279  0
         return this;
 280  
     }
 281  
 
 282  
     public StoryReporterBuilder withKeywords(Keywords keywords) {
 283  3
         this.keywords = keywords;
 284  3
         return this;
 285  
     }
 286  
 
 287  
     public StoryReporterBuilder withMultiThreading(boolean multiThreading) {
 288  117
         this.multiThreading = multiThreading;
 289  117
         return this;
 290  
     }
 291  
 
 292  
     public StoryReporterBuilder withViewResources(Properties resources) {
 293  1
         this.viewResources = resources;
 294  1
         return this;
 295  
     }
 296  
 
 297  
     public StoryReporter build(String storyPath) {
 298  19
         Map<org.jbehave.core.reporters.Format, StoryReporter> delegates = new HashMap<org.jbehave.core.reporters.Format, StoryReporter>();
 299  19
         for (org.jbehave.core.reporters.Format format : formats) {
 300  42
             delegates.put(format, reporterFor(storyPath, format));
 301  42
         }
 302  
 
 303  19
         DelegatingStoryReporter delegate = new DelegatingStoryReporter(delegates.values());
 304  19
         StoryReporter crossReferencing = (crossReference == null ? new NullStoryReporter() : reporterFor(storyPath,
 305  
                 crossReference));
 306  19
         return new ConcurrentStoryReporter(crossReferencing, delegate, multiThreading);
 307  
     }
 308  
 
 309  
     public Map<String, StoryReporter> build(List<String> storyPaths) {
 310  0
         Map<String, StoryReporter> reporters = new HashMap<String, StoryReporter>();
 311  0
         for (String storyPath : storyPaths) {
 312  0
             reporters.put(storyPath, build(storyPath));
 313  0
         }
 314  0
         reporters.put("*", build("*"));
 315  0
         return reporters;
 316  
     }
 317  
 
 318  
     public StoryReporter reporterFor(String storyPath, Format format) {
 319  0
         return reporterFor(storyPath, format.realFormat);
 320  
     }
 321  
 
 322  
     public StoryReporter reporterFor(String storyPath, org.jbehave.core.reporters.Format format) {
 323  40
         FilePrintStreamFactory factory = filePrintStreamFactory(storyPath);
 324  40
         return format.createStoryReporter(factory, this);
 325  
     }
 326  
 
 327  
     protected FilePrintStreamFactory filePrintStreamFactory(String storyPath) {
 328  56
         return new FilePrintStreamFactory(new StoryLocation(codeLocation, storyPath), fileConfiguration(""));
 329  
     }
 330  
 
 331  
     public FileConfiguration fileConfiguration(String extension) {
 332  88
         return new FileConfiguration(relativeDirectory, extension, pathResolver);
 333  
     }
 334  
 
 335  
     /**
 336  
      * A Format that wraps a StoryReporter instance provided.
 337  
      */
 338  
     public static class ProvidedFormat extends org.jbehave.core.reporters.Format {
 339  
 
 340  
         private final StoryReporter reporter;
 341  
 
 342  
         public ProvidedFormat(StoryReporter reporter) {
 343  2
             super(reporter.getClass().getSimpleName());
 344  2
             this.reporter = reporter;
 345  2
         }
 346  
 
 347  
         @Override
 348  
         public StoryReporter createStoryReporter(FilePrintStreamFactory factory,
 349  
                 StoryReporterBuilder storyReporterBuilder) {
 350  2
             return reporter;
 351  
         }
 352  
         
 353  
     }
 354  
 }