--- /dev/null
+package net.jaekl.cfb.analyze;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+
+import net.jaekl.cfb.CfbBundle;
+import net.jaekl.cfb.CfbBundleMock;
+import net.jaekl.cfb.util.Command;
+import net.jaekl.cfb.xml.messages.MessageCollection;
+import net.jaekl.cfb.xml.messages.MessagesData;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.helpers.DefaultHandler;
+
+public class HtmlReportTest {
+ private static class CheckWellFormedHandler extends DefaultHandler
+ {
+ @Override
+ public void warning(SAXParseException spe) throws SAXException
+ {
+ throw new SAXException(spe);
+ }
+
+ @Override
+ public void error(SAXParseException spe) throws SAXException
+ {
+ throw new SAXException(spe);
+ }
+
+ @Override
+ public void fatalError(SAXParseException spe) throws SAXException
+ {
+ throw new SAXException(spe);
+ }
+ }
+
+ String[] BUG_XMLS = {
+ BugReportData.getDmDefaultEncoding(),
+ BugReportData.getDmNumberCtor156(),
+ BugReportData.getRcnRedundantNullCheck(),
+ BugReportData.getVoVolatileIncrement()
+ };
+
+ private static final String PROJECT_NAME = "Project Name";
+ private static final String FIRST_VERSION = "1.0.1.3145";
+ private static final String SECOND_VERSION = "1.0.1.3146";
+
+ private CfbBundleMock m_bundle;
+ private MessageMapMock m_msgMap;
+
+ private Analysis analysisFromXml(String xml, String projectName, String version)
+ throws FileNotFoundException, IOException, SAXException
+ {
+ Analysis analysis = new Analysis(projectName, version);
+ ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes(Command.UTF_8));
+ InputSource inputSource = new InputSource(bais);
+ analysis.parse(inputSource);
+
+ return analysis;
+ }
+
+ private void assertContainsTagExactlyOnce(String html, String tag)
+ {
+ int pos = html.indexOf("<" + tag + ">");
+ assertTrue(pos >= 0);
+ String substr = html.substring(pos + 1);
+ assertFalse(substr.contains("<" + tag + ">"));
+ assertTrue(substr.contains("</" + tag + ">"));
+ }
+
+ private void checkForWellFormedXml(String xml) throws IOException, ParserConfigurationException, SAXException
+ {
+ SAXParserFactory spf = SAXParserFactory.newInstance();
+ spf.setValidating(false);
+ SAXParser parser = spf.newSAXParser();
+
+ try ( ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes(Command.UTF_8)) )
+ {
+ InputSource source = new InputSource(bais);
+ CheckWellFormedHandler handler = new CheckWellFormedHandler();
+
+ parser.parse(source, handler);
+ }
+ }
+
+ private String createReport(String firstXml, String secondXml) throws IOException, SAXException
+ {
+ Analysis first = null;
+ if (null != firstXml) {
+ first = analysisFromXml(firstXml, PROJECT_NAME, FIRST_VERSION);
+ }
+
+ Analysis second = analysisFromXml(secondXml, PROJECT_NAME, SECOND_VERSION);
+ Delta delta = new Delta(first, second);
+ MessageCollection msgColl = m_msgMap.getColl();
+ assertNotNull(msgColl);
+
+ HtmlReport htmlReport = new HtmlReport(m_bundle, msgColl, delta);
+
+ try (
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ )
+ {
+ htmlReport.write(pw);
+ pw.close();
+ sw.close();
+ return sw.toString();
+ }
+ }
+
+ private void doTestDelta(String firstXml, String secondXml) throws FileNotFoundException, IOException, SAXException, ParserConfigurationException
+ {
+ String html = createReport(firstXml, secondXml);
+ validateReport(html);
+ }
+
+ private void validateReport(String html) throws IOException, ParserConfigurationException, SAXException
+ {
+ assertNotNull(html);
+
+ // Report should be well-formed XHTML
+ checkForWellFormedXml(html);
+
+ // Certain tags should be present exactly once
+ for (String tag : new String[]{"HTML", "HEAD", "BODY", "STYLE"})
+ {
+ assertContainsTagExactlyOnce(html, tag);
+ }
+
+ // Title should be the result of translating CFB_REPORT
+ String title = m_bundle.get(CfbBundle.CFB_REPORT);
+ assertTrue(html.contains("<TITLE>" + title + "</TITLE>"));
+
+ // The character set UTF-8 should be specified
+ assertTrue(html.contains("<META CHARSET=\"UTF-8\"/>"));
+ }
+
+ @Before
+ public void setUp() throws FileNotFoundException, IOException, SAXException
+ {
+ m_bundle = new CfbBundleMock();
+ m_msgMap = new MessageMapMock();
+
+ try (ByteArrayInputStream bais = new ByteArrayInputStream(MessagesData.getData().getBytes(Command.UTF_8))) {
+ m_msgMap.parse(new InputSource(bais));
+ }
+ }
+
+ @Test
+ public void testVariousDeltas() throws FileNotFoundException, IOException, SAXException, ParserConfigurationException
+ {
+ StringBuilder sbFirst = new StringBuilder(BugReportData.getPrologue());
+ StringBuilder sbSecond = new StringBuilder(BugReportData.getPrologue());
+ for (int i = 0; i < BUG_XMLS.length; ++i) {
+ sbFirst.append(BUG_XMLS[i]);
+ for (int j = 0; j < BUG_XMLS.length; ++j) {
+ sbSecond.append(BUG_XMLS[j]);
+
+ String firstXml = sbFirst.toString() + BugReportData.getEpilogue();
+ String secondXml = sbSecond.toString() + BugReportData.getEpilogue();
+
+ doTestDelta(firstXml, secondXml);
+ }
+ }
+ }
+
+ @Test
+ public void testLocalVariable() throws FileNotFoundException, IOException, SAXException, ParserConfigurationException
+ {
+ String xml = BugReportData.getPrologue()
+ + BugReportData.getRcnRedundantNullCheck()
+ + BugReportData.getEpilogue();
+
+ String html = createReport(null, xml);
+ validateReport(html);
+
+ String expected = "con (LOCAL_VARIABLE_VALUE_OF)";
+ // expected string should be present exactly once
+ int pos = html.indexOf(expected);
+ assertTrue(pos > 0);
+ assertFalse(html.substring(pos + expected.length()).contains(expected));
+ }
+}