View Javadoc
1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd.renderers;
5   
6   import java.io.StringReader;
7   
8   import javax.xml.parsers.DocumentBuilderFactory;
9   
10  import net.sourceforge.pmd.FooRule;
11  import net.sourceforge.pmd.PMD;
12  import net.sourceforge.pmd.Report;
13  import net.sourceforge.pmd.Report.ProcessingError;
14  import net.sourceforge.pmd.ReportTest;
15  import net.sourceforge.pmd.RuleContext;
16  import net.sourceforge.pmd.RuleViolation;
17  import net.sourceforge.pmd.lang.ast.DummyNode;
18  import net.sourceforge.pmd.lang.ast.Node;
19  import net.sourceforge.pmd.lang.rule.ParametricRuleViolation;
20  
21  import org.junit.Assert;
22  import org.junit.Test;
23  import org.w3c.dom.Document;
24  import org.w3c.dom.NodeList;
25  import org.xml.sax.InputSource;
26  
27  public class XMLRendererTest extends AbstractRendererTst {
28  
29      @Override
30      public Renderer getRenderer() {
31          return new XMLRenderer();
32      }
33  
34      @Override
35      public String getExpected() {
36          return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
37                  + PMD.EOL
38                  + "<pmd version=\""
39                  + PMD.VERSION
40                  + "\" timestamp=\"2014-10-06T19:30:51.262\">"
41                  + PMD.EOL
42                  + "<file name=\"n/a\">"
43                  + PMD.EOL
44                  + "<violation beginline=\"1\" endline=\"1\" begincolumn=\"1\" endcolumn=\"1\" rule=\"Foo\" ruleset=\"RuleSet\" priority=\"5\">"
45                  + PMD.EOL + "blah" + PMD.EOL + "</violation>" + PMD.EOL + "</file>" + PMD.EOL + "</pmd>" + PMD.EOL;
46      }
47  
48      @Override
49      public String getExpectedEmpty() {
50          return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + PMD.EOL + "<pmd version=\"" + PMD.VERSION
51                  + "\" timestamp=\"2014-10-06T19:30:51.262\">" + PMD.EOL + "</pmd>" + PMD.EOL;
52      }
53  
54      @Override
55      public String getExpectedMultiple() {
56          return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
57                  + PMD.EOL
58                  + "<pmd version=\""
59                  + PMD.VERSION
60                  + "\" timestamp=\"2014-10-06T19:30:51.239\">"
61                  + PMD.EOL
62                  + "<file name=\"n/a\">"
63                  + PMD.EOL
64                  + "<violation beginline=\"1\" endline=\"1\" begincolumn=\"1\" endcolumn=\"1\" rule=\"Foo\" ruleset=\"RuleSet\" priority=\"5\">"
65                  + PMD.EOL
66                  + "blah"
67                  + PMD.EOL
68                  + "</violation>"
69                  + PMD.EOL
70                  + "<violation beginline=\"1\" endline=\"1\" begincolumn=\"1\" endcolumn=\"2\" rule=\"Foo\" ruleset=\"RuleSet\" priority=\"5\">"
71                  + PMD.EOL + "blah" + PMD.EOL + "</violation>" + PMD.EOL + "</file>" + PMD.EOL + "</pmd>" + PMD.EOL;
72      }
73  
74      @Override
75      public String getExpectedError(ProcessingError error) {
76          return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + PMD.EOL + "<pmd version=\"" + PMD.VERSION
77                  + "\" timestamp=\"2014-10-06T19:30:51.222\">" + PMD.EOL + "<error filename=\"file\" msg=\"Error\"/>"
78                  + PMD.EOL + "</pmd>" + PMD.EOL;
79      }
80  
81      @Override
82      public String filter(String expected) {
83          String result = expected.replaceAll(" timestamp=\"[^\"]+\">", " timestamp=\"\">");
84          return result;
85      }
86  
87      private static RuleViolation createRuleViolation(String description) {
88          DummyNode node = new DummyNode(1);
89          node.testingOnly__setBeginLine(1);
90          node.testingOnly__setBeginColumn(1);
91          node.testingOnly__setEndLine(1);
92          node.testingOnly__setEndColumn(1);
93          RuleContext ctx = new RuleContext();
94          ctx.setSourceCodeFilename("n/a");
95          return new ParametricRuleViolation<Node>(new FooRule(), ctx, node, description);
96      }
97  
98      private void verifyXmlEscaping(Renderer renderer, String shouldContain) throws Exception {
99          Report report = new Report();
100         String surrogatePair = "\ud801\udc1c";
101         String msg = "The String literal \"Tokenizer " + surrogatePair + "\" appears...";
102         report.addRuleViolation(createRuleViolation(msg));
103         String actual = ReportTest.render(renderer, report);
104         Assert.assertTrue(actual.contains(shouldContain));
105         Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new InputSource(new StringReader(actual)));
106         NodeList violations = doc.getElementsByTagName("violation");
107         Assert.assertEquals(1, violations.getLength());
108         Assert.assertEquals(msg,
109                 violations.item(0).getTextContent().trim());
110     }
111 
112     @Test
113     public void testXMLEscapingWithUTF8() throws Exception {
114         Renderer renderer = getRenderer();
115         renderer.setProperty(XMLRenderer.ENCODING, "UTF-8");
116         verifyXmlEscaping(renderer, "\ud801\udc1c");
117     }
118 
119     @Test
120     public void testXMLEscapingWithoutUTF8() throws Exception {
121         Renderer renderer = getRenderer();
122         renderer.setProperty(XMLRenderer.ENCODING, "ISO-8859-1");
123         verifyXmlEscaping(renderer, "&#x1041c;");
124     }
125 }