0
votes

I have the following rule defined in my ruleSet.xml file:

<rule ref="category/java/codestyle.xml/MethodNamingConventions">
    <properties>
        <property name="junit4TestPattern" value="[a-z]*_[A-Z]{1}[a-z,A-Z]*_[A-Z]{1}[a-z,A-Z]*"/>
        <property name="violationSuppressXPath" value="//ClassOrInterfaceDeclaration['.*FoobarRepository']"/>
    </properties>
</rule>

But when running PMD nothing fails yet I have alot of methods that are not conform the junit4 method naming pattern. All method are annotated with org.junit.Test What is needed to trigger junit specific rules ?

1

1 Answers

2
votes

I don't think it's a bug, your violationSuppressXPath just returns true all the time. Remember, that it's evaluated with the violating node as the context node of the expression.

//ClassOrInterfaceDeclaration

// at the start of an XPath expression select all the descendants of the document root, so all the nodes in the file. So //ClassOrInterfaceDeclaration selects all the nodes of that type in the file, and not necessarily one that encloses the violation node.

['.*PrincipalRepository']

This predicate is always true, because any non-empty string is truthy. A predicate like ['foo'] is evaluated by converting the string to a boolean with the boolean function, which yields true() if the string is non-empty. (Here you mean to test the name of the class, in the attribute @Image)

So basically the predicate doesn't test anything. The effect, is that your violationSuppressXPath suppresses the violation any time the file where the violation is found contains some ClassOrInterfaceDeclaration anywhere, which is pretty frequent.

To make this work, you could replace it with

./ancestor::ClassOrInterfaceDeclaration[@Image = 'PrincipalRepository']

Note that unfortunately, XPath 1.0 does not support regular expressions so you can't do a regex test (though you can use contains or imitate an ends-with like in this answer). In this instance, I think a @SuppressWarnings("PMD.MethodNamingConventions") like you came up with is more appropriate.