1

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 ?

Jonas Geiregat
  • 5,214
  • 4
  • 41
  • 60

1 Answers1

2

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.

oowekyala
  • 7,518
  • 1
  • 15
  • 20
  • 1
    PMD provides for XPath 1.0 a own `matches` function to support regex: `./ancestor::ClassOrInterfaceDeclaration[matches(@Image, '^.*PrincipalRepository$')]` – adangel Jun 14 '19 at 12:57
  • This is really strange because this does not work for me but `` works like a charm and it definitely filters classes. I use it for `TooManyStaticImports` – Saljack May 23 '23 at 08:11
  • @Saljack Both rules don't report on the same nodes. TooManyStaticImports reports on the root node, while MethodNamingConventions reports on the method node. The latter has a ClassOrInterfaceDeclaration ancestor but the former doesn't. I'm surprised your expression doesn't filter out all classes. Did you check whether legit violations are still reported? – oowekyala May 24 '23 at 10:54
  • Yes I checked it. I have two classes `SomethingFoobarRepository` and `SomethingServiceImpl`. `SomethinFoobarrepository` is filtered but `SomethingServiceImpl` is still there. – Saljack May 24 '23 at 12:10