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.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("*");		// try to create a duplicate
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(".*");	// try to create a duplicate
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 	// Two violations
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         // One violation
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 }