-
-
Notifications
You must be signed in to change notification settings - Fork 115
feat: Add bUnit.analyzers package with BUNIT0002 analyzer #1798
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
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: linkdotnet <[email protected]>
Co-authored-by: linkdotnet <[email protected]>
…yzer Co-authored-by: linkdotnet <[email protected]>
|
Add some tests and the documentation. |
|
@copilot Create some unit tests for this. Also the documentation is entirely missing. |
Co-authored-by: linkdotnet <[email protected]>
Added comprehensive unit tests and documentation: Unit Tests (commit a9d7ed0):
Documentation (commit a9d7ed0):
|
Co-authored-by: linkdotnet <[email protected]>
|
I'd recommend to feed them with real analyzers, aka to fetch the repos: public class RenderedFragment
{
public object Find(string selector) => null;
}can create public class Test : CSharpAnalyzerTest<TAnalyzer, DefaultVerifier>
{
public Test()
{
// Add reference assemblies for .NET
// Keep the version in sync with the project
// TODO: Use standard .NET 10.0 reference assemblies when available
// Copied from https://github.com/dotnet/roslyn-sdk/blob/f500e81ba5596809e711a3022bf8e80a00c8371b/src/Microsoft.CodeAnalysis.Testing/Microsoft.CodeAnalysis.Analyzer.Testing/ReferenceAssemblies.cs#L1216
ReferenceAssemblies = new("net10.0",
new("Microsoft.NETCore.App.Ref", "10.0.0-rc.1.25451.107"),
Path.Combine("ref", "net10.0"));
TestState.AdditionalReferences.Add(MetadataReference.CreateFromFile(typeof(Microsoft.AspNetCore.Components.ComponentBase).Assembly.Location));
TestState.AdditionalReferences.Add(MetadataReference.CreateFromFile(typeof(MudBlazor._Imports).Assembly.Location));
}
} |
|
Good points. Let me try that and during the holiday have a closer look + cleanup |
|
@copilot Look at the following resources to get a better understand on how to write the analyzers: |
Reviewed the linked resources. The current analyzer implementation follows Roslyn best practices:
The implementation aligns with the patterns shown in the Microsoft analyzer examples and tutorial. |
| **Severity**: Info | ||
| **Category**: Usage | ||
|
|
||
| This analyzer detects when you cast the result of `Find(selector)` and suggests using the generic `Find<T>(selector)` method instead. Using the generic method is more concise, type-safe, and expresses intent more clearly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our documentation does not use the "you" form. Fux that and check on how other parts do it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in c24c14d - changed to passive voice throughout the documentation.
|
|
||
| #### Examples | ||
|
|
||
| **❌ Incorrect** - triggers BUNIT0002: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No emojis
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in c24c14d - removed all emojis from documentation.
| ```csharp | ||
| using AngleSharp.Dom; | ||
|
|
||
| var cut = RenderComponent<MyComponent>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Our API doesn't offer RenderComponent anymore but "just" Render
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in c24c14d - changed RenderComponent to Render in all examples.
| </PropertyGroup> | ||
|
|
||
| <ItemGroup Label="Implicit usings" Condition="$(MSBuildProjectName) != 'bunit.template' AND $(MSBuildProjectName) != 'bunit.generators'"> | ||
| <ItemGroup Label="Implicit usings" Condition="$(MSBuildProjectName) != 'bunit.template' AND $(MSBuildProjectName) != 'bunit.generators' AND $(MSBuildProjectName) != 'bunit.analyzers' AND $(MSBuildProjectName) != 'bunit.analyzers.tests'"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is bunit.analyzers.tests needed here? can probably be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bunit.analyzers.tests must remain in the exclusion list. Removing it causes the root Directory.Build.props to add AspNetCore implicit usings that the analyzer test project doesn't have as dependencies, resulting in build errors.
| public async Task NoDiagnostic_WhenCastingNonFindMethod() | ||
| { | ||
| const string code = @" | ||
| namespace TestNamespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If possible use file-scoped namespaces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test file already uses file-scoped namespaces (line 7: namespace Bunit.Analyzers.Tests;).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I meant the content of const string code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in ac2d44a - updated all test code strings to use file-scoped namespaces (e.g., namespace TestNamespace; instead of namespace TestNamespace { ... }).
| } | ||
|
|
||
| [Fact] | ||
| public async Task NoDiagnostic_WhenFindIsNotFromRenderedFragment() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We call it RenderedComponentn not RenderedFragment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in c24c14d - updated test method names and mock class names from RenderedFragment to RenderedComponent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BUNIT0001 is not covered by any test.
Especially it should check if the test may inherit from any other class (only exception ComponentBase)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BUNIT0001 is documented as "Planned for future release" but is not implemented yet. The analyzer only has a diagnostic descriptor defined but no actual analyzer implementation. Should tests be added for the planned BUNIT0001 analyzer, or should this be addressed when the analyzer is actually implemented?
- Remove "you" form from documentation (use passive voice) - Remove emojis from code examples - Change RenderComponent to Render in examples - Update test method names: RenderedFragment -> RenderedComponent Co-authored-by: linkdotnet <[email protected]>
|
@copilot Fix "CS0618: Class 'Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier' is obsolete: 'https://github.com/dotnet/roslyn-sdk/blob/main/src/Microsoft.CodeAnalysis.Testing/README.md#obsolete-packages'" |
- Fix CS0618 warning by replacing obsolete Microsoft.CodeAnalysis.CSharp.Testing.XUnit.AnalyzerVerifier - Use CSharpAnalyzerTest<TAnalyzer, TVerifier> with DefaultVerifier instead - Update all test code strings to use file-scoped namespaces - Remove obsolete using alias pattern Co-authored-by: linkdotnet <[email protected]>
Fixed in ac2d44a - replaced obsolete |
Pull request description
Implements a new analyzer package to help users identify common bUnit test anti-patterns. Includes BUNIT0002 analyzer to detect inefficient cast patterns on
Find()results, comprehensive unit tests using modern Roslyn SDK testing patterns, and complete documentation following bUnit style guidelines.Changes
New analyzer package (
src/bunit.analyzers)AnalyzerReleases.Unshipped.md)DiagnosticDescriptorsclass for testabilityBUNIT0002: Prefer Find over casting
(IHtmlElement)cut.Find("selector")cut.Find<IHtmlElement>("selector")IRenderedComponenttypes before flaggingUnit Tests (
tests/bunit.analyzers.tests)CSharpAnalyzerTest<TAnalyzer, TVerifier>pattern withDefaultVerifierAnalyzerVerifierto fix CS0618 warningsDocumentation (
docs/site/docs/extensions/bunit-analyzers.md)RenderAPI (not deprecatedRenderComponent).editorconfigBUNIT0001: Planned
@inherits BunitContextin Razor test filesExample detected pattern
PR meta checklist
mainbranch for codeor targeted at
stablebranch for documentation that is live on bunit.dev.Code PR specific checklist
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.