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