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

Changed to calculate based on the average coverage of the modules #479

Merged
merged 7 commits into from
Jul 27, 2019

Conversation

dlplenin
Copy link
Contributor

@dlplenin dlplenin commented Jun 27, 2019

Fixes #346

Minor changes to calculate Average (console's table) based on average from all projects. Im not sure if it is ok only to modify CalculateLineCoverage(Modules modules) functions.
Also a change in CoverageResult.cs just to keep same logic, because its switch-case (ThresholdStatistic.Average) was working well (average based on average from all projects).

@MarcoRossignoli MarcoRossignoli added the bug Something isn't working label Jun 28, 2019
@MarcoRossignoli
Copy link
Collaborator

Diego can you add some tests here https://github.com/tonerdo/coverlet/blob/master/test/coverlet.core.tests/CoverageSummaryTests.cs?

@MarcoRossignoli MarcoRossignoli added * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) and removed * NO MERGE * The PR is not ready for merge yet (see discussion for detailed reasons) labels Jun 28, 2019
@sasivishnu
Copy link
Contributor

sasivishnu commented Jun 28, 2019

Just a suggestion... could you use modules.Count instead of modules.Count()? since property already available to give the value. Linq Count() method use property Count anyway when type is of ICollection I believe.

foreach (var _module in result.Modules)
{
var linePercent = summary.CalculateLineCoverage(_module.Value).Percent;
var branchPercent = summary.CalculateBranchCoverage(_module.Value).Percent;
var methodPercent = summary.CalculateMethodCoverage(_module.Value).Percent;

coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{linePercent}%", $"{branchPercent}%", $"{methodPercent}%");
coverageTable.AddRow(Path.GetFileNameWithoutExtension(_module.Key), $"{linePercent.ToString("0.00")}%", $"{branchPercent.ToString("0.00")}%", $"{methodPercent.ToString("0.00")}%");
Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need do ToString("0.00"). Percent property already takes care of rounding down to 2 decimal precision.

@@ -187,8 +191,8 @@ static int Main(string[] args)
coverageTable.Rows.Clear();

coverageTable.AddColumn(new[] { "", "Line", "Branch", "Method" });
coverageTable.AddRow("Total", $"{totalLinePercent}%", $"{totalBranchPercent}%", $"{totalMethodPercent}%");
coverageTable.AddRow("Average", $"{totalLinePercent / numModules}%", $"{totalBranchPercent / numModules}%", $"{totalMethodPercent / numModules}%");
coverageTable.AddRow("Total", $"{totalLinePercent.ToString("0.00")}%", $"{totalBranchPercent.ToString("0.00")}%", $"{totalMethodPercent.ToString("0.00")}%");
Copy link
Contributor

Choose a reason for hiding this comment

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

Same here... Percent property of CoverageDetails class takes care of rounding down.

@@ -6,6 +6,7 @@ public class CoverageDetails
{
public double Covered { get; internal set; }
public int Total { get; internal set; }
public double AverageModulePercent { get; internal set; }
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a thought... can we do rounding down to 2 decimal precision here itself? In getter, we can return value after rounding down to 2 decimal precision at max. So to keep rounding decision at one place.

By this way, we can avoid doing .ToString("0.00") for displaying average at different place.

Upto @MarcoRossignoli @tonerdo for final thoughts though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with u, at first try I wrote with this approach, just more verbose than ToString("0.00"), but as u said we have different outputs if only use string format:

Ex: threshold value is "85.25" and lets say line value is "85.2463", then if condition will evaluate to true and we output coverage failed for average threshold. But while displaying, we print "85.25" because we do ToString("0.00") which will do normal rounding.

I realized about it, but I needed another oint of view, tks! I'll work on it

src/coverlet.core/CoverageResult.cs Show resolved Hide resolved
@@ -53,12 +53,15 @@ public CoverageDetails CalculateLineCoverage(Documents documents)
public CoverageDetails CalculateLineCoverage(Modules modules)
{
var details = new CoverageDetails();
var accumPercent = 0.0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Just to make it more obvious, can you do var accumPercent = 0.0D

@@ -172,13 +172,17 @@ static int Main(string[] args)
var totalBranchPercent = summary.CalculateBranchCoverage(result.Modules).Percent;
var totalMethodPercent = summary.CalculateMethodCoverage(result.Modules).Percent;

var averageLinePercent = summary.CalculateLineCoverage(result.Modules).AverageModulePercent;
var averageBranchPercent = summary.CalculateBranchCoverage(result.Modules).AverageModulePercent;
var averageMethodPercent = summary.CalculateMethodCoverage(result.Modules).AverageModulePercent;
Copy link
Contributor

Choose a reason for hiding this comment

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

We can reuse objects from line# 171, 172 and 173, then get total percent and average percent from those CoverageDetails object for each type line, branch and module respectively. This way we avoid doing recalculation and get some perf benefit. What you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, it need a refactoring

@sasivishnu
Copy link
Contributor

@MarcoRossignoli I did review since I worked on this section last time. Let me know if you want to remove my comments. I am doing review first time in Github so I am not sure whether I did it right or messed up something.

@MarcoRossignoli
Copy link
Collaborator

MarcoRossignoli commented Jun 28, 2019

Let me know if you want to remove my comments.

@sasivishnu absolutely NOT!
This project is OSS every idea review discussion on code are welcome!
Feel free to comment everything!
We won't remove any comments if constructive!
I think that @tonerdo agrees with me 😄

@dlplenin
Copy link
Contributor Author

dlplenin commented Jun 28, 2019

@MarcoRossignoli Tests added.
@sasivishnu I refactored according your suggestions, also I change the aligment for numbers (just visual thing), let me knot if it is ok or if it add complexity in vane.

Maybe I shouldnt 😬 coz:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// ⚠ Do not modify this file. It will be replaced by a package reference once ConsoleTables has a strong name.
///////////////////////////////////////////////////////////////////////////////////////////////////////////////

but I saw a couple of commits...

@@ -75,8 +75,52 @@ private void SetupData()
_modules.Add("module", documents);
}

private void SetupAditionalData()
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: rename SetupDataForAverageCalculation and call inside constructor CoverageSummaryTests one time togheter with others.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Rename is done,.... but if SetupDataForAverageCalculation is called into the constructor, previous tests will fail because initial data will have two modules.
I want to have two scnearios to test, one with one module(TestCalculateBranchCoverage_OneModule), and other with multiple modules (TestCalculateBranchCoverage_Modules).... what do u think?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I prefer custom private fields with custom setup for tests for instance

private Modules _averageCalculationSingleModule;
private Modules _averageCalculationMultiModule;

and load in constructor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed... pls take a look at line 123 (LMK if its ok) => I want to reuse data from SetupDataSingleModule

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see it's ok, some nits and LGTM

@MarcoRossignoli
Copy link
Collaborator

also I change the aligment for numbers (just visual thing), let me knot if it is ok or if it add complexity in vane.

Were there issues here?I don't think we should touch that code in this PR, better keep the focus on issue topic.
BTW can you attach screenshot with before/after to understand the difference?

private double averageModulePercent;
public double AverageModulePercent
{
get { return Math.Round(averageModulePercent, 2); ; }
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: double token ;

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, can you do return Math.Floor(averageModulePercent * 100)/100;

To keep consistency with the way Coverlet handles rounding. We round down using floor. You can refer Percent property below this line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@sasivishnu
Copy link
Contributor

also I change the aligment for numbers (just visual thing), let me knot if it is ok or if it add complexity in vane.

Were there issues here?I don't think we should touch that code in this PR, better keep the focus on issue topic.
BTW can you attach screenshot with before/after to understand the difference?

Yep, agree with @MarcoRossignoli here. No need to change any alignment as part of this PR. Please open new issue to discuss regarding your alignment proposal.

@dlplenin
Copy link
Contributor Author

also I change the aligment for numbers (just visual thing), let me knot if it is ok or if it add complexity in vane.

Were there issues here?I don't think we should touch that code in this PR, better keep the focus on issue topic.
BTW can you attach screenshot with before/after to understand the difference?

There isnt a issue at all, it is just a visual aligment for number. It is not really important so I reverted the code.
Just: "My client asked me why number are aligned to left in CI report, ...I like that my clients value the use of tests"

@sasivishnu
Copy link
Contributor

LGTM

@@ -6,6 +6,13 @@ public class CoverageDetails
{
public double Covered { get; internal set; }
public int Total { get; internal set; }
private double averageModulePercent;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: move this field on top of class and change in _averageModulePercent

public class CoverageDetails
    {
        private double _averageModulePercent;
        public double Covered { get; internal set; }
        public int Total { get; internal set; }
        public double AverageModulePercent
        {
            get { return Math.Floor(_averageModulePercent * 100) / 100; }
            internal set { _averageModulePercent = value; }
        }

        public double Percent => Total == 0 ? 100D : Math.Floor((Covered / Total) * 10000) / 100;
    }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

double line = 0;
double branch = 0;
double method = 0;
var line = summary.CalculateLineCoverage(Modules).AverageModulePercent;
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: double

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done... just one thing: lines 173 to 175 & 225 to 227 are using var, LMK if var o double is better, I can do a quick push if needed

Copy link
Collaborator

Choose a reason for hiding this comment

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

yes please push fast update to keep style.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The rule I follow is "if the type is clear from assignment it's ok var but if it's not clear better make clean".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done!


Branches branches = new Branches
{
new BranchInfo { Line = 1, Hits = 1, Offset = 1, Path = 0, Ordinal = 1 },//covered
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: add space before comments } // covered everywhere

Copy link
Collaborator

@MarcoRossignoli MarcoRossignoli left a comment

Choose a reason for hiding this comment

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

LGTM thank's Diego!
thank's also to @sasivishnu for help on review!

@MarcoRossignoli MarcoRossignoli changed the title [Bug fix]Changed to calculate based on the average coverage of the modules (tonerdo#346) [Bug fix]Changed to calculate based on the average coverage of the modules Jul 3, 2019
@MarcoRossignoli MarcoRossignoli changed the title [Bug fix]Changed to calculate based on the average coverage of the modules Changed to calculate based on the average coverage of the modules Jul 3, 2019
@MarcoRossignoli
Copy link
Collaborator

@tonerdo I merged this stale bug fix.
Feel free to revert if not in agreement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Suspicious Average
4 participants