View Javadoc

1   /*
2    * Copyright 2010-2013 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.testdoc.maven.export.sink;
17  
18  import java.io.IOException;
19  import java.io.OutputStream;
20  import java.util.List;
21  
22  import org.apache.maven.doxia.sink.Sink;
23  import org.slf4j.Logger;
24  import org.slf4j.LoggerFactory;
25  
26  import de.smartics.maven.util.report.MessageHelper;
27  import de.smartics.maven.util.report.link.ExternalReport;
28  import de.smartics.testdoc.maven.export.AbstractReportExporter;
29  import de.smartics.testdoc.core.doc.ScenarioTestDoc;
30  import de.smartics.testdoc.core.doc.TestMethodDoc;
31  import de.smartics.testdoc.core.doc.Type;
32  import de.smartics.testdoc.core.doc.UnitTestDoc;
33  import de.smartics.testdoc.report.export.doc.ExternalReportReferences;
34  import de.smartics.testdoc.report.export.doc.ImageHelper;
35  import de.smartics.testdoc.report.export.doc.TestDocHelper;
36  import de.smartics.testdoc.report.junit.JUnitTestCaseDoc;
37  import de.smartics.testdoc.report.junit.JUnitTestCaseManager;
38  import de.smartics.testdoc.report.junit.JUnitTestMethodDoc;
39  import de.smartics.testdoc.report.junit.JUnitTestMethodDoc.ResultType;
40  import de.smartics.testdoc.report.junit.TestCaseReportException;
41  
42  /**
43   * Exports the test documentation to a sink.
44   *
45   * @author <a href="mailto:robert.reiner@smartics.de">Robert Reiner</a>
46   * @version $Revision:591 $
47   */
48  public class SinkExporter extends AbstractReportExporter
49  { // NOPMD
50    // ********************************* Fields *********************************
51  
52    // --- constants ------------------------------------------------------------
53  
54    // --- members --------------------------------------------------------------
55  
56    /**
57     * Reference to the logger for this class.
58     */
59    private final Logger log = LoggerFactory.getLogger(SinkExporter.class);
60  
61    /**
62     * The output medium to write to.
63     */
64    private final Sink sink;
65  
66    /**
67     * Helper for rendering page parts.
68     */
69    private final RenderHelper helper;
70  
71    // ****************************** Initializer *******************************
72  
73    // ****************************** Constructors ******************************
74  
75    /**
76     * Default constructor.
77     *
78     * @param messages the resource bundles with messages to display as labels in
79     *          the generated report.
80     * @param testDocHelper the value for testDocHelper.
81     * @param sink the output medium to write to.
82     */
83    public SinkExporter(final MessageHelper messages,
84        final TestDocHelper testDocHelper, final Sink sink)
85    {
86      super(messages, testDocHelper);
87      this.sink = sink;
88      this.helper = new RenderHelper(messages, sink);
89    }
90  
91    // ****************************** Inner Classes *****************************
92  
93    // ********************************* Methods ********************************
94  
95    // --- init -----------------------------------------------------------------
96  
97    // --- get&set --------------------------------------------------------------
98  
99    /**
100    * Returns the output medium to write to.
101    *
102    * @return the output medium to write to.
103    */
104   public Sink getSink()
105   {
106     return sink;
107   }
108 
109   // --- business -------------------------------------------------------------
110 
111   /**
112    * {@inheritDoc}
113    *
114    * @see de.smartics.testdoc.report.export.UnitTestDocExporter#export(de.smartics.testdoc.report.doc.UnitTestDoc,
115    *      java.io.OutputStream)
116    */
117   @Override
118   public void export(final UnitTestDoc testDoc, final OutputStream output)
119     throws NullPointerException, IOException
120   {
121     if (output != null)
122     {
123       throw new IllegalArgumentException(
124           "The sink implementation does not use the output stream."
125               + " Therefore the output is required to be 'null'");
126     }
127 
128     super.export(testDoc, null);
129   }
130 
131   @Override
132   protected void renderTableStart(final ScenarioTestDoc scenarioRepresentant)
133   {
134     sink.table();
135     sink.tableRow();
136 
137     renderRowNumberHeader();
138     renderJunitHeader();
139     renderScenarioHeader();
140     renderCategoriesHeader();
141     renderTestCaseHeader();
142 
143     sink.tableRow_();
144   }
145 
146   private void renderRowNumberHeader()
147   {
148     if (informationFilter.isShowNumbering())
149     {
150       sink.tableHeaderCell(messages
151           .getLabel("report.table.header.counter.width"));
152       final String label = messages.getLabel("report.table.header.counter");
153       sink.text(label);
154       sink.tableHeaderCell_();
155     }
156   }
157 
158   private void renderJunitHeader()
159   {
160     if (this.testDocHelper.isJUnitReportInformationRequested()
161         && informationFilter.isShowTestStatus())
162     {
163       sink.tableHeaderCell(messages
164           .getLabel("report.table.header.junitestcase.width"));
165       final String label =
166           messages.getLabel("report.table.header.junitestcase");
167       sink.text(label);
168       sink.tableHeaderCell_();
169     }
170   }
171 
172   private void renderScenarioHeader()
173   {
174     sink.tableHeaderCell();
175     final String scenarioLabel =
176         messages.getLabel("report.table.header.scenario");
177     sink.text(scenarioLabel);
178     sink.tableHeaderCell_();
179   }
180 
181   private void renderCategoriesHeader()
182   {
183     if (informationFilter.isShowCategories())
184     {
185       sink.tableHeaderCell(messages
186           .getLabel("report.table.header.categories.width"));
187       final String label = messages.getLabel("report.table.header.categories");
188       sink.text(label);
189       sink.tableHeaderCell_();
190     }
191   }
192 
193   private void renderTestCaseHeader()
194   {
195     if (informationFilter.isShowTestCase())
196     {
197       sink.tableHeaderCell(messages
198           .getLabel("report.table.header.testcase.width"));
199       final String label = messages.getLabel("report.table.header.testcase");
200       sink.text(label);
201       sink.tableHeaderCell_();
202     }
203   }
204 
205   @Override
206   protected void renderTestDocTypeStart(final UnitTestDoc testDoc)
207   {
208     final Type type = testDoc.getUutType();
209     final String id = type.toString();
210     final String name = type.getTypeName();
211 
212     sink.section3();
213 
214     helper.renderAnchor(id);
215     sink.sectionTitle3();
216     sink.text(name + " (" + type.getPackageName() + ')');
217     sink.sectionTitle3_();
218   }
219 
220   @Override
221   protected void renderTestDocTypeEnd(final UnitTestDoc testDoc)
222   {
223     sink.section3_();
224   }
225 
226   @Override
227   protected void renderTestDocUutReportLinks(final Type type,
228       final ExternalReportReferences reports)
229   {
230     sink.paragraph();
231     final UutLinkRenderer linkRenderer =
232         new UutLinkRenderer(sink, messages, type);
233     for (final ExternalReport report : reports.getUutReports())
234     {
235       linkRenderer.renderTestMethodLink(report);
236     }
237     sink.paragraph_();
238   }
239 
240   @Override
241   protected void renderRowNumber(final int counter)
242   {
243     if (informationFilter.isShowNumbering())
244     {
245       sink.tableCell();
246       sink.text(String.valueOf(counter));
247       sink.tableCell_();
248     }
249   }
250 
251   @Override
252   protected void renderJUnitStatus(final ScenarioTestDoc scenario)
253   {
254     if (this.testDocHelper.isJUnitReportInformationRequested()
255         && informationFilter.isShowTestStatus())
256     {
257       sink.tableCell();
258       final JUnitTestCaseManager junitManager = testDocHelper.getJunitManager();
259       final Type testCaseType = scenario.getTestCaseType();
260       final TestMethodDoc testMethod = scenario.getTestMethod();
261       final String testMethodName = testMethod.getTestName();
262       try
263       {
264         final JUnitTestCaseDoc testCase =
265             junitManager.readTestCase(testCaseType);
266         final JUnitTestMethodDoc method =
267             testCase.getTestMethod(testMethodName);
268 
269         final ImageHelper images = testDocHelper.getImageHelper();
270         final ResultType resultType = method.getResultType();
271         final String link = images.getImageLink(resultType);
272         renderJUnitStatusLink(resultType, link);
273       }
274       catch (final TestCaseReportException e)
275       {
276         if (log.isWarnEnabled())
277         {
278           log.warn("Cannot read JUnit information: " + e.getMessage());
279         }
280         sink.text("---");
281       }
282       sink.tableCell_();
283     }
284   }
285 
286   protected void renderJUnitStatusLink(final ResultType resultType,
287       final String link)
288   {
289     if (link != null)
290     {
291       sink.rawText("<div style='text-align:center;'>");
292       sink.figure();
293       sink.figureGraphics(link);
294       sink.figureCaption();
295       sink.text(String.valueOf(resultType));
296       sink.figureCaption_();
297       sink.figure_();
298       sink.rawText("</div>");
299     }
300     else
301     {
302       sink.text(String.valueOf(resultType));
303     }
304   }
305 
306   @Override
307   protected void renderSentence(final ScenarioTestDoc scenario)
308   {
309     sink.tableCell();
310     final String testSentence =
311         messages.getLabel(scenario.getId(), scenario.getTestMethod()
312             .getTestSentence());
313     sink.text(testSentence);
314     sink.tableCell_();
315   }
316 
317   @Override
318   protected void renderCategories(final ScenarioTestDoc scenario)
319   {
320     if (informationFilter.isShowCategories())
321     {
322       sink.tableCell();
323       final List<String> categories =
324           testDocHelper.filter(scenario.getCategories());
325       if (!categories.isEmpty())
326       {
327         if (categories.size() == 1)
328         {
329           final String category = categories.get(0);
330           sink.text(messages.getLabel(category));
331         }
332         else
333         {
334           // sink.list();
335           // for (final String category : categories)
336           // {
337           // sink.listItem();
338           // sink.text(messages.getLabel(category));
339           // sink.listItem_();
340           // }
341           // sink.list_();
342           for (final String category : categories)
343           {
344             sink.text(messages.getLabel(category) + ' ');
345           }
346         }
347       }
348       sink.tableCell_();
349     }
350   }
351 
352   @Override
353   protected void renderTestCase(final ScenarioTestDoc scenario)
354   {
355     if (informationFilter.isShowTestCase())
356     {
357       sink.tableCell();
358       final Type testCase = scenario.getTestCaseType();
359       sink.text(testCase.getTypeName());
360       final ExternalReportReferences reportRefs = testDocHelper.getReports();
361       final List<ExternalReport> reports = reportRefs.getTestCaseReports();
362       if (!reports.isEmpty())
363       {
364         sink.text(": ");
365 
366         final ScenarioLinkRenderer linkRenderer =
367             new ScenarioLinkRenderer(sink, messages, scenario);
368         for (final ExternalReport report : reports)
369         {
370           linkRenderer.renderTestMethodLink(report);
371         }
372       }
373       sink.tableCell_();
374     }
375   }
376 
377   @Override
378   protected void endScenario()
379   {
380     sink.tableRow_();
381   }
382 
383   @Override
384   protected void startScenario()
385   {
386     sink.tableRow();
387   }
388 
389   @Override
390   protected void renderTableEnd(final ScenarioTestDoc scenarioRepresentant)
391     throws IOException
392   {
393     super.renderTableEnd(scenarioRepresentant);
394 
395     sink.table_();
396   }
397 
398   /**
399    * Convenience method that matches the Sink design.
400    *
401    * @param testDoc the documentation to export.
402    */
403   public void export(final UnitTestDoc testDoc) throws IOException
404   {
405     export(testDoc, null);
406   }
407 
408   // --- object basics --------------------------------------------------------
409 
410 }