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