Skip to content

Issue #13328: Kill mutation for MatchXpathCheck#13242

Closed
Kevin222004 wants to merge 1 commit intocheckstyle:masterfrom
Kevin222004:MatchXpath
Closed

Issue #13328: Kill mutation for MatchXpathCheck#13242
Kevin222004 wants to merge 1 commit intocheckstyle:masterfrom
Kevin222004:MatchXpath

Conversation

@Kevin222004
Copy link
Copy Markdown
Contributor

@Kevin222004 Kevin222004 commented Jun 17, 2023

Issue #13328: Kill mutation for MatchXpathCheck


Check

https://checkstyle.org/config_coding.html#MatchXpath


Mutation

<mutation unstable="false">
<sourceFile>MatchXpathCheck.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.coding.MatchXpathCheck</mutatedClass>
<mutatedMethod>&lt;init&gt;</mutatedMethod>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.experimental.MemberVariableMutator</mutator>
<description>Removed assignment to member variable query</description>
<lineContent>private String query = &quot;&quot;;</lineContent>
</mutation>
<mutation unstable="false">
<sourceFile>MatchXpathCheck.java</sourceFile>
<mutatedClass>com.puppycrawl.tools.checkstyle.checks.coding.MatchXpathCheck</mutatedClass>
<mutatedMethod>setQuery</mutatedMethod>
<mutator>org.pitest.mutationtest.engine.gregor.mutators.experimental.MemberVariableMutator</mutator>
<description>Removed assignment to member variable query</description>
<lineContent>this.query = query;</lineContent>
</mutation>


Explaination

The reason to create a pure unit testing for mutation

throw new IllegalStateException("Evaluation of Xpath query failed: " + query, ex);
hence to get the exact message I have to create a pure Ut. else test case is not possible removal of that statement is also not going to create issue because in all the set method if query is required it will be used from parameter the only usage after the setter is to throw exception message so user can see what is wrong


Removal of " " will not create an issue as it is going to change to null. This check always require to set property.

@Kevin222004 Kevin222004 force-pushed the MatchXpath branch 2 times, most recently from 3142a92 to b453518 Compare June 18, 2023 14:56
}

@Test
public void testExceptionMessage() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a copy paste of testEvaluationException() with exception checked. It should be possible to test it via input like:

/*
MatchXpath
query = count(*) div 0

*/

package com.puppycrawl.tools.checkstyle.checks.coding.matchxpath;

public class InputWithBadQuery {
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, no new pure unit testing in fake tree.
All should be on our AST and on our Check.

Copy link
Copy Markdown
Contributor Author

@Kevin222004 Kevin222004 Jun 24, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be possible to test it via input like:

Yes, but we want to get the exact message of the exception
it won't work with input based
please guide me if I miss anything

