Skip to content

Commit

Permalink
Analyzer for informing MethodDataSource > InstanceMethodDataSource (#…
Browse files Browse the repository at this point in the history
…2048)

* Analyzer for informing MethodDataSource > InstanceMethodDataSource

* Fix

* Fix logic

* Fix test
  • Loading branch information
thomhurst authored Mar 10, 2025
1 parent e0ff476 commit b169852
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 3 deletions.
29 changes: 29 additions & 0 deletions TUnit.Analyzers.Tests/MethodDataSourceAnalyzerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -698,4 +698,33 @@ public static
"""
);
}

[Test]
public async Task Method_Data_Source_Is_Flagged_When_Instance_Method_And_Wrong_Attribute()
{
await Verifier
.VerifyAnalyzerAsync(
"""
using TUnit.Core;
using System;
[Arguments(1)]
public class MyClass(int _)
{
[{|#0:MethodDataSource(nameof(One))|}]
[Test]
public void MyTest(int value)
{
}
public int One()
{
return 1;
}
}
""",
Verifier.Diagnostic(Rules.InstanceMethodSource)
.WithLocation(0)
);
}
}
27 changes: 27 additions & 0 deletions TUnit.Analyzers/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions TUnit.Analyzers/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -513,4 +513,13 @@
<data name="TUnit0055Title" xml:space="preserve">
<value>Do not overwrite the Console writer</value>
</data>
<data name="TUnit0056Description" xml:space="preserve">
<value>Instance methods used as data sources must use the `InstanceMethodDataSource` attribute.</value>
</data>
<data name="TUnit0056MessageFormat" xml:space="preserve">
<value>Instance methods used as data sources must use the `InstanceMethodDataSource` attribute</value>
</data>
<data name="TUnit0056Title" xml:space="preserve">
<value>Instance methods used as data sources must use the `InstanceMethodDataSource` attribute</value>
</data>
</root>
3 changes: 3 additions & 0 deletions TUnit.Analyzers/Rules.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ public static class Rules
public static readonly DiagnosticDescriptor OverwriteConsole =
CreateDescriptor("TUnit0055", UsageCategory, DiagnosticSeverity.Warning);

public static readonly DiagnosticDescriptor InstanceMethodSource =
CreateDescriptor("TUnit0056", UsageCategory, DiagnosticSeverity.Error);

private static DiagnosticDescriptor CreateDescriptor(string diagnosticId, string category, DiagnosticSeverity severity)
{
return new DiagnosticDescriptor(
Expand Down
15 changes: 14 additions & 1 deletion TUnit.Analyzers/TestDataAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ public class TestDataAnalyzer : ConcurrentDiagnosticAnalyzer
Rules.MustHavePropertySetter,
Rules.ReturnFunc,
Rules.MatrixDataSourceAttributeRequired,
Rules.TooManyArguments);
Rules.TooManyArguments,
Rules.InstanceMethodSource);

protected override void InitializeInternal(AnalysisContext context)
{
Expand Down Expand Up @@ -322,6 +323,18 @@ private void CheckMethodDataSource(SymbolAnalysisContext context,
return;
}

if (!dataSourceMethod.IsStatic
&& !dataSourceMethod.ContainingType.InstanceConstructors.Any(c => c.Parameters.IsDefaultOrEmpty)
&& SymbolEqualityComparer.Default.Equals(dataSourceMethod.ContainingType, testClassType))
{
context.ReportDiagnostic(
Diagnostic.Create(
Rules.InstanceMethodSource,
attribute.GetLocation())
);
return;
}

var canBeInstanceMethod = context.Symbol is IPropertySymbol or IMethodSymbol
&& testClassType.InstanceConstructors.First().Parameters.IsDefaultOrEmpty;

Expand Down
4 changes: 2 additions & 2 deletions TUnit.TestProject/GenericTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public async Task Test()
public abstract Task DataDrivenTest(T t);

[Test]
[MethodDataSource(nameof(GetData))]
[MethodDataSource(nameof(GetEnumerableData))]
[InstanceMethodDataSource(nameof(GetData))]
[InstanceMethodDataSource(nameof(GetEnumerableData))]
public async Task DataSourceDrivenTest(T t)
{
await Task.CompletedTask;
Expand Down

0 comments on commit b169852

Please sign in to comment.