altcover
altcover copied to clipboard
Generic methods share the same name and signature
Hi,
when there are two methods just differentiating based on their derived types, they share the same name and signature in the cobertura output.
Here is an example:
public static void AddSingleton<T1, T2, T>(this IServiceCollection services, Func<IServiceProvider, T> implementationFactory)
where T : class, T1, T2 where T1 : class where T2 : class
{
services.AddSingleton<T2, T>(implementationFactory);
services.AddSingleton<T1, T>(x => (T)x.GetService<T2>()!);
}
public static void AddSingleton<T1, T2, T3, T>(this IServiceCollection services, Func<IServiceProvider, T> implementationFactory)
where T : class, T1, T2, T3 where T1 : class where T2 : class where T3 : class
{
services.AddSingleton<T2, T>(implementationFactory);
services.AddSingleton<T1, T>(x => (T)x.GetService<T2>()!);
services.AddSingleton<T3, T>(x => (T)x.GetService<T2>()!);
}
This results in a cobertura.xml
that looks like this:
<class name="Extensions.DependencyInjectionExtensions" filename="...\Extensions\DependencyInjectionExtensions.cs" line-rate="0" branch-rate="0" complexity="2.6">
<methods>
<method name="AddSingleton" signature="System.Void (Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Func`2<System.IServiceProvider,T>)" line-rate="0" branch-rate="0" complexity="2">
<lines>
<line number="37" hits="0" branch="false" />
</lines>
</method>
<method name="AddSingleton" signature="System.Void (Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Func`2<System.IServiceProvider,T>)" line-rate="0" branch-rate="0" complexity="3">
<lines>
<line number="60" hits="0" branch="false" />
</lines>
</method>
</methods>
</class>
I noticed the issue when I tried to include the output into a Jenkins CI. The coverage plugin threw an Exception, that there is already an item with the key. Just as context, here is the exception thrown by Jenkins:
java.lang.IllegalArgumentException: There is already a child [METHOD] AddSingletonSystem.Void (Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Func`2<System.IServiceProvider,T>) <0> with the name AddSingletonSystem.Void (Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Func`2<System.IServiceProvider,T>) in [CLASS] Extensions.DependencyInjectionExtensions <3, LINE: 0.00% (0/12)>
It's not just cobertura
(which is a downstream format) that does not handle this edge case; the base OpenCover
format doesn't record the information, so has two method entries of the same name, differing by metadata token. AltCover's JSON
format even merges the two methods into one keyed on the non-generic signature. Of all the formats, it's only the ancient NCover
that retains the information as it currently stands.
Well, it seems that AltCover
perfectly emulates OpenCover
for that format, and coverlet
for the json format. The latter also merges the two methods in cobertura
format, rather than having two records with the same method signature as in this issue.
Time to improve on that.
Should be resolved in release v8.8.74.
Assuming silence as assent; closing.
Sorry for the very late reply. Can confirm it is fixed now! Thank you!