danielpalme / ReportGenerator

ReportGenerator converts coverage reports generated by coverlet, OpenCover, dotCover, Visual Studio, NCover, Cobertura, JaCoCo, Clover, gcov or lcov into human readable reports in various formats.
https://reportgenerator.io
Apache License 2.0
2.58k stars 281 forks source link

Async local function issues #591

Closed bramborman closed 1 year ago

bramborman commented 1 year ago

It seems that C# local functions are not counted as methods by ReportGenerator, and as such don't have their own line in the Metrics table. Not sure if this is intended, but it doesn't work consistently all the time, anyway.

No local function here:

metrics

When I, however, use some more complex code, local functions do appear in the metrics, however with an improperly parsed name. I wanted to provide some sample outputs, but don't have much time to properly dig into that right now, so I at least provide some code that can be used for testing:

public class MyClass<T1> {
    public class MyNestedClass<T2> {
        public T2 MyProperty { get; set; }

        public async Task MyAsyncMethod<T3>(T3 myParam) {
            await MyAsyncLocalFunction<T3>();

            async Task MyAsyncLocalFunction<T4>() {
                Console.WriteLine(myParam);
                Console.WriteLine(MyProperty);

                await Task.CompletedTask;
            }
        }
    }
}
public class UnitTest1 {
    [Fact]
    public void Test1() {
        new MyClass<object>.MyNestedClass<object>().MyAsyncMethod<object>(null).GetAwaiter().GetResult();
    }
}

I'm using dotnet-reportgenerator-globaltool v5.1.17 and the Cobertura format. I tried both dotnet-coverage tool and Coverlet, both of which resulted in an incorrect behavior. Their behavior might be the same when #590 is fixed.

danielpalme commented 1 year ago

The changes in #590 should also improve the method names.

The result is not perfect, since . is used instead of / to separate a class and its nested classes.
This may result is several classes in the summary page.

Also the method names are not yet perfect, but give the new version a try. Let me know if I can add further improvements.

bramborman commented 1 year ago

Thanks, I'll take a deeper look hopefully this week.

I see, nested classes or async methods might be hard to even impossible to distinguish from the strings that are in the cobertura files. I'll try to think about a solution as well.

bramborman commented 1 year ago

Okay so I finally got some time to take a look into this... I'm trying to find various differences between Coverlet and dotnet-coverage outputs. It will take some time as I'm trying various combinations of nested classes, async methods, generics and local functions. Would you like me to open a separate issue regarding dotnet-coverage support?

danielpalme commented 1 year ago

Would you like me to open a separate issue regarding dotnet-coverage support?

You can open a new issue or reuse this one. Does not matter.