1   /***
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3   */
4   package test.net.sourceforge.pmd.renderers;
5   
6   import junit.framework.TestCase;
7   import net.sourceforge.pmd.Report;
8   import net.sourceforge.pmd.RuleContext;
9   import net.sourceforge.pmd.RuleViolation;
10  import net.sourceforge.pmd.renderers.XMLRenderer;
11  import org.w3c.dom.Element;
12  import org.xml.sax.InputSource;
13  import org.xml.sax.SAXException;
14  import test.net.sourceforge.pmd.testframework.MockRule;
15  
16  import javax.xml.parsers.DocumentBuilderFactory;
17  import javax.xml.parsers.ParserConfigurationException;
18  import java.io.IOException;
19  import java.io.StringReader;
20  
21  public class XMLRendererTest extends TestCase {
22  
23      private MockRule RULE1 = new MockRule("RULE1", "RULE1", "msg", "rulesetname", 3);
24      private MockRule RULE2 = new MockRule("RULE2", "RULE2", "msg", "rulesetname");
25      private RuleContext ctx = new RuleContext();
26  
27      public XMLRendererTest(String name) {
28          super(name);
29      }
30  
31      public void testEmptyReport() throws Throwable {
32          Element root = parseRootElement(new Report());
33          assertEquals("pmd", root.getNodeName());
34          assertNull(root.getFirstChild().getNextSibling()); // only one child, it's whitespace
35      }
36  
37      public void testErrorReport() throws Throwable {
38          Report report = new Report();
39          report.addError(new Report.ProcessingError("test_msg", "test_filename"));
40          Element root = parseRootElement(report);
41          assertEquals("test_msg", root.getFirstChild().getNextSibling().getAttributes().getNamedItem("msg").getNodeValue());
42      }
43  
44      public void testSingleReport() throws Throwable {
45          Report report = new Report();
46          ctx.setSourceCodeFilename("testSingleReport");
47          report.addRuleViolation(new RuleViolation(RULE1, 1, "Rule1", ctx));
48          Element root = parseRootElement(report);
49          assertEquals("testSingleReport", root.getFirstChild().getNextSibling().getAttributes().getNamedItem("name").getNodeValue());
50          assertEquals("RULE1", root.getFirstChild().getNextSibling().getFirstChild().getNextSibling().getAttributes().getNamedItem("rule").getNodeValue());
51          assertEquals("rulesetname", root.getFirstChild().getNextSibling().getFirstChild().getNextSibling().getAttributes().getNamedItem("ruleset").getNodeValue());
52          assertEquals("1", root.getFirstChild().getNextSibling().getFirstChild().getNextSibling().getAttributes().getNamedItem("line").getNodeValue());
53      }
54  
55      public void testDoubleReport() throws Throwable {
56          Report report = new Report();
57          ctx.setSourceCodeFilename("testDoubleReport");
58          report.addRuleViolation(new RuleViolation(RULE1, 1, "Rule1", ctx));
59          report.addRuleViolation(new RuleViolation(RULE2, 2, "Rule2", ctx));
60          Element root = parseRootElement(report);
61          assertEquals("RULE1", root.getFirstChild().getNextSibling().getFirstChild().getNextSibling().getAttributes().getNamedItem("rule").getNodeValue());
62          assertEquals("RULE2", root.getFirstChild().getNextSibling().getFirstChild().getNextSibling().getNextSibling().getNextSibling().getAttributes().getNamedItem("rule").getNodeValue());
63      }
64  
65      public void testTwoFiles() throws Throwable {
66          Report report = new Report();
67          ctx.setSourceCodeFilename("testTwoFiles_0");
68          report.addRuleViolation(new RuleViolation(RULE1, 1, "Rule1", ctx));
69          ctx.setSourceCodeFilename("testTwoFiles_1");
70          report.addRuleViolation(new RuleViolation(RULE1, 1, "Rule1", ctx));
71          Element root = parseRootElement(report);
72          assertEquals("testTwoFiles_0", root.getFirstChild().getNextSibling().getAttributes().getNamedItem("name").getNodeValue());
73          assertEquals("testTwoFiles_1", root.getFirstChild().getNextSibling().getNextSibling().getNextSibling().getAttributes().getNamedItem("name").getNodeValue());
74      }
75  
76      public void testUnorderedFiles() throws Throwable {
77          Report report = new Report();
78          ctx.setSourceCodeFilename("testTwoFiles_0");
79          report.addRuleViolation(new RuleViolation(RULE1, 1, "Rule1", ctx));
80  
81          ctx.setSourceCodeFilename("testTwoFiles_1");
82          report.addRuleViolation(new RuleViolation(RULE1, 1, "Rule1", ctx));
83  
84          ctx.setSourceCodeFilename("testTwoFiles_0");
85          report.addRuleViolation(new RuleViolation(RULE2, 2, "Rule2", ctx));
86  
87          Element root = parseRootElement(report);
88          assertEquals("testTwoFiles_0", root.getFirstChild().getNextSibling().getAttributes().getNamedItem("name").getNodeValue());
89          assertEquals("testTwoFiles_1", root.getFirstChild().getNextSibling().getNextSibling().getNextSibling().getAttributes().getNamedItem("name").getNodeValue());
90          assertEquals("RULE1", root.getFirstChild().getNextSibling().getFirstChild().getNextSibling().getAttributes().getNamedItem("rule").getNodeValue());
91          assertEquals("RULE2", root.getFirstChild().getNextSibling().getFirstChild().getNextSibling().getNextSibling().getNextSibling().getAttributes().getNamedItem("rule").getNodeValue());
92          assertEquals("RULE1", root.getFirstChild().getNextSibling().getNextSibling().getNextSibling().getFirstChild().getNextSibling().getAttributes().getNamedItem("rule").getNodeValue());
93      }
94  
95  
96      public void testEscaping() throws Throwable {
97          // <?xml version="1.0"?>
98          // <pmd>
99          //   <file name="testEscaping: Less than: &lt; Greater than: &gt; Ampersand: &amp; Quote: &quot; 'e' acute: &#233;">
100         //     <violation line="1" rule="RULE1">
101         // [RULE] Less than: &lt; Greater than: &gt; Ampersand: &amp; Quote: &quot; 'e' acute: &#233;
102         //     </violation>
103         //   </file>
104         // </pmd>
105         Report report = new Report();
106         ctx.setSourceCodeFilename("testEscaping: Less than: < Greater than: > Ampersand: & Quote: \" 'e' acute: \u00E9");
107         report.addRuleViolation(new RuleViolation(RULE1, 1, "[RULE] Less than: < Greater than: > Ampersand: & Quote: \" 'e' acute: \u00E9", ctx));
108         Element root = parseRootElement(report);
109         String out = root.getFirstChild().getNextSibling().toString();
110         // TODO - this works when run "manually" but not when run using Maven.  Must
111         // be some hideous XML difference.  Argh.
112 /*
113         assertTrue(out.indexOf("&gt;") != -1);
114         assertTrue(out.indexOf("&lt;") != -1);
115         assertTrue(out.indexOf("&amp;") != -1);
116         assertTrue(out.indexOf("&apos;") != -1);
117 */
118     }
119     private Element parseRootElement(Report rpt) throws SAXException, IOException, ParserConfigurationException {
120         return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(new XMLRenderer().render(rpt)))).getDocumentElement();
121     }
122 
123 }