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