Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: wrong output truecount and falsecount of clover #699

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

KiritaniAyaka
Copy link

@KiritaniAyaka KiritaniAyaka commented Oct 23, 2022

close #695

Changes

  • fix wrong truecount and falsecount in clover
  • switch will be considered a statement now because it has no binary result (not applicable to truecount and falsecount). (#discussion_r1091535324)
  • for default args and binary expression, use the fake value of truecount and falsecount to express covered and not covered

Copy link
Member

@bcoe bcoe left a comment

Choose a reason for hiding this comment

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

switch will be considered a statement now because it has no binary result

For branch coverage, I'm assuming we'll understand coverage of the branch based on line coverage?


if (branchDetail) {
if (branchDetail && branchDetail.type === 'if') {
Copy link
Member

Choose a reason for hiding this comment

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

Are there other branch types we should consider, e.g., ternary operations?

Copy link
Author

Choose a reason for hiding this comment

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

Oh, thanks for point out. I'll dig it further later.

Copy link
Author

Choose a reason for hiding this comment

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

I have done a simple search in source code and a testing (Check it in my repo). Except if and switch, there are three types of branches:

default-arg:
The states always have one member and it presents the number of times that default arguments are applied.

cond-expr: (ternary operator)
The states always have two members. The first presents the number of times that condition was judged as true, and the second presents the number of times that condition was judged as false.

binary-expr:
The number of members is equal to the number of conditions. The xth member presents the number of times that xth condition was calculated. And it has nothing to do with the nest and calculating order.


For default-arg, I think it should be considered a statement according to the standard mentioned at #695 .

For cond-expr, it could be deal with the same as if.

I have no good idea to deal with binary-expr. Maybe we can consider it as covered when all conditions are calculated?

@KiritaniAyaka
Copy link
Author

I dealt with the remaining branch types in the latest commit. Please check again. @bcoe

@silverbackdan
Copy link

Would be a great and very useful fix, I'm in no position to reproduce but have been experiencing this issue with partial matches. Thanks all for the work leading to this PR. In the linked issue I have another simple reproduction if required.

Comment on lines +158 to +163
if (branchDetail.states.every(state => state > 0)) {
attrs.truecount = 1;
attrs.falsecount = 1;
} else {
attrs.truecount = 1;
attrs.falsecount = 0;
Copy link
Author

Choose a reason for hiding this comment

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

Hi, @bcoe. The problem mentioned in issue #695 looks to make others puzzled now so I think it's needed to push this PR.

I guess this PR stop forward because you may disagree with the practice that assigning hardcode values to make 3rd-party parsers understand if this line was covered or not.

Could we have better practice to resolve this problem?

@silverbackdan
Copy link

FYI if anyone finds this thread and is looking for an answer, I've found uploading coverage-final.json instead of clover.xml to codecov results in the correct results and there are not partial line matches galore.

@KiritaniAyaka
Copy link
Author

FYI if anyone finds this thread and is looking for an answer, I've found uploading coverage-final.json instead of clover.xml to codecov results in the correct results and there are not partial line matches galore.

Great alternative plan!

Just enable json reporter in .nycrc to resolve it, for example:

{
  "extends": "@istanbuljs/nyc-config-typescript",
  "include": ["src/**/*.ts"],
  "extension": [".ts"],
  "reporter": ["html", "json"], // enable json reporter
  "all": true,
  "sourceMap": true,
  "instrument": true
}

Here's my coverage report on codecov after switch to json reporter

@silverbackdan
Copy link

silverbackdan commented Jan 28, 2023

Great, pleased it's helped someone. I found the idea from uploading a different type of report for a different coverage provider so thought it worth a shot. I'd like to my updated coverage to show as well, but it's on a feature branch which will be deleted shortly, but anyway. Happy days.

But this is my PR which has the update showing the coverage increase
components-web-app/cwa-nuxt-module#89

TBH it should be nice if a partial match showed if a conditional statement doesn't match both true and false at some point, but technically it is a hit for the line so coverage that the line was tested is correct.

@bcoe bcoe added the ci label Jan 30, 2023
Copy link
Member

@bcoe bcoe left a comment

Choose a reason for hiding this comment

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

Your implementation seems good to me, but it would be helpful to have a comment above each logical check, to explain the decisions you've made.

attrs.type = 'cond';
attrs.truecount = branchDetail.covered;
attrs.falsecount = branchDetail.total - branchDetail.covered;
if (!branchDetail || branchDetail.type === 'switch') {
Copy link
Member

Choose a reason for hiding this comment

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

What is the effect of adding a line tag here and returning immediately, will this result in 100% line coverage and no missing branch coverage?

Copy link
Author

Choose a reason for hiding this comment

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

It is from the original code:

if (branchDetail) {
    attrs.type = 'cond';
    attrs.truecount = branchDetail.covered;
    attrs.falsecount = branchDetail.total - branchDetail.covered;
}
this.xml.inlineTag('line', attrs);

but the true case is too complex now, so I move the false case into the brackets and change the condition to !branchDetail.

As to branchDetail.type === 'switch'. Thanks to you, I found a situation as you said:

switch (num) {
    case 0:
    case 1:
        console.log('Hello');
        break;
}

When we use num=1 to test this switch, all lines are covered but branches not.

Maybe we should treat switch the same as binary-expr.

return this.xml.inlineTag('line', attrs);
}

if (['if', 'cond-expr'].includes(branchDetail.type)) {
Copy link
Member

Choose a reason for hiding this comment

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

This logic is complex enough, that I think it would be good to add a description above each condition, explaining the reasoning for the logic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Branch counter of reporter may have a bug
3 participants