    @Test
    public void testCheckWithMatchingMethodName2() throws Exception {
        final DefaultConfiguration checkConfig = createModuleConfig(MatchXpathCheck.class);
        checkConfig.addProperty("query", "count(*) div 0");
        try {
           verify(checkConfig, getPath("InputMatchXpath5.java"));
        }
        catch (XPathException ex) {
            assertWithMessage("Exception message")
                .that(ex.getMessage())
                .isEqualTo("Evaluation of Xpath query failed: count(*) div 0");
        }
    }

Input file is as same as mentioned at #13242 (comment)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you try to catch all exceptions ? I think there should be CheckstyleException
And message will be in cause exception.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you tried and it didn't not, please show all all details on how you did this and what is results

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done please check

@rdiachenko rdiachenko self-assigned this Jun 22, 2023
@Kevin222004 Kevin222004 force-pushed the MatchXpath branch 2 times, most recently from c878d96 to 51c1a2e Compare June 25, 2023 15:30
Copy link
Copy Markdown
Member

@romani romani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Items

@rdiachenko
Copy link
Copy Markdown
Member

@Kevin222004 please resolve conflicts and address leftovers.

Comment on lines +239 to +248
final DefaultConfiguration checkConfig = createModuleConfig(MatchXpathCheck.class);
checkConfig.addProperty("query", "count(*) div 0");
try {
verify(checkConfig, getPath("InputMatchXpath5.java"));
}
catch (CheckstyleException ex) {
final Throwable cause = ex.getCause();
assertThat(cause.getMessage())
.isEqualTo("Evaluation of Xpath query failed: count(*) div 0");
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
final DefaultConfiguration checkConfig = createModuleConfig(MatchXpathCheck.class);
checkConfig.addProperty("query", "count(*) div 0");
try {
verify(checkConfig, getPath("InputMatchXpath5.java"));
}
catch (CheckstyleException ex) {
final Throwable cause = ex.getCause();
assertThat(cause.getMessage())
.isEqualTo("Evaluation of Xpath query failed: count(*) div 0");
}
final DefaultConfiguration checkConfig = createModuleConfig(MatchXpathCheck.class);
checkConfig.addProperty("query", "count(*) div 0");
final CheckstyleException ex = assertThrows(CheckstyleException.class, () -> {
verify(checkConfig, getPath("InputMatchXpath5.java"));
});
assertThat(ex.getCause().getMessage())
.isEqualTo("Evaluation of Xpath query failed: count(*) div 0");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks

@Kevin222004 Kevin222004 changed the title Issue #13109: Kill mutation for MatchXpathCheck Issue #13328: Kill mutation for MatchXpathCheck Jul 1, 2023
@Kevin222004 Kevin222004 force-pushed the MatchXpath branch 2 times, most recently from 6dd8a36 to e7374e2 Compare July 1, 2023 15:45
@romani
Copy link
Copy Markdown
Member

romani commented Jul 2, 2023

@Kevin222004 ,

This check always require to set property.

Non of Check requires property to be set. If we are not sure on default, we usually set some value that is not going to produce any violation.
Please doublecheck this PR, a lot is changed from initial PR state, please update description.

We have empty string in default at https://checkstyle.org/config_coding.html#MatchXpath_Properties , are we going to change it to null ?

@romani
Copy link
Copy Markdown
Member

romani commented Jul 2, 2023

looks like we need user defined query only to throw exceptions:

private String query = "";
/** Xpath expression. */
private XPathExpression xpathExpression;
/**
* Setter to specify Xpath query.
*
* @param query Xpath query.
* @throws IllegalStateException if creation of xpath expression fails
*/
public void setQuery(String query) {
this.query = query;
if (!query.isEmpty()) {
try {
final XPathEvaluator xpathEvaluator =
new XPathEvaluator(Configuration.newConfiguration());
xpathExpression = xpathEvaluator.createExpression(query);
}
catch (XPathException ex) {
throw new IllegalStateException("Creating Xpath expression failed: " + query, ex);

so it is same pattern that we have in other Checks, we store user defined value but we do not use it acltually outside of setXxxxx.

and

private List<DetailAST> findMatchingNodesByXpathQuery(DetailAST rootAST) {
try {
final RootNode rootNode = new RootNode(rootAST);
final XPathDynamicContext xpathDynamicContext =
xpathExpression.createDynamicContext(rootNode);
final List<Item> matchingItems = xpathExpression.evaluate(xpathDynamicContext);
return matchingItems.stream()
.map(item -> (DetailAST) ((AbstractNode) item).getUnderlyingNode())
.collect(Collectors.toList());
}
catch (XPathException ex) {
throw new IllegalStateException("Evaluation of Xpath query failed: " + query, ex);

so we need to preserve user defined value in setQuery and we can catch exception to verify user set value.
you just need to reproduce Evaluation of Xpath query failed:

@Kevin222004
Copy link
Copy Markdown
Contributor Author

Kevin222004 commented Jul 2, 2023

looks like we need user defined query only to throw exceptions:

yes if I explicitly set query to "" then it will throw exception when it is used as default so as ans of #13242 (comment) yes we setting by default null

@romani
Copy link
Copy Markdown
Member

romani commented Jul 2, 2023

ok, so no main code changes should happen, please extend tests

Copy link
Copy Markdown
Member

@romani romani left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

items:


/** Specify Xpath query. */
private String query = "";
private String query;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

somthing is broken in this Check.

if user did setQuery ones he can not return Check to default state by setting setQuery("") by providing default value.
it is not possible to set query twice in our config, but plugings (sonar, eclipse-cs) are working directly with modules (no xml), so it might be problem for them.

I am ok with pure junit here , but we need to have default and we need to restore Check instance to default mode of execution by setting defalt value in its setter.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And we need to reset xpathExpression field if user set empty value.
Empty string should mean null in xpathExpression

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issue I will look on this by tommorow

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Kevin222004 any update on this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rdiachenko sorry I haven't visited it yet will update as soon as possible

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@romani I haven't missed #13242 (comment) this but,
please look at the updated pr. I have make a slight change in setter. I don't think it is required to restore check instance.
I added all the kind of test #13242 (comment) please check

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having null as default, make it impossible to set back to default.
There is no null as value in xml

What I meant is to update setter to:

if (!query.isEmpty()) {
....
} else {
this.query = "";
this.xpathExpression = null;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I'm following the request with null. @Kevin222004 what's the latest status of this PR?

Copy link
Copy Markdown
Member

@romani romani Aug 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should remove such field, having this.xpathExpression is enough.
We have no functionality to reuse what user set, so we can loose it for now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Kevin222004 , what is problem to remove this field

@romani
Copy link
Copy Markdown
Member

romani commented Aug 15, 2023

@Kevin222004 , please resolve conflict.

@romani
Copy link
Copy Markdown
Member

romani commented Aug 18, 2023

@Kevin222004 , please focus on this PR, lets finish it.
if you stuck, ask question and share problems with us.

@romani
Copy link
Copy Markdown
Member

romani commented Aug 20, 2023

Still bunch CI failures and review item above is not addressed

@rdiachenko
Copy link
Copy Markdown
Member

@Kevin222004 I'm closing this PR in favour of #13726. Please take a look at it, if you have any questions I'm happy to help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants