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 }