View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3    */
4   package net.sourceforge.pmd;
5   
6   import static org.junit.Assert.assertEquals;
7   import static org.junit.Assert.assertFalse;
8   import static org.junit.Assert.assertTrue;
9   
10  import java.io.IOException;
11  import java.io.StringWriter;
12  import java.util.Iterator;
13  import java.util.Map;
14  
15  import junit.framework.JUnit4TestAdapter;
16  import net.sourceforge.pmd.lang.Language;
17  import net.sourceforge.pmd.lang.LanguageVersion;
18  import net.sourceforge.pmd.lang.ecmascript.ast.ASTFunctionNode;
19  import net.sourceforge.pmd.lang.ecmascript.rule.AbstractEcmascriptRule;
20  import net.sourceforge.pmd.lang.ecmascript.rule.EcmascriptRuleViolationFactory;
21  import net.sourceforge.pmd.lang.java.ast.ASTClassOrInterfaceDeclaration;
22  import net.sourceforge.pmd.lang.java.ast.DummyJavaNode;
23  import net.sourceforge.pmd.lang.java.ast.JavaNode;
24  import net.sourceforge.pmd.lang.java.rule.AbstractJavaRule;
25  import net.sourceforge.pmd.lang.java.rule.JavaRuleViolation;
26  import net.sourceforge.pmd.lang.java.symboltable.SourceFileScope;
27  import net.sourceforge.pmd.lang.rule.MockRule;
28  import net.sourceforge.pmd.renderers.Renderer;
29  import net.sourceforge.pmd.renderers.XMLRenderer;
30  import net.sourceforge.pmd.stat.Metric;
31  import net.sourceforge.pmd.testframework.RuleTst;
32  
33  import org.junit.Test;
34  
35  
36  public class ReportTest extends RuleTst implements ReportListener {
37  
38      public static class FooRule extends AbstractJavaRule {
39          public Object visit(ASTClassOrInterfaceDeclaration c, Object ctx) {
40              if ("Foo".equals(c.getImage())) addViolation(ctx, c);
41              return ctx;
42          }
43  
44          public String getMessage() {
45              return "blah";
46          }
47  
48          public String getName() {
49              return "Foo";
50          }
51  
52          public String getRuleSetName() {
53              return "RuleSet";
54          }
55  
56          public String getDescription() {
57              return "desc";
58          }
59      }
60  
61      private boolean violationSemaphore;
62      private boolean metricSemaphore;
63  
64      public void ruleViolationAdded(RuleViolation ruleViolation) {
65          violationSemaphore = true;
66      }
67  
68      public void metricAdded(Metric metric) {
69          metricSemaphore = true;
70      }
71  
72      @Test
73      public void testBasic() throws Throwable {
74          Report r = new Report();
75          runTestFromString(TEST1, new FooRule(), r);
76          assertFalse(r.isEmpty());
77      }
78  
79      @Test
80      public void testMetric0() {
81          Report r = new Report();
82          assertFalse("Default report shouldn't contain metrics", r.hasMetrics());
83      }
84  
85      @Test
86      public void testMetric1() {
87          Report r = new Report();
88          assertFalse("Default report shouldn't contain metrics", r.hasMetrics());
89  
90          r.addMetric(new Metric("m1", 0, 0.0, 1.0, 2.0, 3.0, 4.0));
91          assertTrue("Expected metrics weren't there", r.hasMetrics());
92  
93          Iterator<Metric> ms = r.metrics();
94          assertTrue("Should have some metrics in there now", ms.hasNext());
95  
96          Object o = ms.next();
97          assertTrue("Expected Metric, got " + o.getClass(), o instanceof Metric);
98  
99          Metric m = (Metric) o;
100         assertEquals("metric name mismatch", "m1", m.getMetricName());
101         assertEquals("wrong low value", 1.0, m.getLowValue(), 0.05);
102         assertEquals("wrong high value", 2.0, m.getHighValue(), 0.05);
103         assertEquals("wrong avg value", 3.0, m.getAverage(), 0.05);
104         assertEquals("wrong std dev value", 4.0, m.getStandardDeviation(), 0.05);
105     }
106 
107     @Test
108     public void testExclusionsInReportWithRuleViolationSuppressRegex() throws Throwable {
109         Report rpt = new Report();
110         Rule rule =  new FooRule();
111         rule.setProperty(Rule.VIOLATION_SUPPRESS_REGEX_DESCRIPTOR, ".*blah.*");
112         runTestFromString(TEST1, rule, rpt);
113         assertTrue(rpt.isEmpty());
114         assertEquals(1, rpt.getSuppressedRuleViolations().size());
115     }
116 
117     @Test
118     public void testExclusionsInReportWithRuleViolationSuppressXPath() throws Throwable {
119         Report rpt = new Report();
120         Rule rule =  new FooRule();
121         rule.setProperty(Rule.VIOLATION_SUPPRESS_XPATH_DESCRIPTOR, ".[@Image = 'Foo']");
122         runTestFromString(TEST1, rule, rpt);
123         assertTrue(rpt.isEmpty());
124         assertEquals(1, rpt.getSuppressedRuleViolations().size());
125     }
126 
127     @Test
128     public void testExclusionsInReportWithAnnotations() throws Throwable {
129         Report rpt = new Report();
130         runTestFromString(TEST2, new FooRule(), rpt, LanguageVersion.JAVA_15);
131         assertTrue(rpt.isEmpty());
132         assertEquals(1, rpt.getSuppressedRuleViolations().size());
133     }
134 
135     @Test
136     public void testExclusionsInReportWithAnnotationsFullName() throws Throwable {
137         Report rpt = new Report();
138         runTestFromString(TEST2_FULL, new FooRule(), rpt, LanguageVersion.JAVA_15);
139         assertTrue(rpt.isEmpty());
140         assertEquals(1, rpt.getSuppressedRuleViolations().size());
141     }
142 
143     @Test
144     public void testExclusionsInReportWithNOPMD() throws Throwable {
145         Report rpt = new Report();
146         runTestFromString(TEST3, new FooRule(), rpt);
147         assertTrue(rpt.isEmpty());
148         assertEquals(1, rpt.getSuppressedRuleViolations().size());
149     }
150 
151     @Test
152     public void testExclusionsInReportWithNOPMDEcmascript() throws Exception {
153         Report rpt = new Report();
154         Rule rule = new AbstractEcmascriptRule() {
155             @Override
156             public Object visit(ASTFunctionNode node, Object data) {
157                 EcmascriptRuleViolationFactory.INSTANCE.addViolation((RuleContext)data, this, node, "Test", null);
158                 return super.visit(node, data);
159             }
160         };
161         String code = "function(x) // NOPMD test suppress\n"
162                 + "{ x = 1; }";
163         runTestFromString(code, rule, rpt, Language.ECMASCRIPT.getDefaultVersion());
164         assertTrue(rpt.isEmpty());
165         assertEquals(1, rpt.getSuppressedRuleViolations().size());
166     }
167 
168     private static final String TEST1 =
169             "public class Foo {}" + PMD.EOL;
170 
171     private static final String TEST2 =
172             "@SuppressWarnings(\"PMD\")" + PMD.EOL +
173             "public class Foo {}";
174     private static final String TEST2_FULL =
175             "@java.lang.SuppressWarnings(\"PMD\")" + PMD.EOL +
176             "public class Foo {}";
177 
178     private static final String TEST3 =
179             "public class Foo {} // NOPMD";
180 
181     // Files are grouped together now.
182     @Test
183     public void testSortedReport_File() throws IOException {
184         Report r = new Report();
185         RuleContext ctx = new RuleContext();
186         ctx.setSourceCodeFilename("foo");
187         JavaNode s = getNode(10, 5, ctx.getSourceCodeFilename());
188         Rule rule1 = new MockRule("name", "desc", "msg", "rulesetname");
189         r.addRuleViolation(new JavaRuleViolation(rule1, ctx, s, rule1.getMessage()));
190         ctx.setSourceCodeFilename("bar");
191         JavaNode s1 = getNode(10, 5, ctx.getSourceCodeFilename());
192         Rule rule2 = new MockRule("name", "desc", "msg", "rulesetname");
193         r.addRuleViolation(new JavaRuleViolation(rule2, ctx, s1, rule2.getMessage()));
194         Renderer rend = new XMLRenderer();
195         String result = render(rend, r);
196         assertTrue("sort order wrong", result.indexOf("bar") < result.indexOf("foo"));
197     }
198 
199     @Test
200     public void testSortedReport_Line() throws IOException {
201         Report r = new Report();
202         RuleContext ctx = new RuleContext();
203         ctx.setSourceCodeFilename("foo1");
204         JavaNode s = getNode(10, 5, ctx.getSourceCodeFilename());
205         Rule rule1 = new MockRule("rule2", "rule2", "msg", "rulesetname");
206         r.addRuleViolation(new JavaRuleViolation(rule1, ctx, s, rule1.getMessage()));
207         ctx.setSourceCodeFilename("foo2");
208         JavaNode s1 = getNode(20, 5, ctx.getSourceCodeFilename());
209         Rule rule2 = new MockRule("rule1", "rule1", "msg", "rulesetname");
210         r.addRuleViolation(new JavaRuleViolation(rule2, ctx, s1, rule2.getMessage()));
211         Renderer rend = new XMLRenderer();
212         String result = render(rend, r);
213         assertTrue("sort order wrong", result.indexOf("rule2") < result.indexOf("rule1"));
214     }
215 
216     @Test
217     public void testListener() {
218         Report rpt = new Report();
219         rpt.addListener(this);
220         violationSemaphore = false;
221         RuleContext ctx = new RuleContext();
222         ctx.setSourceCodeFilename("file");
223         JavaNode s = getNode(5, 5, ctx.getSourceCodeFilename());
224         Rule rule1 = new MockRule("name", "desc", "msg", "rulesetname");
225         rpt.addRuleViolation(new JavaRuleViolation(rule1, ctx, s, rule1.getMessage()));
226         assertTrue(violationSemaphore);
227 
228         metricSemaphore = false;
229         rpt.addMetric(new Metric("test", 0, 0.0, 0.0, 0.0, 0.0, 0.0));
230 
231         assertTrue("no metric", metricSemaphore);
232     }
233 
234     @Test
235     public void testSummary() {
236         Report r = new Report();
237         RuleContext ctx = new RuleContext();
238         ctx.setSourceCodeFilename("foo1");
239         JavaNode s = getNode(5, 5, ctx.getSourceCodeFilename());
240         Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
241         r.addRuleViolation(new JavaRuleViolation(rule, ctx, s, rule.getMessage()));
242         ctx.setSourceCodeFilename("foo2");
243         Rule mr = new MockRule("rule1", "rule1", "msg", "rulesetname");
244         JavaNode s1 = getNode(20, 5, ctx.getSourceCodeFilename());
245         JavaNode s2 = getNode(30, 5, ctx.getSourceCodeFilename());
246         r.addRuleViolation(new JavaRuleViolation(mr, ctx, s1, mr.getMessage()));
247         r.addRuleViolation(new JavaRuleViolation(mr, ctx, s2, mr.getMessage()));
248         Map<String, Integer> summary = r.getSummary();
249         assertEquals(summary.keySet().size(), 2);
250         assertTrue(summary.values().contains(Integer.valueOf(1)));
251         assertTrue(summary.values().contains(Integer.valueOf(2)));
252     }
253 
254     @Test
255     public void testTreeIterator() {
256         Report r = new Report();
257         RuleContext ctx = new RuleContext();
258         Rule rule = new MockRule("name", "desc", "msg", "rulesetname");
259         JavaNode node1 = getNode(5, 5, ctx.getSourceCodeFilename(), true);
260         r.addRuleViolation(new JavaRuleViolation(rule, ctx, node1, rule.getMessage()));
261         JavaNode node2 = getNode(5, 6, ctx.getSourceCodeFilename(), true);
262         r.addRuleViolation(new JavaRuleViolation(rule, ctx, node2, rule.getMessage()));
263 
264         Iterator<RuleViolation> violations = r.iterator();
265         int violationCount = 0;
266         while (violations.hasNext()) {
267             violations.next();
268             violationCount++;
269         }
270         assertEquals(2, violationCount);
271 
272         Iterator<RuleViolation> treeIterator = r.treeIterator();
273         int treeCount = 0;
274         while (treeIterator.hasNext()) {
275             treeIterator.next();
276             treeCount++;
277         }
278         assertEquals(2, treeCount);
279     }
280     
281     public static JavaNode getNode(int line, int column, String scopeName){
282 	DummyJavaNode s = new DummyJavaNode(2);
283         DummyJavaNode parent = new DummyJavaNode(1);
284         parent.testingOnly__setBeginLine(line);
285         parent.testingOnly__setBeginColumn(column);
286         s.jjtSetParent(parent);
287         s.setScope(new SourceFileScope(scopeName));
288         s.testingOnly__setBeginLine(10);
289         s.testingOnly__setBeginColumn(5);
290         return s;
291     }
292 
293     public static JavaNode getNode(int line, int column, String scopeName, boolean nextLine) {
294         DummyJavaNode s = (DummyJavaNode)getNode(line, column, scopeName);
295         if (nextLine) {
296             s.testingOnly__setBeginLine(line + 1);
297             s.testingOnly__setBeginColumn(column + 4);
298         }
299         return s;
300     }
301 
302     public static String render(Renderer renderer, Report report) throws IOException {
303         StringWriter writer = new StringWriter();
304         renderer.setWriter(writer);
305         renderer.start();
306         renderer.renderFileReport(report);
307         renderer.end();
308         return writer.toString();
309     }
310 
311     public static junit.framework.Test suite() {
312         return new JUnit4TestAdapter(ReportTest.class);
313     }
314 
315 }