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.assertNotNull;
9 import static org.junit.Assert.assertNull;
10 import static org.junit.Assert.assertTrue;
11
12 import java.io.File;
13 import java.io.StringReader;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashSet;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Set;
20
21 import net.sourceforge.pmd.lang.Language;
22 import net.sourceforge.pmd.lang.LanguageVersion;
23 import net.sourceforge.pmd.lang.LanguageVersionHandler;
24 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
25 import net.sourceforge.pmd.lang.rule.MockRule;
26 import net.sourceforge.pmd.lang.rule.RuleReference;
27 import net.sourceforge.pmd.testframework.RuleTst;
28
29 import org.junit.Test;
30
31
32 public class RuleSetTest extends RuleTst {
33
34 private String javaCode = "public class Test { }";
35
36 @Test
37 public void testNoDFA() {
38 RuleSet rs = new RuleSet();
39 MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
40 rs.addRule(mock);
41 assertFalse(rs.usesDFA(Language.JAVA));
42 }
43
44 @Test
45 public void testIncludesRuleWithDFA() {
46 RuleSet rs = new RuleSet();
47 MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
48 mock.setUsesDFA();
49 rs.addRule(mock);
50 assertTrue(rs.usesDFA(Language.JAVA));
51 }
52
53 @Test
54 public void testAccessors() {
55 RuleSet rs = new RuleSet();
56 rs.setFileName("baz");
57 assertEquals("file name mismatch", "baz", rs.getFileName());
58 rs.setName("foo");
59 assertEquals("name mismatch", "foo", rs.getName());
60 rs.setDescription("bar");
61 assertEquals("description mismatch", "bar", rs.getDescription());
62 }
63
64 @Test
65 public void testGetRuleByName() {
66 RuleSet rs = new RuleSet();
67 MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
68 rs.addRule(mock);
69 assertEquals("unable to fetch rule by name", mock, rs.getRuleByName("name"));
70 }
71
72 @Test
73 public void testGetRuleByName2() {
74 RuleSet rs = new RuleSet();
75 MockRule mock = new MockRule("name", "desc", "msg", "rulesetname");
76 rs.addRule(mock);
77 assertNull("the rule FooRule must not be found!", rs.getRuleByName("FooRule"));
78 }
79
80 @Test
81 public void testRuleList() {
82 RuleSet IUT = new RuleSet();
83
84 assertEquals("Size of RuleSet isn't zero.", 0, IUT.size());
85
86 MockRule rule = new MockRule("name", "desc", "msg", "rulesetname");
87 IUT.addRule(rule);
88
89 assertEquals("Size of RuleSet isn't one.", 1, IUT.size());
90
91 Collection rules = IUT.getRules();
92
93 Iterator i = rules.iterator();
94 assertTrue("Empty Set", i.hasNext());
95 assertEquals("Returned set of wrong size.", 1, rules.size());
96 assertEquals("Rule isn't in ruleset.", rule, i.next());
97 }
98
99 @Test
100 public void testAddRuleSet() {
101 RuleSet set1 = new RuleSet();
102 set1.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
103 RuleSet set2 = new RuleSet();
104 set2.addRule(new MockRule("name2", "desc", "msg", "rulesetname"));
105 set1.addRuleSet(set2);
106 assertEquals("ruleset size wrong", 2, set1.size());
107 }
108
109 @Test(expected = RuntimeException.class)
110 public void testAddRuleSetByReferenceBad() {
111 RuleSet set1 = new RuleSet();
112 set1.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
113 RuleSet set2 = new RuleSet();
114 set2.addRule(new MockRule("name2", "desc", "msg", "rulesetname"));
115 set1.addRuleSetByReference(set2, false);
116 }
117
118 @Test
119 public void testAddRuleSetByReferenceAllRule() {
120 RuleSet set1 = new RuleSet();
121 RuleSet set2 = new RuleSet();
122 set2.setFileName("foo");
123 set2.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
124 set2.addRule(new MockRule("name2", "desc", "msg", "rulesetname"));
125 set1.addRuleSetByReference(set2, true);
126 assertEquals("wrong rule size", 2, set1.getRules().size());
127 for (Rule rule : set1.getRules()) {
128 assertTrue("not a rule reference", rule instanceof RuleReference);
129 RuleReference ruleReference = (RuleReference) rule;
130 assertEquals("wrong ruleset file name", "foo", ruleReference.getRuleSetReference().getRuleSetFileName());
131 assertTrue("not all rule reference", ruleReference.getRuleSetReference().isAllRules());
132 }
133 }
134
135 @Test
136 public void testAddRuleSetByReferenceSingleRule() {
137 RuleSet set1 = new RuleSet();
138 RuleSet set2 = new RuleSet();
139 set2.setFileName("foo");
140 set2.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
141 set2.addRule(new MockRule("name2", "desc", "msg", "rulesetname"));
142 set1.addRuleSetByReference(set2, false);
143 assertEquals("wrong rule size", 2, set1.getRules().size());
144 for (Rule rule : set1.getRules()) {
145 assertTrue("not a rule reference", rule instanceof RuleReference);
146 RuleReference ruleReference = (RuleReference) rule;
147 assertEquals("wrong ruleset file name", "foo", ruleReference.getRuleSetReference().getRuleSetFileName());
148 assertFalse("should not be all rule reference", ruleReference.getRuleSetReference().isAllRules());
149 }
150 }
151
152 @Test
153 public void testApply0Rules() throws Throwable {
154 RuleSet IUT = new RuleSet();
155 verifyRuleSet(IUT, 0, new HashSet());
156 }
157
158 @Test
159 public void testEquals1() {
160 RuleSet s = new RuleSet();
161 assertFalse("A ruleset cannot be equals to null", s.equals(null));
162 }
163
164 @Test
165 @SuppressWarnings("PMD.UseAssertEqualsInsteadOfAssertTrue")
166 public void testEquals2() {
167 RuleSet s = new RuleSet();
168 assertTrue("A rulset must be equals to itself", s.equals(s));
169 }
170
171 @Test
172 public void testEquals3() {
173 RuleSet s = new RuleSet();
174 s.setName("basic rules");
175 assertFalse("A ruleset cannot be equals to another kind of object", s.equals("basic rules"));
176 }
177
178 @Test
179 public void testEquals4() {
180 RuleSet s1 = new RuleSet();
181 s1.setName("my ruleset");
182 s1.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
183
184 RuleSet s2 = new RuleSet();
185 s2.setName("my ruleset");
186 s2.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
187
188 assertEquals("2 rulesets with same name and rules must be equals", s1, s2);
189 assertEquals("Equals rulesets must have the same hashcode", s1.hashCode(), s2.hashCode());
190 }
191
192 @Test
193 public void testEquals5() {
194 RuleSet s1 = new RuleSet();
195 s1.setName("my ruleset");
196 s1.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
197
198 RuleSet s2 = new RuleSet();
199 s2.setName("my other ruleset");
200 s2.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
201
202 assertFalse("2 rulesets with different name but same rules must not be equals", s1.equals(s2));
203 }
204
205 @Test
206 public void testEquals6() {
207 RuleSet s1 = new RuleSet();
208 s1.setName("my ruleset");
209 s1.addRule(new MockRule("name", "desc", "msg", "rulesetname"));
210
211 RuleSet s2 = new RuleSet();
212 s2.setName("my ruleset");
213 s2.addRule(new MockRule("other rule", "desc", "msg", "rulesetname"));
214
215 assertFalse("2 rulesets with same name but different rules must not be equals", s1.equals(s2));
216 }
217
218 @Test
219 public void testLanguageApplies() {
220
221 Rule rule = new MockRule();
222
223 rule.setLanguage(Language.ECMASCRIPT);
224 assertFalse("Different languages should not apply", RuleSet.applies(rule, LanguageVersion.JAVA_15));
225
226 rule.setLanguage(Language.JAVA);
227 assertTrue("Same language with no min/max should apply", RuleSet.applies(rule, LanguageVersion.JAVA_15));
228
229 rule.setMinimumLanguageVersion(LanguageVersion.JAVA_15);
230 assertTrue("Same language with valid min only should apply", RuleSet.applies(rule, LanguageVersion.JAVA_15));
231
232 rule.setMaximumLanguageVersion(LanguageVersion.JAVA_16);
233 assertTrue("Same language with valid min and max should apply", RuleSet.applies(rule, LanguageVersion.JAVA_15));
234 assertFalse("Same language with outside range of min/max should not apply", RuleSet.applies(rule, LanguageVersion.JAVA_14));
235 assertFalse("Same language with outside range of min/max should not apply", RuleSet.applies(rule, LanguageVersion.JAVA_17));
236 }
237
238 @Test
239 public void testAddExcludePattern() {
240 RuleSet ruleSet = new RuleSet();
241 ruleSet.addExcludePattern("*");
242 assertNotNull("Exclude patterns", ruleSet.getExcludePatterns());
243 assertEquals("Invalid number of patterns", 1, ruleSet.getExcludePatterns().size());
244 ruleSet.addExcludePattern("*");
245 assertEquals("Invalid number of patterns", 1, ruleSet.getExcludePatterns().size());
246 assertEquals("Exclude pattern", "*", ruleSet.getExcludePatterns().get(0));
247 assertNotNull("Include patterns", ruleSet.getIncludePatterns());
248 assertEquals("Invalid number of include patterns", 0, ruleSet.getIncludePatterns().size());
249 }
250
251 @Test
252 public void testAddExcludePatterns() {
253 RuleSet ruleSet = new RuleSet();
254 ruleSet.addExcludePattern("*");
255 ruleSet.addExcludePattern(".*");
256 RuleSet ruleSet2 = new RuleSet();
257 ruleSet2.addExcludePatterns(ruleSet.getExcludePatterns());
258 assertNotNull("Exclude patterns", ruleSet2.getExcludePatterns());
259 assertEquals("Invalid number of patterns", 2, ruleSet2.getExcludePatterns().size());
260 ruleSet.addExcludePattern(".*");
261 assertEquals("Invalid number of patterns", 2, ruleSet2.getExcludePatterns().size());
262 assertEquals("Exclude pattern", "*", ruleSet2.getExcludePatterns().get(0));
263 assertEquals("Exclude pattern", ".*", ruleSet2.getExcludePatterns().get(1));
264 assertNotNull("Include patterns", ruleSet2.getIncludePatterns());
265 assertEquals("Invalid number of include patterns", 0, ruleSet2.getIncludePatterns().size());
266 }
267
268 @Test
269 public void testSetExcludePatterns() {
270 List<String> excludePatterns = new ArrayList<String>();
271 excludePatterns.add("*");
272 excludePatterns.add(".*");
273 RuleSet ruleSet = new RuleSet();
274 ruleSet.setExcludePatterns(excludePatterns);
275 assertNotNull("Exclude patterns", ruleSet.getExcludePatterns());
276 assertEquals("Invalid number of exclude patterns", 2, ruleSet.getExcludePatterns().size());
277 assertEquals("Exclude pattern", "*", ruleSet.getExcludePatterns().get(0));
278 assertEquals("Exclude pattern", ".*", ruleSet.getExcludePatterns().get(1));
279 assertNotNull("Include patterns", ruleSet.getIncludePatterns());
280 assertEquals("Invalid number of include patterns", 0, ruleSet.getIncludePatterns().size());
281 }
282
283 @Test
284 public void testAddIncludePattern() {
285 RuleSet ruleSet = new RuleSet();
286 ruleSet.addIncludePattern("*");
287 assertNotNull("Include patterns", ruleSet.getIncludePatterns());
288 assertEquals("Invalid number of patterns", 1, ruleSet.getIncludePatterns().size());
289 assertEquals("Include pattern", "*", ruleSet.getIncludePatterns().get(0));
290 assertNotNull("Exclude patterns", ruleSet.getExcludePatterns());
291 assertEquals("Invalid number of exclude patterns", 0, ruleSet.getExcludePatterns().size());
292 }
293
294 @Test
295 public void testAddIncludePatterns() {
296 RuleSet ruleSet = new RuleSet();
297 ruleSet.addIncludePattern("*");
298 ruleSet.addIncludePattern(".*");
299 RuleSet ruleSet2 = new RuleSet();
300 ruleSet2.addIncludePatterns(ruleSet.getIncludePatterns());
301 assertNotNull("Include patterns", ruleSet2.getIncludePatterns());
302 assertEquals("Invalid number of patterns", 2, ruleSet2.getIncludePatterns().size());
303 assertEquals("Include pattern", "*", ruleSet2.getIncludePatterns().get(0));
304 assertEquals("Include pattern", ".*", ruleSet2.getIncludePatterns().get(1));
305 assertNotNull("Exclude patterns", ruleSet.getExcludePatterns());
306 assertEquals("Invalid number of exclude patterns", 0, ruleSet.getExcludePatterns().size());
307 }
308
309 @Test
310 public void testSetIncludePatterns() {
311 List<String> includePatterns = new ArrayList<String>();
312 includePatterns.add("*");
313 includePatterns.add(".*");
314 RuleSet ruleSet = new RuleSet();
315 ruleSet.setIncludePatterns(includePatterns);
316 assertNotNull("Include patterns", ruleSet.getIncludePatterns());
317 assertEquals("Invalid number of include patterns", 2, ruleSet.getIncludePatterns().size());
318 assertEquals("Include pattern", "*", ruleSet.getIncludePatterns().get(0));
319 assertEquals("Include pattern", ".*", ruleSet.getIncludePatterns().get(1));
320 assertNotNull("Exclude patterns", ruleSet.getExcludePatterns());
321 assertEquals("Invalid number of exclude patterns", 0, ruleSet.getExcludePatterns().size());
322 }
323
324 @Test
325 public void testIncludeExcludeApplies() {
326 File file = new File("C:\\myworkspace\\project\\some\\random\\package\\RandomClass.java");
327
328 RuleSet ruleSet = new RuleSet();
329 assertTrue("No patterns", ruleSet.applies(file));
330
331 ruleSet = new RuleSet();
332 ruleSet.addExcludePattern("nomatch");
333 assertTrue("Non-matching exclude", ruleSet.applies(file));
334
335 ruleSet = new RuleSet();
336 ruleSet.addExcludePattern("nomatch");
337 ruleSet.addExcludePattern(".*/package/.*");
338 assertFalse("Matching exclude", ruleSet.applies(file));
339
340 ruleSet = new RuleSet();
341 ruleSet.addExcludePattern("nomatch");
342 ruleSet.addExcludePattern(".*/package/.*");
343 ruleSet.addIncludePattern(".*/randomX/.*");
344 assertFalse("Non-matching include", ruleSet.applies(file));
345
346 ruleSet = new RuleSet();
347 ruleSet.addExcludePattern("nomatch");
348 ruleSet.addExcludePattern(".*/package/.*");
349 ruleSet.addIncludePattern(".*/randomX/.*");
350 ruleSet.addIncludePattern(".*/random/.*");
351 assertTrue("Matching include", ruleSet.applies(file));
352 }
353
354 @Test
355 public void testIncludeExcludeMultipleRuleSetWithRuleChainApplies() throws PMDException {
356 File file = new File("C:\\myworkspace\\project\\some\\random\\package\\RandomClass.java");
357
358 RuleSet ruleSet1 = new RuleSet();
359 ruleSet1.setName("RuleSet1");
360 Rule rule = findRule("java-empty", "EmptyIfStmt");
361 assertTrue("RuleChain rule", rule.usesRuleChain());
362 ruleSet1.addRule(rule);
363
364 RuleSet ruleSet2 = new RuleSet();
365 ruleSet2.setName("RuleSet2");
366 ruleSet2.addRule(rule);
367
368 RuleSets ruleSets = new RuleSets();
369 ruleSets.addRuleSet(ruleSet1);
370 ruleSets.addRuleSet(ruleSet2);
371
372
373 PMD p = new PMD();
374 RuleContext ctx = new RuleContext();
375 Report r = new Report();
376 ctx.setReport(r);
377 ctx.setSourceCodeFilename(file.getName());
378 ctx.setSourceCodeFile(file);
379 p.getSourceCodeProcessor().processSourceCode(new StringReader(TEST1), ruleSets, ctx);
380 assertEquals("Violations", 2, r.size());
381
382
383 ruleSet1 = new RuleSet();
384 ruleSet1.setName("RuleSet1");
385 ruleSet1.addExcludePattern(".*/package/.*");
386 ruleSet1.addRule(rule);
387
388 ruleSets = new RuleSets();
389 ruleSets.addRuleSet(ruleSet1);
390 ruleSets.addRuleSet(ruleSet2);
391
392 r = new Report();
393 ctx.setReport(r);
394 p.getSourceCodeProcessor().processSourceCode(new StringReader(TEST1), ruleSets, ctx);
395 assertEquals("Violations", 1, r.size());
396 }
397
398 protected void verifyRuleSet(RuleSet IUT, int size, Set values) throws Throwable {
399
400 RuleContext context = new RuleContext();
401 Set<RuleViolation> reportedValues = new HashSet<RuleViolation>();
402 context.setReport(new Report());
403 IUT.apply(makeCompilationUnits(), context);
404
405 assertEquals("Invalid number of Violations Reported", size, context.getReport().size());
406
407 Iterator violations = context.getReport().iterator();
408 while (violations.hasNext()) {
409 RuleViolation violation = (RuleViolation) violations.next();
410
411 reportedValues.add(violation);
412 assertTrue("Unexpected Violation Returned: " + violation, values.contains(violation));
413 }
414
415 Iterator expected = values.iterator();
416 while (expected.hasNext()) {
417 RuleViolation violation = (RuleViolation) expected.next();
418 assertTrue("Expected Violation not Returned: " + violation, reportedValues.contains(violation));
419 }
420 }
421
422 protected List<ASTCompilationUnit> makeCompilationUnits() throws Throwable {
423 List<ASTCompilationUnit> RC = new ArrayList<ASTCompilationUnit>();
424 LanguageVersionHandler languageVersionHandler = Language.JAVA.getDefaultVersion().getLanguageVersionHandler();
425 ASTCompilationUnit cu = (ASTCompilationUnit) languageVersionHandler.getParser(
426 languageVersionHandler.getDefaultParserOptions()).parse(null, new StringReader(javaCode));
427 RC.add(cu);
428 return RC;
429 }
430
431 private static final String TEST1 = "public class Foo {" + PMD.EOL +
432 " public void foo() {" + PMD.EOL +
433 " if (true) { }" + PMD.EOL +
434 " }" + PMD.EOL +
435 "}" + PMD.EOL;
436
437 public static junit.framework.Test suite() {
438 return new junit.framework.JUnit4TestAdapter(RuleSetTest.class);
439 }
440 }